x86: msr: fix bogus return values from rdmsr_safe/wrmsr_safe
authorH. Peter Anvin <hpa@zytor.com>
Tue, 26 Aug 2008 05:39:15 +0000 (22:39 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 26 Aug 2008 05:39:15 +0000 (22:39 -0700)
Impact: bogus error codes (+other?) on x86-64

The rdmsr_safe/wrmsr_safe routines have macros for the handling of the
edx:eax arguments.  Those macros take a variable number of assembly
arguments.  This is rather inherently incompatible with using
%digit-style escapes in the inline assembly; replace those with
%[name]-style escapes.

This fixes miscompilation on x86-64, which at the very least caused
bogus return values.  It is possible that this could also corrupt the
return value; I am not sure.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
include/asm-x86/msr.h

index ad5f2de..2362cfd 100644 (file)
@@ -52,14 +52,14 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 {
        DECLARE_ARGS(val, low, high);
 
-       asm volatile("2: rdmsr ; xor %0,%0\n"
+       asm volatile("2: rdmsr ; xor %[err],%[err]\n"
                     "1:\n\t"
                     ".section .fixup,\"ax\"\n\t"
-                    "3:  mov %3,%0 ; jmp 1b\n\t"
+                    "3:  mov %[fault],%[err] ; jmp 1b\n\t"
                     ".previous\n\t"
                     _ASM_EXTABLE(2b, 3b)
-                    : "=r" (*err), EAX_EDX_RET(val, low, high)
-                    : "c" (msr), "i" (-EFAULT));
+                    : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
+                    : "c" (msr), [fault] "i" (-EFAULT));
        return EAX_EDX_VAL(val, low, high);
 }
 
@@ -73,15 +73,15 @@ static inline int native_write_msr_safe(unsigned int msr,
                                        unsigned low, unsigned high)
 {
        int err;
-       asm volatile("2: wrmsr ; xor %0,%0\n"
+       asm volatile("2: wrmsr ; xor %[err],%[err]\n"
                     "1:\n\t"
                     ".section .fixup,\"ax\"\n\t"
-                    "3:  mov %4,%0 ; jmp 1b\n\t"
+                    "3:  mov %[fault],%[err] ; jmp 1b\n\t"
                     ".previous\n\t"
                     _ASM_EXTABLE(2b, 3b)
-                    : "=a" (err)
+                    : [err] "=a" (err)
                     : "c" (msr), "0" (low), "d" (high),
-                      "i" (-EFAULT)
+                      [fault] "i" (-EFAULT)
                     : "memory");
        return err;
 }