Commit def0bfdb authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc: use probe_user_read() and probe_user_write()



Instead of opencoding, use probe_user_read() to failessly read
a user location and probe_user_write() for writing to user.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/e041f5eedb23f09ab553be8a91c3de2087147320.1579800517.git.christophe.leroy@c-s.fr
parent 1e353198
Loading
Loading
Loading
Loading
+1 −11
Original line number Diff line number Diff line
@@ -1277,16 +1277,6 @@ void show_user_instructions(struct pt_regs *regs)

	pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));

	/*
	 * Make sure the NIP points at userspace, not kernel text/data or
	 * elsewhere.
	 */
	if (!__access_ok(pc, NR_INSN_TO_PRINT * sizeof(int), USER_DS)) {
		pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
			current->comm, current->pid);
		return;
	}

	seq_buf_init(&s, buf, sizeof(buf));

	while (n) {
@@ -1297,7 +1287,7 @@ void show_user_instructions(struct pt_regs *regs)
		for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) {
			int instr;

			if (probe_kernel_address((const void *)pc, instr)) {
			if (probe_user_read(&instr, (void __user *)pc, sizeof(instr))) {
				seq_buf_printf(&s, "XXXXXXXX ");
				continue;
			}
+2 −4
Original line number Diff line number Diff line
@@ -63,12 +63,10 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
	}
	isync();

	pagefault_disable();
	if (is_load)
		ret = raw_copy_from_user(to, from, n);
		ret = probe_user_read(to, (const void __user *)from, n);
	else
		ret = raw_copy_to_user(to, from, n);
	pagefault_enable();
		ret = probe_user_write((void __user *)to, from, n);

	/* switch the pid first to avoid running host with unallocated pid */
	if (quadrant == 1 && pid != old_pid)
+1 −5
Original line number Diff line number Diff line
@@ -279,12 +279,8 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
		if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) &&
		    access_ok(nip, sizeof(*nip))) {
			unsigned int inst;
			int res;

			pagefault_disable();
			res = __get_user_inatomic(inst, nip);
			pagefault_enable();
			if (!res)
			if (!probe_user_read(&inst, nip, sizeof(inst)))
				return !store_updates_sp(inst);
			*must_retry = true;
		}
+2 −12
Original line number Diff line number Diff line
@@ -28,15 +28,12 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
	unsigned int stack_frame[2];
	void __user *p = compat_ptr(sp);

	if (!access_ok(p, sizeof(stack_frame)))
		return 0;

	/*
	 * The most likely reason for this is that we returned -EFAULT,
	 * which means that we've done all that we can do from
	 * interrupt context.
	 */
	if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
	if (probe_user_read(stack_frame, (void __user *)p, sizeof(stack_frame)))
		return 0;

	if (!is_first)
@@ -54,11 +51,7 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
{
	unsigned long stack_frame[3];

	if (!access_ok((void __user *)sp, sizeof(stack_frame)))
		return 0;

	if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
					sizeof(stack_frame)))
	if (probe_user_read(stack_frame, (void __user *)sp, sizeof(stack_frame)))
		return 0;

	if (!is_first)
@@ -103,7 +96,6 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
			first_frame = 0;
		}
	} else {
		pagefault_disable();
#ifdef CONFIG_PPC64
		if (!is_32bit_task()) {
			while (depth--) {
@@ -112,7 +104,6 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
					break;
				first_frame = 0;
			}
			pagefault_enable();
			return;
		}
#endif
@@ -123,6 +114,5 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
				break;
			first_frame = 0;
		}
		pagefault_enable();
	}
}
+3 −17
Original line number Diff line number Diff line
@@ -155,12 +155,8 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
	    ((unsigned long)ptr & 7))
		return -EFAULT;

	pagefault_disable();
	if (!__get_user_inatomic(*ret, ptr)) {
		pagefault_enable();
	if (!probe_user_read(ret, ptr, sizeof(*ret)))
		return 0;
	}
	pagefault_enable();

	return read_user_stack_slow(ptr, ret, 8);
}
@@ -171,12 +167,8 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
	    ((unsigned long)ptr & 3))
		return -EFAULT;

	pagefault_disable();
	if (!__get_user_inatomic(*ret, ptr)) {
		pagefault_enable();
	if (!probe_user_read(ret, ptr, sizeof(*ret)))
		return 0;
	}
	pagefault_enable();

	return read_user_stack_slow(ptr, ret, 4);
}
@@ -293,17 +285,11 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
 */
static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
{
	int rc;

	if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
	    ((unsigned long)ptr & 3))
		return -EFAULT;

	pagefault_disable();
	rc = __get_user_inatomic(*ret, ptr);
	pagefault_enable();

	return rc;
	return probe_user_read(ret, ptr, sizeof(*ret));
}

static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
Loading