Commit b2cfc0cd authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar
Browse files

uaccess: Provide put/get_user_inline()



Provide convenience wrappers around scoped user access similar 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: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Reviewed-by: default avatarMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027083745.609031602@linutronix.de
parent e497310b
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -825,6 +825,56 @@ for (bool done = false; !done; done = true) \
#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,