From: Andrew Cooper Date: Mon, 17 Oct 2016 09:36:45 +0000 (+0100) Subject: Provide library {rdmsr,wrmsr}_safe() functions X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=89e5eba167fff21d51e5eb5dbcee55ebc129d2e9;p=xtf.git Provide library {rdmsr,wrmsr}_safe() functions Replace a local implementation in the MSR utility. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/extable.c b/arch/x86/extable.c index f138701..f3bb461 100644 --- a/arch/x86/extable.c +++ b/arch/x86/extable.c @@ -26,6 +26,33 @@ bool ex_record_fault_eax(struct cpu_regs *regs, const struct extable_entry *ex) return true; } +/** + * Fixup from a rdmsr fault + * + * Clobber the MSR index to signify error, and zero output. + */ +bool ex_rdmsr_safe(struct cpu_regs *regs, const struct extable_entry *ex) +{ + regs->ax = regs->dx = 0; + regs->cx = -1u; + regs->ip = ex->fixup; + + return true; +} + +/** + * Fixup from a wrmsr fault + * + * Clobber the MSR index to signify error. + */ +bool ex_wrmsr_safe(struct cpu_regs *regs, const struct extable_entry *ex) +{ + regs->cx = -1u; + regs->ip = ex->fixup; + + return true; +} + /* * Local variables: * mode: C diff --git a/include/arch/x86/lib.h b/include/arch/x86/lib.h index f8bcb81..3a652b4 100644 --- a/include/arch/x86/lib.h +++ b/include/arch/x86/lib.h @@ -14,6 +14,23 @@ static inline uint64_t rdmsr(uint32_t idx) return (((uint64_t)hi) << 32) | lo; } +static inline bool rdmsr_safe(uint32_t idx, uint64_t *val) +{ + uint32_t lo, hi, new_idx; + + asm volatile("1: rdmsr; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_rdmsr_safe) + : "=a" (lo), "=d" (hi), "=c" (new_idx) + : "c" (idx)); + + bool fault = idx != new_idx; + + if ( !fault ) + *val = (((uint64_t)hi) << 32) | lo; + + return fault; +} + static inline void wrmsr(uint32_t idx, uint64_t val) { asm volatile ("wrmsr": @@ -21,6 +38,19 @@ static inline void wrmsr(uint32_t idx, uint64_t val) "d" ((uint32_t)(val >> 32))); } +static inline bool wrmsr_safe(uint32_t idx, uint64_t val) +{ + uint32_t new_idx; + + asm volatile ("1: wrmsr; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_wrmsr_safe) + : "=c" (new_idx) + : "c" (idx), "a" ((uint32_t)val), + "d" ((uint32_t)(val >> 32))); + + return idx != new_idx; +} + static inline void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) diff --git a/tests/msr/main.c b/tests/msr/main.c index 78643ea..e16f570 100644 --- a/tests/msr/main.c +++ b/tests/msr/main.c @@ -13,25 +13,6 @@ */ #include -static int rdmsr_safe(uint32_t msr, uint64_t *val) -{ - uint32_t lo, hi; - int ret; - - asm volatile ("1: rdmsr;" - "jmp 3f; 2:" - "xor %[lo], %[lo];" - "xor %[hi], %[hi];" - "mov %[err], %[res];" - "3:" - _ASM_EXTABLE(1b, 2b) - : [lo] "=a" (lo), [hi] "=d" (hi), [res] "=&q" (ret) - : "c" (msr), [err] "ir" (-EFAULT), "2" (0)); - - *val = ((uint64_t)hi) << 32 | lo; - return ret; -} - void test_main(void) { unsigned int idx = 0;