On Mon, Mar 14, 2016 at 05:38:54PM +0100, Borislav Petkov wrote:
> Hey Tony,
> 
> how about the below, untested change?

I meant this one, which actually builds:

---
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 92b6f651fa4f..6d0845c8a025 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -247,7 +247,6 @@ enum mcp_flags {
        MCP_UC          = BIT(1),       /* log uncorrected errors */
        MCP_DONTLOG     = BIT(2),       /* only clear, don't log */
 };
-bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 
 int mce_notify_irq(void);
 
@@ -266,7 +265,6 @@ extern void mce_disable_bank(int bank);
 
 /* Call the installed machine check handler for this CPU setup. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
-void do_machine_check(struct pt_regs *, long);
 
 /*
  * Threshold handler
@@ -355,4 +353,11 @@ enum amd_df_mca_blocks {
 extern const char * const amd_df_mcablock_names[N_DF_BLOCKS];
 #endif
 
+enum mce_call_cmds {
+       MCE_CALL_DECODE,        /* A struct mce for decoding is being supplied. 
*/
+       MCE_CALL_MC,            /* Invoke #MC exception handler. */
+       MCE_CALL_POLL           /* Poll MCA banks. */
+};
+
+void mce_call(enum mce_call_cmds cmd, void *t);
 #endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c 
b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 517619ea6498..d6137320f773 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -49,13 +49,10 @@ static void inject_mce(struct mce *m)
 
 static void raise_poll(struct mce *m)
 {
-       unsigned long flags;
        mce_banks_t b;
 
        memset(&b, 0xff, sizeof(mce_banks_t));
-       local_irq_save(flags);
-       machine_check_poll(0, &b);
-       local_irq_restore(flags);
+       mce_call(MCE_CALL_POLL, &b);
        m->finished = 0;
 }
 
@@ -72,7 +69,7 @@ static void raise_exception(struct mce *m, struct pt_regs 
*pregs)
        }
        /* in mcheck exeception handler, irq will be disabled */
        local_irq_save(flags);
-       do_machine_check(pregs, 0);
+       mce_call(MCE_CALL_MC, pregs);
        local_irq_restore(flags);
        m->finished = 0;
 }
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h 
b/arch/x86/kernel/cpu/mcheck/mce-internal.h
index 547720efd923..6bae2bc2b21f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
+++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
@@ -13,6 +13,8 @@ enum severity_level {
        MCE_PANIC_SEVERITY,
 };
 
+void do_machine_check(struct pt_regs *, long);
+bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
 extern struct atomic_notifier_head x86_mce_decoder_chain;
 
 #define ATTR_LEN               16
@@ -79,5 +81,3 @@ static inline int apei_clear_mce(u64 record_id)
        return -EINVAL;
 }
 #endif
-
-void mce_inject_log(struct mce *m);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index f0c921b03e42..32fa4549525f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -198,13 +198,34 @@ void mce_log(struct mce *mce)
        set_bit(0, &mce_need_notify);
 }
 
-void mce_inject_log(struct mce *m)
+void mce_call(enum mce_call_cmds cmd, void *t)
 {
-       mutex_lock(&mce_chrdev_read_mutex);
-       mce_log(m);
-       mutex_unlock(&mce_chrdev_read_mutex);
+       switch (cmd) {
+       case MCE_CALL_DECODE:
+               mutex_lock(&mce_chrdev_read_mutex);
+               mce_log((struct mce *)t);
+               mutex_unlock(&mce_chrdev_read_mutex);
+               break;
+
+       case MCE_CALL_MC:
+               do_machine_check((struct pt_regs *)t, 0);
+               break;
+
+       case MCE_CALL_POLL: {
+               unsigned long flags;
+
+               local_irq_save(flags);
+               machine_check_poll(0, (mce_banks_t *)t);
+               local_irq_restore(flags);
+               }
+               break;
+
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
 }
-EXPORT_SYMBOL_GPL(mce_inject_log);
+EXPORT_SYMBOL_GPL(mce_call);
 
 static struct notifier_block mce_srao_nb;
 
@@ -666,7 +687,6 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t 
*b)
 
        return error_seen;
 }
-EXPORT_SYMBOL_GPL(machine_check_poll);
 
 /*
  * Do a quick check if any of the events requires a panic.
@@ -1182,7 +1202,6 @@ out:
 out_ist:
        ist_exit(regs);
 }
-EXPORT_SYMBOL_GPL(do_machine_check);
 
 #ifndef CONFIG_MEMORY_FAILURE
 int memory_failure(unsigned long pfn, int vector, int flags)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index b92094ee135e..dd308d916fe6 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5251,7 +5251,7 @@ static void kvm_machine_check(void)
                .flags = X86_EFLAGS_IF,
        };
 
-       do_machine_check(&regs, 0);
+       mce_call(MCE_CALL_MC, &regs);
 #endif
 }
 
diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 55d38cfa46c2..dbfb3e4c3440 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -250,7 +250,7 @@ static void do_inject(void)
                i_mce.status |= MCI_STATUS_MISCV;
 
        if (inj_type == SW_INJ) {
-               mce_inject_log(&i_mce);
+               mce_call(MCE_CALL_DECODE, &i_mce);
                return;
        }

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

Reply via email to