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
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":
"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)
*/
#include <xtf.h>
-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;