]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
x86/AMD: Convert rdmsr_amd_safe() to use asm goto()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 7 Apr 2025 15:10:57 +0000 (16:10 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 22 Apr 2025 14:47:48 +0000 (15:47 +0100)
Unlike the WRMSR side, we can't use asm goto() unconditionally, because our
toolchain baseline doesn't support asm goto with outputs.

However, the code generation improvements are substantial enough to warrant
the duplicate implementations.

Detect support, and use asm goto() when available.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/Kconfig
xen/arch/x86/cpu/amd.c

index ae1c401a981e62aea20f6bc0b26cf32e2a8f9144..486b36b843a85edb0a543537136596336cd7989a 100644 (file)
@@ -33,6 +33,20 @@ config LD_IS_LLVM
 config CC_SPLIT_SECTIONS
        bool
 
+# Fixed in GCC 14, 13.3, 12.4 and 11.5
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921
+config GCC_ASM_GOTO_OUTPUT_BROKEN
+       bool
+       depends on CC_IS_GCC
+       default y if GCC_VERSION < 110500
+       default y if GCC_VERSION >= 120000 && GCC_VERSION < 120400
+       default y if GCC_VERSION >= 130000 && GCC_VERSION < 130300
+
+config CC_HAS_ASM_GOTO_OUTPUT
+       def_bool y
+       depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
+       depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+
 # Set code alignment.
 #
 # Allow setting on a boolean basis, and then convert such selection to an
index ce4e1df71064e7bb4b9e962b981d13469a49e233..37d67dd15c898ee164c7105b4869d2f1cdb82c31 100644 (file)
@@ -59,6 +59,18 @@ static bool __read_mostly fam17_c6_disabled;
 static inline int rdmsr_amd_safe(unsigned int msr, unsigned int *lo,
                                 unsigned int *hi)
 {
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+    asm goto ( "1: rdmsr\n\t"
+               _ASM_EXTABLE(1b, %l[fault])
+               : "=a" (*lo), "=d" (*hi)
+               : "c" (msr), "D" (0x9c5a203a)
+               :
+               : fault );
+    return 0;
+
+ fault:
+    return -EFAULT;
+#else
        int err;
 
        asm volatile("1: rdmsr\n2:\n"
@@ -71,6 +83,7 @@ static inline int rdmsr_amd_safe(unsigned int msr, unsigned int *lo,
                     : "c" (msr), "D" (0x9c5a203a), "2" (0), "i" (-EFAULT));
 
        return err;
+#endif
 }
 
 static inline int wrmsr_amd_safe(unsigned int msr, unsigned int lo,