Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027083745.609031602@linutronix.de

authored by

Thomas Gleixner and committed by
Ingo Molnar
b2cfc0cd e497310b

+50
+50
include/linux/uaccess.h
··· 825 825 #define scoped_user_rw_access(uptr, elbl) \ 826 826 scoped_user_rw_access_size(uptr, sizeof(*(uptr)), elbl) 827 827 828 + /** 829 + * get_user_inline - Read user data inlined 830 + * @val: The variable to store the value read from user memory 831 + * @usrc: Pointer to the user space memory to read from 832 + * 833 + * Return: 0 if successful, -EFAULT when faulted 834 + * 835 + * Inlined variant of get_user(). Only use when there is a demonstrable 836 + * performance reason. 837 + */ 838 + #define get_user_inline(val, usrc) \ 839 + ({ \ 840 + __label__ efault; \ 841 + typeof(usrc) _tmpsrc = usrc; \ 842 + int _ret = 0; \ 843 + \ 844 + scoped_user_read_access(_tmpsrc, efault) \ 845 + unsafe_get_user(val, _tmpsrc, efault); \ 846 + if (0) { \ 847 + efault: \ 848 + _ret = -EFAULT; \ 849 + } \ 850 + _ret; \ 851 + }) 852 + 853 + /** 854 + * put_user_inline - Write to user memory inlined 855 + * @val: The value to write 856 + * @udst: Pointer to the user space memory to write to 857 + * 858 + * Return: 0 if successful, -EFAULT when faulted 859 + * 860 + * Inlined variant of put_user(). Only use when there is a demonstrable 861 + * performance reason. 862 + */ 863 + #define put_user_inline(val, udst) \ 864 + ({ \ 865 + __label__ efault; \ 866 + typeof(udst) _tmpdst = udst; \ 867 + int _ret = 0; \ 868 + \ 869 + scoped_user_write_access(_tmpdst, efault) \ 870 + unsafe_put_user(val, _tmpdst, efault); \ 871 + if (0) { \ 872 + efault: \ 873 + _ret = -EFAULT; \ 874 + } \ 875 + _ret; \ 876 + }) 877 + 828 878 #ifdef CONFIG_HARDENED_USERCOPY 829 879 void __noreturn usercopy_abort(const char *name, const char *detail, 830 880 bool to_user, unsigned long offset,