I guess something as straightforward as this:

---
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 0ba24dfffdb2..9893caaf2696 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -373,10 +373,27 @@ static int msr_to_offset(u32 msr)
        return -1;
 }
 
+__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry 
*fixup,
+                                     struct pt_regs *regs, int trapnr,
+                                     unsigned long error_code,
+                                     unsigned long fault_addr)
+{
+       if (pr_warn_once("MSR access error: RDMSR from 0x%x at rIP: 0x%lx 
(%pS)\n",
+                        (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
+               show_stack_regs(regs);
+
+       panic("MCA Architectural violation!\n");
+
+       while (true)
+               cpu_relax();
+
+       return true;
+}
+
 /* MSR access wrappers used for error injection */
 static u64 mce_rdmsrl(u32 msr)
 {
-       u64 v;
+       DECLARE_ARGS(val, low, high);
 
        if (__this_cpu_read(injectm.finished)) {
                int offset = msr_to_offset(msr);
@@ -386,21 +403,42 @@ static u64 mce_rdmsrl(u32 msr)
                return *(u64 *)((char *)this_cpu_ptr(&injectm) + offset);
        }
 
-       if (rdmsrl_safe(msr, &v)) {
-               WARN_ONCE(1, "mce: Unable to read MSR 0x%x!\n", msr);
-               /*
-                * Return zero in case the access faulted. This should
-                * not happen normally but can happen if the CPU does
-                * something weird, or if the code is buggy.
-                */
-               v = 0;
-       }
+       /*
+        * RDMSR on MCA MSRs should not fault. If they do, this is very much an
+        * architectural violation and needs to be reported to hw vendor. Panic
+        * the box to not allow any further progress.
+        */
+       asm volatile("1: rdmsr\n"
+                    "2:\n"
+                    _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_fault)
+                    : EAX_EDX_RET(val, low, high) : "c" (msr));
 
-       return v;
+
+       return EAX_EDX_VAL(val, low, high);
+}
+
+__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry 
*fixup,
+                                     struct pt_regs *regs, int trapnr,
+                                     unsigned long error_code,
+                                     unsigned long fault_addr)
+{
+       if (pr_warn_once("MSR access error: WRMSR to 0x%x (tried to write 
0x%08x%08x) at rIP: 0x%lx (%pS)\n",
+                        (unsigned int)regs->cx, (unsigned int)regs->dx, 
(unsigned int)regs->ax,
+                        regs->ip, (void *)regs->ip))
+               show_stack_regs(regs);
+
+       panic("MCA Architectural violation!\n");
+
+       while (true)
+               cpu_relax();
+
+       return true;
 }
 
 static void mce_wrmsrl(u32 msr, u64 v)
 {
+       u32 low, high;
+
        if (__this_cpu_read(injectm.finished)) {
                int offset = msr_to_offset(msr);
 
@@ -408,7 +446,15 @@ static void mce_wrmsrl(u32 msr, u64 v)
                        *(u64 *)((char *)this_cpu_ptr(&injectm) + offset) = v;
                return;
        }
-       wrmsrl(msr, v);
+
+       low  = (u32)v;
+       high = (u32)(v >> 32);
+
+       /* See comment in mce_rdmsrl() */
+       asm volatile("1: wrmsr\n"
+                    "2:\n"
+                    _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_fault)
+                    : : "c" (msr), "a"(low), "d" (high) : "memory");
 }
 
 /*

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

Reply via email to