From 98169b8804af661b485bbc5699825af8be22a125 Mon Sep 17 00:00:00 2001 From: Sedat Dilek Date: Sat, 28 May 2022 12:42:00 +0200 Subject: [PATCH] x86/usercopy: Use alternatives for clear_user() From: Hugh Dickins Link: https://lore.kernel.org/lkml/2f5ca5e4-e250-a41c-11fb-a7f4ebc7e1c9@google.com/ --- arch/x86/lib/copy_user_64.S | 26 ++++++++++++++++++++++++++ arch/x86/lib/usercopy_64.c | 34 +--------------------------------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 9dec1b38a98f..0194b6981c58 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -408,3 +408,29 @@ SYM_FUNC_START(__copy_user_nocache) _ASM_EXTABLE_CPY(41b, .L_fixup_1b_copy) SYM_FUNC_END(__copy_user_nocache) EXPORT_SYMBOL(__copy_user_nocache) + +/* + * Recent CPUs have added enhanced REP MOVSB/STOSB instructions. + * It's recommended to use enhanced REP MOVSB/STOSB if it's enabled. + * Assume that's best for __clear_user(), until alternatives are provided + * (though would be better to avoid REP STOSB for short clears, if no FSRM). + * + * Input: + * rdi destination + * rsi count + * + * Output: + * rax uncopied bytes or 0 if successful. + */ +SYM_FUNC_START(__clear_user) + ASM_STAC + movl %esi,%ecx + xorq %rax,%rax +1: rep stosb +2: movl %ecx,%eax + ASM_CLAC + ret + + _ASM_EXTABLE_UA(1b, 2b) +SYM_FUNC_END(__clear_user) +EXPORT_SYMBOL(__clear_user) diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 0ae6cf804197..63a4329a7ddd 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -13,41 +13,9 @@ /* * Zero Userspace */ - -unsigned long __clear_user(void __user *addr, unsigned long size) -{ - long __d0; - might_fault(); - /* no memory constraint because it doesn't change any memory gcc knows - about */ - stac(); - asm volatile( - " testq %[size8],%[size8]\n" - " jz 4f\n" - " .align 16\n" - "0: movq $0,(%[dst])\n" - " addq $8,%[dst]\n" - " decl %%ecx ; jnz 0b\n" - "4: movq %[size1],%%rcx\n" - " testl %%ecx,%%ecx\n" - " jz 2f\n" - "1: movb $0,(%[dst])\n" - " incq %[dst]\n" - " decl %%ecx ; jnz 1b\n" - "2:\n" - - _ASM_EXTABLE_TYPE_REG(0b, 2b, EX_TYPE_UCOPY_LEN8, %[size1]) - _ASM_EXTABLE_UA(1b, 2b) - - : [size8] "=&c"(size), [dst] "=&D" (__d0) - : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr)); - clac(); - return size; -} -EXPORT_SYMBOL(__clear_user); - unsigned long clear_user(void __user *to, unsigned long n) { + might_fault(); if (access_ok(to, n)) return __clear_user(to, n); return n; -- 2.36.1