x86, msr: Rewrite AMD rd/wrmsr variants
authorBorislav Petkov <petkovbb@googlemail.com>
Mon, 31 Aug 2009 07:50:10 +0000 (09:50 +0200)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 31 Aug 2009 22:14:28 +0000 (15:14 -0700)
Switch them to native_{rd,wr}msr_safe_regs and remove
pv_cpu_ops.read_msr_amd.

Signed-off-by: Borislav Petkov <petkovbb@gmail.com>
LKML-Reference: <1251705011-18636-2-git-send-email-petkovbb@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
arch/x86/include/asm/msr.h
arch/x86/include/asm/paravirt.h
arch/x86/kernel/paravirt.c

index 184d4a113961adeba656ae4ef25b1dfbc890946f..09c5ca70d49dea8f3a7e9de7042006e5ee5d6603 100644 (file)
@@ -71,22 +71,6 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
        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));
-       return EAX_EDX_VAL(val, low, high);
-}
-
 static inline void native_write_msr(unsigned int msr,
                                    unsigned low, unsigned high)
 {
@@ -184,14 +168,34 @@ 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);
index 1705944e0374fd819bbabb445e97addc68729456..11574934a994f199a765e16a1f55ff2e77eb5bcf 100644 (file)
@@ -166,7 +166,6 @@ struct pv_cpu_ops {
 
        /* MSR, PMC and TSR operations.
           err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-       u64 (*read_msr_amd)(unsigned int msr, int *err);
        u64 (*read_msr)(unsigned int msr, int *err);
        int (*rdmsr_regs)(u32 *regs);
        int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
@@ -828,10 +827,6 @@ static inline int paravirt_rdmsr_regs(u32 *regs)
        return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs);
 }
 
-static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
-{
-       return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
-}
 static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 {
        return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
@@ -887,12 +882,31 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 }
 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 {
+       u32 gprs[8] = { 0 };
        int err;
 
-       *p = paravirt_read_msr_amd(msr, &err);
+       gprs[1] = msr;
+       gprs[7] = 0x9c5a203a;
+
+       err = paravirt_rdmsr_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 paravirt_wrmsr_regs(gprs);
+}
+
 static inline u64 paravirt_read_tsc(void)
 {
        return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);
index 67594af43b38ac029298190511d2a1b630f6c627..f5b0b4a01fb2c9656e175b4842e91e2d44e8e19f 100644 (file)
@@ -363,7 +363,6 @@ struct pv_cpu_ops pv_cpu_ops = {
        .wbinvd = native_wbinvd,
        .read_msr = native_read_msr_safe,
        .rdmsr_regs = native_rdmsr_safe_regs,
-       .read_msr_amd = native_read_msr_amd_safe,
        .write_msr = native_write_msr_safe,
        .wrmsr_regs = native_wrmsr_safe_regs,
        .read_tsc = native_read_tsc,