x86/uaccess: Improve __try_cmpxchg64_user_asm() for x86_32
authorUros Bizjak <ubizjak@gmail.com>
Tue, 28 Jun 2022 16:16:12 +0000 (18:16 +0200)
committerBorislav Petkov <bp@suse.de>
Mon, 15 Aug 2022 17:18:12 +0000 (19:18 +0200)
Improve __try_cmpxcgh64_user_asm() for !CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT
by relaxing the output register constraint from "c" to "q" constraint,
which allows the compiler to choose between %ecx or %ebx register.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20220628161612.7993-1-ubizjak@gmail.com
arch/x86/include/asm/uaccess.h

index 913e593a3b45fb5de1e16170a23320bb464a0ee6..b0583c1da14ff458ef9d444e17a454a19112f0a1 100644 (file)
@@ -448,7 +448,7 @@ do {                                                                        \
 
 #ifdef CONFIG_X86_32
 /*
- * Unlike the normal CMPXCHG, hardcode ECX for both success/fail and error.
+ * Unlike the normal CMPXCHG, use output GPR for both success/fail and error.
  * There are only six GPRs available and four (EAX, EBX, ECX, and EDX) are
  * hardcoded by CMPXCHG8B, leaving only ESI and EDI.  If the compiler uses
  * both ESI and EDI for the memory operand, compilation will fail if the error
@@ -461,11 +461,12 @@ do {                                                                      \
        __typeof__(*(_ptr)) __new = (_new);                             \
        asm volatile("\n"                                               \
                     "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n"             \
-                    "mov $0, %%ecx\n\t"                                \
-                    "setz %%cl\n"                                      \
+                    "mov $0, %[result]\n\t"                            \
+                    "setz %b[result]\n"                                \
                     "2:\n"                                             \
-                    _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %%ecx) \
-                    : [result]"=c" (__result),                         \
+                    _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG,  \
+                                          %[result])                   \
+                    : [result] "=q" (__result),                        \
                       "+A" (__old),                                    \
                       [ptr] "+m" (*_ptr)                               \
                     : "b" ((u32)__new),                                \