[patch V5 08/12] uaccess: Provide put/get_user_inline()
From: Thomas Gleixner <hidden>
Date: 2025-10-27 08:44:00
Also in:
linux-arm-kernel, linux-fsdevel, linux-riscv, linux-s390, lkml
Provide conveniance wrappers around scoped user access similiar to
put/get_user(), which reduce the usage sites to:
if (!get_user_inline(val, ptr))
return -EFAULT;
Should only be used if there is a demonstrable performance benefit.
Signed-off-by: Thomas Gleixner <redacted>
---
V5: Rename to inline
V4: Rename to scoped
---
include/linux/uaccess.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h@@ -825,6 +825,56 @@ for (bool done = false; !done; done = tr #define scoped_user_rw_access(uptr, elbl) \ scoped_user_rw_access_size(uptr, sizeof(*(uptr)), elbl) +/** + * get_user_inline - Read user data inlined + * @val: The variable to store the value read from user memory + * @usrc: Pointer to the user space memory to read from + * + * Return: 0 if successful, -EFAULT when faulted + * + * Inlined variant of get_user(). Only use when there is a demonstrable + * performance reason. + */ +#define get_user_inline(val, usrc) \ +({ \ + __label__ efault; \ + typeof(usrc) _tmpsrc = usrc; \ + int _ret = 0; \ + \ + scoped_user_read_access(_tmpsrc, efault) \ + unsafe_get_user(val, _tmpsrc, efault); \ + if (0) { \ + efault: \ + _ret = -EFAULT; \ + } \ + _ret; \ +}) + +/** + * put_user_inline - Write to user memory inlined + * @val: The value to write + * @udst: Pointer to the user space memory to write to + * + * Return: 0 if successful, -EFAULT when faulted + * + * Inlined variant of put_user(). Only use when there is a demonstrable + * performance reason. + */ +#define put_user_inline(val, udst) \ +({ \ + __label__ efault; \ + typeof(udst) _tmpdst = udst; \ + int _ret = 0; \ + \ + scoped_user_write_access(_tmpdst, efault) \ + unsafe_put_user(val, _tmpdst, efault); \ + if (0) { \ + efault: \ + _ret = -EFAULT; \ + } \ + _ret; \ +}) + #ifdef CONFIG_HARDENED_USERCOPY void __noreturn usercopy_abort(const char *name, const char *detail, bool to_user, unsigned long offset,