[PATCH v4 10/39] x86/uaccess: Add unsafe_copy_from_user() implementation

Josh Poimboeuf <[email protected]>
Newsgroups org.kernel.vger.linux-toolchains,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users,org.kernel.vger.linux-trace-kernel
Message-ID <a87d41fe9b258cfede10727081fefdb1fd4f894b.1737511963.git.jpoimboe@kernel.org>
Add an x86 implementation of unsafe_copy_from_user() similar to the
existing unsafe_copy_to_user().

Signed-off-by: Josh Poimboeuf <[email protected]>
---
 arch/x86/include/asm/uaccess.h | 39 +++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 3a7755c1a441..a3148865bc57 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -599,23 +599,42 @@ _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_copy_to_user_loop(dst, src, len, type, label)			\
 	while (len >= sizeof(type)) {						\
-		unsafe_put_user(*(type *)(src),(type __user *)(dst),label);	\
+		unsafe_put_user(*(type *)(src), (type __user *)(dst), label);	\
 		dst += sizeof(type);						\
 		src += sizeof(type);						\
 		len -= sizeof(type);						\
 	}
 
-#define unsafe_copy_to_user(_dst,_src,_len,label)			\
+#define unsafe_copy_to_user(_dst, _src, _len, label)			\
 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);	\
+	void __user *__dst = (_dst);					\
+	const void *__src = (_src);					\
+	size_t __len = (_len);						\
+	unsafe_copy_to_user_loop(__dst, __src, __len, u64, label);	\
+	unsafe_copy_to_user_loop(__dst, __src, __len, u32, label);	\
+	unsafe_copy_to_user_loop(__dst, __src, __len, u16, label);	\
+	unsafe_copy_to_user_loop(__dst, __src, __len, u8,  label);	\
+} while (0)
+
+#define unsafe_copy_from_user_loop(dst, src, len, type, label)			\
+	while (len >= sizeof(type)) {						\
+		unsafe_get_user(*(type *)(dst),(type __user *)(src),label);	\
+		dst += sizeof(type);						\
+		src += sizeof(type);						\
+		len -= sizeof(type);						\
+	}
+
+#define unsafe_copy_from_user(_dst, _src, _len, label)			\
+do {									\
+	void *__dst = (_dst);						\
+	void __user *__src = (_src);					\
+	size_t __len = (_len);						\
+	unsafe_copy_from_user_loop(__dst, __src, __len, u64, label);	\
+	unsafe_copy_from_user_loop(__dst, __src, __len, u32, label);	\
+	unsafe_copy_from_user_loop(__dst, __src, __len, u16, label);	\
+	unsafe_copy_from_user_loop(__dst, __src, __len, u8,  label);	\
 } while (0)
 
 #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
-- 
2.48.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.