aarch32_break_handler() and call_undef_hook() want to read an instruction at the current PC. instruction_pointer() currently returns just an address (not PCC in PCuABI), so to perform the uaccess we need to create a valid user pointer out of it.
uaddr_to_user_ptr_safe() should no longer be used for that purpose. Instead, we use make_user_ptr_for_read_uaccess() to create a user pointer with appropriate bounds and permissions (in PCuABI).
We may want to change instruction_pointer() to return a full user pointer eventually, however it is unclear whether this makes sense for most use-cases. Since this particular access should be completely safe, using make_user_ptr_for_read_uaccess() to create a user pointer is deemed acceptable.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/kernel/debug-monitors.c | 3 ++- arch/arm64/kernel/traps.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 4239cd747217..9c44906ad517 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -344,7 +344,8 @@ int aarch32_break_handler(struct pt_regs *regs) u32 arm_instr; u16 thumb_instr; bool bp = false; - void __user *pc = uaddr_to_user_ptr_safe(instruction_pointer(regs)); + const void __user *pc = make_user_ptr_for_read_uaccess( + instruction_pointer(regs), sizeof(arm_instr));
if (!compat_user_mode(regs)) return -EFAULT; diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 5d164223a580..b50f657c0b21 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -401,7 +401,8 @@ static int call_undef_hook(struct pt_regs *regs) u32 instr; int (*fn)(struct pt_regs *regs, u32 instr) = NULL; unsigned long pc = instruction_pointer(regs); - void __user *pc_usr_ptr = uaddr_to_user_ptr_safe(pc); + const void __user *pc_usr_ptr = make_user_ptr_for_read_uaccess( + pc, sizeof(instr));
if (!user_mode(regs)) { __le32 instr_le;