* [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection
@ 2026-04-25 2:08 Yury Norov
2026-04-25 2:08 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user() Yury Norov
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Yury Norov @ 2026-04-25 2:08 UTC (permalink / raw)
To: Andrew Morton, Thomas Gleixner, Peter Zijlstra (Intel),
Mathieu Desnoyers, Alice Ryhl, Viktor Malik, Randy Dunlap,
David Laight, linux-kernel
Cc: Yury Norov, Christophe Leroy (CS GROUP), Yury Norov
The kernel allows arches to select between inline and outline
implementations of the copy_{from,to}_user() by defining individual
INLINE_COPY_FROM_USER and INLINE_COPY_TO_USER, correspondingly.
However, all arches enable or disable them always together.
Without the real use-case for one helper being inlined while the other
outlined, having independent controls is excessive and error prone.
The first patch of the series fixes rust/uaccess coppy_to_user() wrapper
guarded with INLINE_COPY_FROM_USER. The 2nd patch switches codebase to
the unified INLINE_COPY_USER. And the last patch cleans up ifdefery in
the include/linux/uaccess.h
---
v1: https://lore.kernel.org/all/20260325163313.749336-1-ynorov@nvidia.com/
v2:
- reword cover letter (Andrew);
- add v2#1 to fix rust/uaccess explicitly (Alice);
Yury Norov (3):
rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user()
uaccess: unify inline vs outline copy_{from,to}_user() selection
uaccess: minimize INLINE_COPY_USER-related ifdefery
arch/arc/include/asm/uaccess.h | 3 +--
arch/arm/include/asm/uaccess.h | 3 +--
arch/arm64/include/asm/uaccess.h | 3 +--
arch/hexagon/include/asm/uaccess.h | 3 +--
arch/loongarch/include/asm/uaccess.h | 3 +--
arch/m68k/include/asm/uaccess.h | 3 +--
arch/microblaze/include/asm/uaccess.h | 3 +--
arch/mips/include/asm/uaccess.h | 3 +--
arch/nios2/include/asm/uaccess.h | 3 +--
arch/openrisc/include/asm/uaccess.h | 3 +--
arch/parisc/include/asm/uaccess.h | 3 +--
arch/s390/include/asm/uaccess.h | 3 +--
arch/sh/include/asm/uaccess.h | 3 +--
arch/sparc/include/asm/uaccess_32.h | 3 +--
arch/sparc/include/asm/uaccess_64.h | 3 +--
arch/um/include/asm/uaccess.h | 3 +--
arch/xtensa/include/asm/uaccess.h | 3 +--
include/asm-generic/uaccess.h | 3 +--
include/linux/uaccess.h | 25 +++++++++----------------
lib/usercopy.c | 4 +---
rust/helpers/uaccess.c | 2 +-
21 files changed, 29 insertions(+), 56 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user()
2026-04-25 2:08 [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
@ 2026-04-25 2:08 ` Yury Norov
2026-04-27 14:54 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user()\ Alice Ryhl
2026-04-25 2:08 ` [PATCH v2 2/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Yury Norov @ 2026-04-25 2:08 UTC (permalink / raw)
To: Andrew Morton, Thomas Gleixner, Peter Zijlstra (Intel),
Mathieu Desnoyers, Alice Ryhl, Viktor Malik, Randy Dunlap,
David Laight, linux-kernel
Cc: Yury Norov, Christophe Leroy (CS GROUP), Yury Norov
The copy_to_user() rust helper is only needed when the main kernel inlines
the function. It is controlled by INLINE_COPY_TO_USER, but the rust helper
is protected with INLINE_COPY_FROM_USER.
Fix that.
Reported-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Closes: https://lore.kernel.org/all/746c9c50-20c4-4dc9-a539-bf1310ff9414@kernel.org/
Fixes: d99dc586ca7c7 ("uaccess: decouple INLINE_COPY_FROM_USER and CONFIG_RUST")
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
rust/helpers/uaccess.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rust/helpers/uaccess.c b/rust/helpers/uaccess.c
index d9625b9ee046..aff22f16ab38 100644
--- a/rust/helpers/uaccess.c
+++ b/rust/helpers/uaccess.c
@@ -20,7 +20,9 @@ unsigned long rust_helper__copy_from_user(void *to, const void __user *from, uns
{
return _inline_copy_from_user(to, from, n);
}
+#endif
+#ifdef INLINE_COPY_TO_USER
__rust_helper
unsigned long rust_helper__copy_to_user(void __user *to, const void *from, unsigned long n)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] uaccess: unify inline vs outline copy_{from,to}_user() selection
2026-04-25 2:08 [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
2026-04-25 2:08 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user() Yury Norov
@ 2026-04-25 2:08 ` Yury Norov
2026-04-25 2:08 ` [PATCH v2 3/3] uaccess: minimize INLINE_COPY_USER-related ifdefery Yury Norov
2026-04-27 15:58 ` [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Andrew Morton
3 siblings, 0 replies; 7+ messages in thread
From: Yury Norov @ 2026-04-25 2:08 UTC (permalink / raw)
To: Andrew Morton, Thomas Gleixner, Peter Zijlstra (Intel),
Mathieu Desnoyers, Alice Ryhl, Viktor Malik, Randy Dunlap,
David Laight, linux-kernel
Cc: Yury Norov, Christophe Leroy (CS GROUP), Yury Norov
The kernel allows arches to select between inline and outline
implementations of the copy_{from,to}_user() by defining individual
INLINE_COPY_FROM_USER and INLINE_COPY_TO_USER, correspondingly.
However, all arches enable or disable them always together.
Without the real use-case for one helper being inlined while the other
outlined, having independent controls is excessive and error prone.
Switch the codebase to the single unified INLINE_COPY_USER control.
Tested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
arch/arc/include/asm/uaccess.h | 3 +--
arch/arm/include/asm/uaccess.h | 3 +--
arch/arm64/include/asm/uaccess.h | 3 +--
arch/hexagon/include/asm/uaccess.h | 3 +--
arch/loongarch/include/asm/uaccess.h | 3 +--
arch/m68k/include/asm/uaccess.h | 3 +--
arch/microblaze/include/asm/uaccess.h | 3 +--
arch/mips/include/asm/uaccess.h | 3 +--
arch/nios2/include/asm/uaccess.h | 3 +--
arch/openrisc/include/asm/uaccess.h | 3 +--
arch/parisc/include/asm/uaccess.h | 3 +--
arch/s390/include/asm/uaccess.h | 3 +--
arch/sh/include/asm/uaccess.h | 3 +--
arch/sparc/include/asm/uaccess_32.h | 3 +--
arch/sparc/include/asm/uaccess_64.h | 3 +--
arch/um/include/asm/uaccess.h | 3 +--
arch/xtensa/include/asm/uaccess.h | 3 +--
include/asm-generic/uaccess.h | 3 +--
include/linux/uaccess.h | 12 ++++++------
lib/usercopy.c | 4 +---
rust/helpers/uaccess.c | 4 +---
21 files changed, 26 insertions(+), 48 deletions(-)
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h
index 1e8809ea000a..6df2209541ac 100644
--- a/arch/arc/include/asm/uaccess.h
+++ b/arch/arc/include/asm/uaccess.h
@@ -628,8 +628,7 @@ static inline unsigned long __clear_user(void __user *to, unsigned long n)
return res;
}
-#define INLINE_COPY_TO_USER
-#define INLINE_COPY_FROM_USER
+#define INLINE_COPY_USER
#define __clear_user __clear_user
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index d6ae80b5df36..1593cf3b9800 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -616,8 +616,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
}
#define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0)
#endif
-#define INLINE_COPY_TO_USER
-#define INLINE_COPY_FROM_USER
+#define INLINE_COPY_USER
static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
{
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index b0c83a08dda9..9f5bd9c69c24 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -456,8 +456,7 @@ do { \
unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
} while (0)
-#define INLINE_COPY_TO_USER
-#define INLINE_COPY_FROM_USER
+#define INLINE_COPY_USER
extern unsigned long __must_check __arch_clear_user(void __user *to, unsigned long n);
static inline unsigned long __must_check __clear_user(void __user *to, unsigned long n)
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index bff77efc0d9a..1aecf60ec4f5 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -26,8 +26,7 @@ unsigned long raw_copy_from_user(void *to, const void __user *from,
unsigned long n);
unsigned long raw_copy_to_user(void __user *to, const void *from,
unsigned long n);
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
__kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count);
#define __clear_user(a, s) __clear_user_hexagon((a), (s))
diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index 438269313e78..428f373feabf 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -292,8 +292,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
return __copy_user((__force void *)to, from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
/*
* __clear_user: - Zero a block of memory in user space, with less checking.
diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h
index 64914872a5c9..31d133faa45e 100644
--- a/arch/m68k/include/asm/uaccess.h
+++ b/arch/m68k/include/asm/uaccess.h
@@ -377,8 +377,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
return __constant_copy_to_user(to, from, n);
return __generic_copy_to_user(to, from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index 3aab2f17e046..afa0dd8d013f 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -250,8 +250,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
return __copy_tofrom_user(to, (__force const void __user *)from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
/*
* Copy a null terminated string from userspace.
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index c0cede273c7c..f00c36676b73 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -433,8 +433,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
return __cu_len_r;
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h
index 6ccc9a232c23..5e6e05cc6efc 100644
--- a/arch/nios2/include/asm/uaccess.h
+++ b/arch/nios2/include/asm/uaccess.h
@@ -57,8 +57,7 @@ extern unsigned long
raw_copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long
raw_copy_to_user(void __user *to, const void *from, unsigned long n);
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
extern long strncpy_from_user(char *__to, const char __user *__from,
long __len);
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index d6500a374e18..db934ebc0069 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -218,8 +218,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long size)
{
return __copy_tofrom_user((__force void *)to, from, size);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
extern unsigned long __clear_user(void __user *addr, unsigned long size);
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 6c531d2c847e..0d17f81c8b27 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -197,7 +197,6 @@ unsigned long __must_check raw_copy_to_user(void __user *dst, const void *src,
unsigned long len);
unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src,
unsigned long len);
-#define INLINE_COPY_TO_USER
-#define INLINE_COPY_FROM_USER
+#define INLINE_COPY_USER
#endif /* __PARISC_UACCESS_H */
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index dff035372601..a9f32c53f699 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -30,8 +30,7 @@ void debug_user_asce(int exit);
#define uaccess_kmsan_or_inline __always_inline
#endif
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
static uaccess_kmsan_or_inline __must_check unsigned long
raw_copy_from_user(void *to, const void __user *from, unsigned long size)
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h
index a79609eb14be..02e7a066538e 100644
--- a/arch/sh/include/asm/uaccess.h
+++ b/arch/sh/include/asm/uaccess.h
@@ -95,8 +95,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
return __copy_user((__force void *)to, from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
/*
* Clear the area and return remaining number of bytes
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 43284b6ec46a..5542d5b32994 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -190,8 +190,7 @@ static inline unsigned long raw_copy_from_user(void *to, const void __user *from
return __copy_user((__force void __user *) to, from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
static inline unsigned long __clear_user(void __user *addr, unsigned long size)
{
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index b825a5dd0210..e2989cfba626 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -231,8 +231,7 @@ unsigned long __must_check raw_copy_from_user(void *to,
unsigned long __must_check raw_copy_to_user(void __user *to,
const void *from,
unsigned long size);
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
unsigned long __must_check raw_copy_in_user(void __user *to,
const void __user *from,
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h
index 0df9ea4abda8..4417c8b1d37a 100644
--- a/arch/um/include/asm/uaccess.h
+++ b/arch/um/include/asm/uaccess.h
@@ -27,8 +27,7 @@ static inline int __access_ok(const void __user *ptr, unsigned long size);
#define __access_ok __access_ok
#define __clear_user __clear_user
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
#include <asm-generic/uaccess.h>
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index 56aec6d504fe..6538a29a2bbd 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -237,8 +237,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
prefetch(from);
return __xtensa_copy_user((__force void *)to, from, n);
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
/*
* We need to return the number of bytes not cleared. Our memset()
diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
index b276f783494c..4569045e7139 100644
--- a/include/asm-generic/uaccess.h
+++ b/include/asm-generic/uaccess.h
@@ -91,8 +91,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
memcpy((void __force *)to, from, n);
return 0;
}
-#define INLINE_COPY_FROM_USER
-#define INLINE_COPY_TO_USER
+#define INLINE_COPY_USER
#endif /* CONFIG_UACCESS_MEMCPY */
/*
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 56328601218c..6100f1046546 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -84,7 +84,7 @@
* the 6 functions (copy_{to,from}_user(), __copy_{to,from}_user_inatomic())
* that are used instead. Out of those, __... ones are inlined. Plain
* copy_{to,from}_user() might or might not be inlined. If you want them
- * inlined, have asm/uaccess.h define INLINE_COPY_{TO,FROM}_USER.
+ * inlined, have asm/uaccess.h define INLINE_COPY_USER.
*
* NOTE: only copy_from_user() zero-pads the destination in case of short copy.
* Neither __copy_from_user() nor __copy_from_user_inatomic() zero anything
@@ -157,7 +157,7 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
}
/*
- * Architectures that #define INLINE_COPY_TO_USER use this function
+ * Architectures that #define INLINE_COPY_USER use this function
* directly in the normal copy_to/from_user(), the other ones go
* through an extern _copy_to/from_user(), which expands the same code
* here.
@@ -190,7 +190,7 @@ _inline_copy_from_user(void *to, const void __user *from, unsigned long n)
memset(to + (n - res), 0, res);
return res;
}
-#ifndef INLINE_COPY_FROM_USER
+#ifndef INLINE_COPY_USER
extern __must_check unsigned long
_copy_from_user(void *, const void __user *, unsigned long);
#endif
@@ -207,7 +207,7 @@ _inline_copy_to_user(void __user *to, const void *from, unsigned long n)
}
return n;
}
-#ifndef INLINE_COPY_TO_USER
+#ifndef INLINE_COPY_USER
extern __must_check unsigned long
_copy_to_user(void __user *, const void *, unsigned long);
#endif
@@ -217,7 +217,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (!check_copy_size(to, n, false))
return n;
-#ifdef INLINE_COPY_FROM_USER
+#ifdef INLINE_COPY_USER
return _inline_copy_from_user(to, from, n);
#else
return _copy_from_user(to, from, n);
@@ -230,7 +230,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
if (!check_copy_size(from, n, true))
return n;
-#ifdef INLINE_COPY_TO_USER
+#ifdef INLINE_COPY_USER
return _inline_copy_to_user(to, from, n);
#else
return _copy_to_user(to, from, n);
diff --git a/lib/usercopy.c b/lib/usercopy.c
index b00a3a957de6..e2f0bf104a59 100644
--- a/lib/usercopy.c
+++ b/lib/usercopy.c
@@ -12,15 +12,13 @@
/* out-of-line parts */
-#if !defined(INLINE_COPY_FROM_USER)
+#if !defined(INLINE_COPY_USER)
unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n)
{
return _inline_copy_from_user(to, from, n);
}
EXPORT_SYMBOL(_copy_from_user);
-#endif
-#if !defined(INLINE_COPY_TO_USER)
unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
{
return _inline_copy_to_user(to, from, n);
diff --git a/rust/helpers/uaccess.c b/rust/helpers/uaccess.c
index aff22f16ab38..6e59cc9c665c 100644
--- a/rust/helpers/uaccess.c
+++ b/rust/helpers/uaccess.c
@@ -14,15 +14,13 @@ rust_helper_copy_to_user(void __user *to, const void *from, unsigned long n)
return copy_to_user(to, from, n);
}
-#ifdef INLINE_COPY_FROM_USER
+#ifdef INLINE_COPY_USER
__rust_helper
unsigned long rust_helper__copy_from_user(void *to, const void __user *from, unsigned long n)
{
return _inline_copy_from_user(to, from, n);
}
-#endif
-#ifdef INLINE_COPY_TO_USER
__rust_helper
unsigned long rust_helper__copy_to_user(void __user *to, const void *from, unsigned long n)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] uaccess: minimize INLINE_COPY_USER-related ifdefery
2026-04-25 2:08 [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
2026-04-25 2:08 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user() Yury Norov
2026-04-25 2:08 ` [PATCH v2 2/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
@ 2026-04-25 2:08 ` Yury Norov
2026-04-27 15:58 ` [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Andrew Morton
3 siblings, 0 replies; 7+ messages in thread
From: Yury Norov @ 2026-04-25 2:08 UTC (permalink / raw)
To: Andrew Morton, Thomas Gleixner, Peter Zijlstra (Intel),
Mathieu Desnoyers, Alice Ryhl, Viktor Malik, Randy Dunlap,
David Laight, linux-kernel
Cc: Yury Norov, Christophe Leroy (CS GROUP), Yury Norov
Now that we've got the same config selecting inline vs outline
copy_to_user() and copy_from_user(), we can simplify the corresponding
logic in the uaccess.h.
Fixes: 1f9a8286bc0c ("uaccess: always export _copy_[from|to]_user with CONFIG_RUST")
Tested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/uaccess.h | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 6100f1046546..e0c3d6e29301 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -190,10 +190,6 @@ _inline_copy_from_user(void *to, const void __user *from, unsigned long n)
memset(to + (n - res), 0, res);
return res;
}
-#ifndef INLINE_COPY_USER
-extern __must_check unsigned long
-_copy_from_user(void *, const void __user *, unsigned long);
-#endif
static inline __must_check unsigned long
_inline_copy_to_user(void __user *to, const void *from, unsigned long n)
@@ -207,7 +203,13 @@ _inline_copy_to_user(void __user *to, const void *from, unsigned long n)
}
return n;
}
-#ifndef INLINE_COPY_USER
+#ifdef INLINE_COPY_USER
+# define _copy_to_user _inline_copy_to_user
+# define _copy_from_user _inline_copy_from_user
+#else
+extern __must_check unsigned long
+_copy_from_user(void *, const void __user *, unsigned long);
+
extern __must_check unsigned long
_copy_to_user(void __user *, const void *, unsigned long);
#endif
@@ -217,11 +219,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (!check_copy_size(to, n, false))
return n;
-#ifdef INLINE_COPY_USER
- return _inline_copy_from_user(to, from, n);
-#else
return _copy_from_user(to, from, n);
-#endif
}
static __always_inline unsigned long __must_check
@@ -229,12 +227,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (!check_copy_size(from, n, true))
return n;
-
-#ifdef INLINE_COPY_USER
- return _inline_copy_to_user(to, from, n);
-#else
return _copy_to_user(to, from, n);
-#endif
}
#ifndef copy_mc_to_kernel
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user()\
2026-04-25 2:08 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user() Yury Norov
@ 2026-04-27 14:54 ` Alice Ryhl
0 siblings, 0 replies; 7+ messages in thread
From: Alice Ryhl @ 2026-04-27 14:54 UTC (permalink / raw)
To: Yury Norov
Cc: Andrew Morton, Thomas Gleixner, Peter Zijlstra (Intel),
Mathieu Desnoyers, Viktor Malik, Randy Dunlap, David Laight,
linux-kernel, Christophe Leroy (CS GROUP), Yury Norov
On Fri, Apr 24, 2026 at 10:08:55PM -0400, Yury Norov wrote:
> The copy_to_user() rust helper is only needed when the main kernel inlines
> the function. It is controlled by INLINE_COPY_TO_USER, but the rust helper
> is protected with INLINE_COPY_FROM_USER.
>
> Fix that.
>
> Reported-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
> Closes: https://lore.kernel.org/all/746c9c50-20c4-4dc9-a539-bf1310ff9414@kernel.org/
> Fixes: d99dc586ca7c7 ("uaccess: decouple INLINE_COPY_FROM_USER and CONFIG_RUST")
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection
2026-04-25 2:08 [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
` (2 preceding siblings ...)
2026-04-25 2:08 ` [PATCH v2 3/3] uaccess: minimize INLINE_COPY_USER-related ifdefery Yury Norov
@ 2026-04-27 15:58 ` Andrew Morton
2026-04-27 18:47 ` Christophe Leroy (CS GROUP)
3 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2026-04-27 15:58 UTC (permalink / raw)
To: Yury Norov
Cc: Thomas Gleixner, Peter Zijlstra (Intel), Mathieu Desnoyers,
Alice Ryhl, Viktor Malik, Randy Dunlap, David Laight,
linux-kernel, Christophe Leroy (CS GROUP), Yury Norov,
Arnd Bergmann
On Fri, 24 Apr 2026 22:08:54 -0400 Yury Norov <ynorov@nvidia.com> wrote:
> The kernel allows arches to select between inline and outline
> implementations of the copy_{from,to}_user() by defining individual
> INLINE_COPY_FROM_USER and INLINE_COPY_TO_USER, correspondingly.
> However, all arches enable or disable them always together.
>
> Without the real use-case for one helper being inlined while the other
> outlined, having independent controls is excessive and error prone.
>
> The first patch of the series fixes rust/uaccess coppy_to_user() wrapper
> guarded with INLINE_COPY_FROM_USER. The 2nd patch switches codebase to
> the unified INLINE_COPY_USER. And the last patch cleans up ifdefery in
> the include/linux/uaccess.h
Seems sensible, thanks. I'll queue these up for test-n-review.
Arnd was involved in some of the Fixes: commits and might be interested
in these changes, so Cc:.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection
2026-04-27 15:58 ` [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Andrew Morton
@ 2026-04-27 18:47 ` Christophe Leroy (CS GROUP)
0 siblings, 0 replies; 7+ messages in thread
From: Christophe Leroy (CS GROUP) @ 2026-04-27 18:47 UTC (permalink / raw)
To: Andrew Morton, Yury Norov
Cc: Thomas Gleixner, Peter Zijlstra (Intel), Mathieu Desnoyers,
Alice Ryhl, Viktor Malik, Randy Dunlap, David Laight,
linux-kernel, Yury Norov, Arnd Bergmann
Le 27/04/2026 à 17:58, Andrew Morton a écrit :
> On Fri, 24 Apr 2026 22:08:54 -0400 Yury Norov <ynorov@nvidia.com> wrote:
>
>> The kernel allows arches to select between inline and outline
>> implementations of the copy_{from,to}_user() by defining individual
>> INLINE_COPY_FROM_USER and INLINE_COPY_TO_USER, correspondingly.
>> However, all arches enable or disable them always together.
>>
>> Without the real use-case for one helper being inlined while the other
>> outlined, having independent controls is excessive and error prone.
>>
>> The first patch of the series fixes rust/uaccess coppy_to_user() wrapper
>> guarded with INLINE_COPY_FROM_USER. The 2nd patch switches codebase to
>> the unified INLINE_COPY_USER. And the last patch cleans up ifdefery in
>> the include/linux/uaccess.h
>
> Seems sensible, thanks. I'll queue these up for test-n-review.
>
> Arnd was involved in some of the Fixes: commits and might be interested
> in these changes, so Cc:.
>
I have an alternative as patch 2 in this series :
https://lore.kernel.org/all/cover.1777306795.git.chleroy@kernel.org/
Christophe
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-04-27 18:47 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-25 2:08 [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
2026-04-25 2:08 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user() Yury Norov
2026-04-27 14:54 ` [PATCH v2 1/3] rust: uaccess: use INLINE_COPY_TO_USER to guard copy_to_user()\ Alice Ryhl
2026-04-25 2:08 ` [PATCH v2 2/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Yury Norov
2026-04-25 2:08 ` [PATCH v2 3/3] uaccess: minimize INLINE_COPY_USER-related ifdefery Yury Norov
2026-04-27 15:58 ` [PATCH v2 0/3] uaccess: unify inline vs outline copy_{from,to}_user() selection Andrew Morton
2026-04-27 18:47 ` Christophe Leroy (CS GROUP)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.