Commit 861574d51bbd ("powerpc/uaccess: Implement masked user access")
provides optimised user access by avoiding the cost of access_ok().Convert single step emulation functions to scoped user access to benefit from masked user access. Scoped user access also make the code simpler. Signed-off-by: Christophe Leroy (CS GROUP) <[email protected]> --- arch/powerpc/lib/sstep.c | 77 +++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index ac3ee19531d8..f0d6aa657c1a 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -329,20 +329,17 @@ __read_mem_aligned(unsigned long *dest, unsigned long ea, int nb, struct pt_regs static nokprobe_inline int read_mem_aligned(unsigned long *dest, unsigned long ea, int nb, struct pt_regs *regs) { - int err; + void __user *uea = (void __user *)ea; if (is_kernel_addr(ea)) return __read_mem_aligned(dest, ea, nb, regs); - if (user_read_access_begin((void __user *)ea, nb)) { - err = __read_mem_aligned(dest, ea, nb, regs); - user_read_access_end(); - } else { - err = -EFAULT; - regs->dar = ea; - } + scoped_user_read_access_size(uea, nb, efault) + return __read_mem_aligned(dest, (unsigned long)uea, nb, regs); - return err; +efault: + regs->dar = ea; + return -EFAULT; } /* @@ -385,20 +382,17 @@ static __always_inline int __copy_mem_in(u8 *dest, unsigned long ea, int nb, str static nokprobe_inline int copy_mem_in(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs) { - int err; + void __user *uea = (void __user *)ea; if (is_kernel_addr(ea)) return __copy_mem_in(dest, ea, nb, regs); - if (user_read_access_begin((void __user *)ea, nb)) { - err = __copy_mem_in(dest, ea, nb, regs); - user_read_access_end(); - } else { - err = -EFAULT; - regs->dar = ea; - } + scoped_user_read_access_size(uea, nb, efault) + return __copy_mem_in(dest, (unsigned long)uea, nb, regs); - return err; +efault: + regs->dar = ea; + return -EFAULT; } static nokprobe_inline int read_mem_unaligned(unsigned long *dest, @@ -465,20 +459,17 @@ __write_mem_aligned(unsigned long val, unsigned long ea, int nb, struct pt_regs static nokprobe_inline int write_mem_aligned(unsigned long val, unsigned long ea, int nb, struct pt_regs *regs) { - int err; + void __user *uea = (void __user *)ea; if (is_kernel_addr(ea)) return __write_mem_aligned(val, ea, nb, regs); - if (user_write_access_begin((void __user *)ea, nb)) { - err = __write_mem_aligned(val, ea, nb, regs); - user_write_access_end(); - } else { - err = -EFAULT; - regs->dar = ea; - } + scoped_user_write_access_size(uea, nb, efault) + return __write_mem_aligned(val, (unsigned long)uea, nb, regs); - return err; +efault: + regs->dar = ea; + return -EFAULT; } /* @@ -521,20 +512,17 @@ static __always_inline int __copy_mem_out(u8 *dest, unsigned long ea, int nb, st static nokprobe_inline int copy_mem_out(u8 *dest, unsigned long ea, int nb, struct pt_regs *regs) { - int err; + void __user *uea = (void __user *)ea; if (is_kernel_addr(ea)) return __copy_mem_out(dest, ea, nb, regs); - if (user_write_access_begin((void __user *)ea, nb)) { - err = __copy_mem_out(dest, ea, nb, regs); - user_write_access_end(); - } else { - err = -EFAULT; - regs->dar = ea; - } + scoped_user_write_access_size(uea, nb, efault) + return __copy_mem_out(dest, (unsigned long)uea, nb, regs); - return err; +efault: + regs->dar = ea; + return -EFAULT; } static nokprobe_inline int write_mem_unaligned(unsigned long val, @@ -1065,6 +1053,7 @@ static __always_inline int __emulate_dcbz(unsigned long ea) int emulate_dcbz(unsigned long ea, struct pt_regs *regs) { + void __user *uea = (void __user *)ea; int err; unsigned long size = l1_dcache_bytes(); @@ -1073,20 +1062,20 @@ int emulate_dcbz(unsigned long ea, struct pt_regs *regs) if (!address_ok(regs, ea, size)) return -EFAULT; - if (is_kernel_addr(ea)) { - err = __emulate_dcbz(ea); - } else if (user_write_access_begin((void __user *)ea, size)) { + if (is_kernel_addr(ea)) err = __emulate_dcbz(ea); - user_write_access_end(); - } else { - err = -EFAULT; - } + else + scoped_user_write_access_size(uea, size, efault) + err = __emulate_dcbz((unsigned long)uea); if (err) regs->dar = ea; - return err; + +efault: + regs->dar = ea; + return -EFAULT; } NOKPROBE_SYMBOL(emulate_dcbz); -- 2.49.0
