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>
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
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"
: "c" (msr), "D" (0x9c5a203a), "2" (0), "i" (-EFAULT));
return err;
+#endif
}
static inline int wrmsr_amd_safe(unsigned int msr, unsigned int lo,