summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Gray <bgray@linux.ibm.com>2023-08-29 16:34:56 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-10-06 14:56:57 +0200
commit3632e9fd82d030491c8643cb61d36a2371e83a02 (patch)
treec84d9347f94bec8e20934f89ba2c049de6c9ec78 /arch
parent16722418cbe31400a4ab2ebab05ca2cb305c68e4 (diff)
downloadlinux-stable-3632e9fd82d030491c8643cb61d36a2371e83a02.tar.gz
linux-stable-3632e9fd82d030491c8643cb61d36a2371e83a02.tar.bz2
linux-stable-3632e9fd82d030491c8643cb61d36a2371e83a02.zip
powerpc/watchpoint: Disable pagefaults when getting user instruction
[ Upstream commit 3241f260eb830d27d09cc604690ec24533fdb433 ] This is called in an atomic context, so is not allowed to sleep if a user page needs to be faulted in and has nowhere it can be deferred to. The pagefault_disabled() function is documented as preventing user access methods from sleeping. In practice the page will be mapped in nearly always because we are reading the instruction that just triggered the watchpoint trap. Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20230829063457.54157-3-bgray@linux.ibm.com Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/hw_breakpoint_constraints.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c
index a74623025f3a..9e51801c4915 100644
--- a/arch/powerpc/kernel/hw_breakpoint_constraints.c
+++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c
@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
int *type, int *size, unsigned long *ea)
{
struct instruction_op op;
+ int err;
- if (__get_user_instr(*instr, (void __user *)regs->nip))
+ pagefault_disable();
+ err = __get_user_instr(*instr, (void __user *)regs->nip);
+ pagefault_enable();
+
+ if (err)
return;
analyse_instr(&op, regs, *instr);