[RFC PATCH v1 7/9] x86: Add unsafe_copy_from_user()

Christophe Leroy (CS GROUP)
2026-04-27T17:19:01Z

At the time being, x86 and arm64 are missing unsafe_copy_from_user().

Add it.

Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
---
arch/x86/include/asm/uaccess.h | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 3a0dd3c2b233..10c458ffa399 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -598,7 +598,7 @@ _label: \
* We want the unsafe accessors to always be inlined and use
* the error labels - thus the macro games.
*/
-#define unsafe_copy_loop(dst, src, len, type, label) \
+#define unsafe_put_loop(dst, src, len, type, label) \
while (len >= sizeof(type)) { \
unsafe_put_user(*(type *)(src),(type __user *)(dst),label); \
dst += sizeof(type); \
@@ -611,10 +611,29 @@ do { \
char __user *__ucu_dst = (_dst); \
const char *__ucu_src = (_src); \
size_t __ucu_len = (_len); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+} while (0)
+
+#define unsafe_get_loop(dst, src, len, type, label) \
+ while (len >= sizeof(type)) { \
+ unsafe_get_user(*(type __user *)(src),(type *)(dst),label); \
+ dst += sizeof(type); \
+ src += sizeof(type); \
+ len -= sizeof(type); \
+ }
+
+#define unsafe_copy_from_user(_dst,_src,_len,label) \
+do { \
+ char *__ucu_dst = (_dst); \
+ const char __user *__ucu_src = (_src); \
+ size_t __ucu_len = (_len); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
} while (0)

#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
--
2.49.0