user_read_access_begin() and user_write_access_begin() and user_access_begin() are now very similar. Create a common __user_access_begin() that take direction as parameter. In order to avoid a warning with the conditional call of barrier_nospec() which is sometimes an empty macro, change it to a do {} while (0). Signed-off-by: Christophe Leroy --- v2: New --- arch/powerpc/include/asm/barrier.h | 2 +- arch/powerpc/include/asm/uaccess.h | 46 +++++++++--------------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index b95b666f0374..7acbf27cac6c 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -102,7 +102,7 @@ do { \ #else /* !CONFIG_PPC_BARRIER_NOSPEC */ #define barrier_nospec_asm -#define barrier_nospec() +#define barrier_nospec() do {} while (0) #endif /* CONFIG_PPC_BARRIER_NOSPEC */ /* diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 698996f34891..49254f7d9069 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -410,50 +410,30 @@ copy_mc_to_user(void __user *to, const void *from, unsigned long n) extern long __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size); -static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len) +static __must_check __always_inline bool __user_access_begin(const void __user *ptr, size_t len, + unsigned long dir) { if (unlikely(!access_ok(ptr, len))) return false; might_fault(); - barrier_nospec(); - allow_read_write_user((void __user *)ptr, ptr, len); + if (dir & KUAP_READ) + barrier_nospec(); + allow_user_access((void __user *)ptr, dir); return true; } -#define user_access_begin user_access_begin -#define user_access_end prevent_current_access_user -#define user_access_save prevent_user_access_return -#define user_access_restore restore_user_access -static __must_check __always_inline bool -user_read_access_begin(const void __user *ptr, size_t len) -{ - if (unlikely(!access_ok(ptr, len))) - return false; +#define user_access_begin(p, l) __user_access_begin(p, l, KUAP_READ_WRITE) +#define user_read_access_begin(p, l) __user_access_begin(p, l, KUAP_READ) +#define user_write_access_begin(p, l) __user_access_begin(p, l, KUAP_WRITE) - might_fault(); - - barrier_nospec(); - allow_read_from_user(ptr, len); - return true; -} -#define user_read_access_begin user_read_access_begin -#define user_read_access_end prevent_current_read_from_user +#define user_access_end() prevent_user_access(KUAP_READ_WRITE) +#define user_read_access_end() prevent_user_access(KUAP_READ) +#define user_write_access_end() prevent_user_access(KUAP_WRITE) -static __must_check __always_inline bool -user_write_access_begin(const void __user *ptr, size_t len) -{ - if (unlikely(!access_ok(ptr, len))) - return false; - - might_fault(); - - allow_write_to_user((void __user *)ptr, len); - return true; -} -#define user_write_access_begin user_write_access_begin -#define user_write_access_end prevent_current_write_to_user +#define user_access_save prevent_user_access_return +#define user_access_restore restore_user_access #define unsafe_get_user(x, p, e) do { \ __long_type(*(p)) __gu_val; \ -- 2.49.0