Le 27/10/2025 à 09:43, Thomas Gleixner a écrit :
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 <[email protected]>

Reviewed-by: Christophe Leroy <[email protected]>

---
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,



Reply via email to