x86, msr: Have the _safe MSR functions return -EIO, not -EFAULT
[pandora-kernel.git] / arch / x86 / include / asm / msr.h
index 48ad9d2..943fdd5 100644 (file)
@@ -67,23 +67,7 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
                     ".previous\n\t"
                     _ASM_EXTABLE(2b, 3b)
                     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
-                    : "c" (msr), [fault] "i" (-EFAULT));
-       return EAX_EDX_VAL(val, low, high);
-}
-
-static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
-                                                     int *err)
-{
-       DECLARE_ARGS(val, low, high);
-
-       asm volatile("2: rdmsr ; xor %0,%0\n"
-                    "1:\n\t"
-                    ".section .fixup,\"ax\"\n\t"
-                    "3:  mov %3,%0 ; jmp 1b\n\t"
-                    ".previous\n\t"
-                    _ASM_EXTABLE(2b, 3b)
-                    : "=r" (*err), EAX_EDX_RET(val, low, high)
-                    : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
+                    : "c" (msr), [fault] "i" (-EIO));
        return EAX_EDX_VAL(val, low, high);
 }
 
@@ -106,13 +90,16 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
                     _ASM_EXTABLE(2b, 3b)
                     : [err] "=a" (err)
                     : "c" (msr), "0" (low), "d" (high),
-                      [fault] "i" (-EFAULT)
+                      [fault] "i" (-EIO)
                     : "memory");
        return err;
 }
 
 extern unsigned long long native_read_tsc(void);
 
+extern int native_rdmsr_safe_regs(u32 *regs);
+extern int native_wrmsr_safe_regs(u32 *regs);
+
 static __always_inline unsigned long long __native_read_tsc(void)
 {
        DECLARE_ARGS(val, low, high);
@@ -181,14 +168,44 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
        *p = native_read_msr_safe(msr, &err);
        return err;
 }
+
 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 {
+       u32 gprs[8] = { 0 };
        int err;
 
-       *p = native_read_msr_amd_safe(msr, &err);
+       gprs[1] = msr;
+       gprs[7] = 0x9c5a203a;
+
+       err = native_rdmsr_safe_regs(gprs);
+
+       *p = gprs[0] | ((u64)gprs[2] << 32);
+
        return err;
 }
 
+static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
+{
+       u32 gprs[8] = { 0 };
+
+       gprs[0] = (u32)val;
+       gprs[1] = msr;
+       gprs[2] = val >> 32;
+       gprs[7] = 0x9c5a203a;
+
+       return native_wrmsr_safe_regs(gprs);
+}
+
+static inline int rdmsr_safe_regs(u32 *regs)
+{
+       return native_rdmsr_safe_regs(regs);
+}
+
+static inline int wrmsr_safe_regs(u32 *regs)
+{
+       return native_wrmsr_safe_regs(regs);
+}
+
 #define rdtscl(low)                                            \
        ((low) = (u32)__native_read_tsc())