[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86 mce: Clean-up the mc_panic handler.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1276154351 -3600 # Node ID 8a2486514f1adda5b35acc39ccc71c7aa0348420 # Parent 704bcd622dc2ee4acb799d1bbd08ca1b28af0552 x86 mce: Clean-up the mc_panic handler. Firstly, mc_panic should only mc_panic in one CPU to avoid printk output be mixed. Secondly, call urgent handler in MCE panic to get error code specific hander be involved. Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx> --- xen/arch/x86/cpu/mcheck/mce_intel.c | 94 +++++++++++++++++++++++++++++------- 1 files changed, 76 insertions(+), 18 deletions(-) diff -r 704bcd622dc2 -r 8a2486514f1a xen/arch/x86/cpu/mcheck/mce_intel.c --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Thu Jun 10 08:18:46 2010 +0100 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Thu Jun 10 08:19:11 2010 +0100 @@ -150,6 +150,7 @@ static DEFINE_SPINLOCK(mce_logout_lock); static atomic_t severity_cpu = ATOMIC_INIT(-1); static atomic_t found_error = ATOMIC_INIT(0); +static cpumask_t mce_fatal_cpus; static void mce_barrier_enter(struct mce_softirq_barrier *); static void mce_barrier_exit(struct mce_softirq_barrier *); @@ -320,6 +321,27 @@ static void mce_softirq(void) } mce_barrier_exit(&mce_inside_bar); +} + +/* + * Return: + * -1: if system can't be recoved + * 0: Continoue to next step + */ +static int mce_urgent_action(struct cpu_user_regs *regs, + mctelem_cookie_t mctc) +{ + uint64_t gstatus; + + if ( mctc == NULL) + return 0; + + mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); + /* Xen is not pre-emptible */ + if ( !(gstatus & MCG_STATUS_RIPV) && !guest_mode(regs)) + return 0; + + return mce_action(regs, mctc) == MCER_RESET ? -1 : 0; } /* Machine Check owner judge algorithm: @@ -693,6 +715,31 @@ struct mca_error_handler intel_mce_dhand struct mca_error_handler intel_mce_dhandlers[] = {{is_async_memerr, intel_memerr_dhandler}, {default_check, intel_default_dhandler}}; +static void intel_default_uhandler(int bnum, + struct mca_binfo *binfo, + struct mca_handle_result *result) +{ + uint64_t status = binfo->mib->mc_status; + enum intel_mce_type type; + + type = intel_check_mce_type(status); + + switch (type) + { + /* Panic if no handler for SRAR error */ + case intel_mce_ucr_srar: + case intel_mce_fatal: + result->result = MCA_RESET; + break; + default: + result->result = MCA_NO_ACTION; + break; + } +} + +struct mca_error_handler intel_mce_uhandlers[] = + {{default_check, intel_default_uhandler}}; + static void intel_machine_check(struct cpu_user_regs * regs, long error_code) { uint64_t gstatus; @@ -724,17 +771,16 @@ static void intel_machine_check(struct c * clearing the banks, and deal with the telemetry after reboot * (the MSRs are sticky) */ - if (bs.pcc) - mc_panic("State lost due to machine check exception.\n"); - if (!bs.ripv) - mc_panic("RIPV =0 can't resume execution!\n"); - if (!bs.recoverable) - mc_panic("Machine check exception software recovery fail.\n"); + if (bs.pcc || !bs.recoverable) + cpu_set(smp_processor_id(), mce_fatal_cpus); } else { if (mctc != NULL) mctelem_commit(mctc); } atomic_set(&found_error, 1); + + /* The last CPU will be take check/clean-up etc */ + atomic_set(&severity_cpu, smp_processor_id()); mce_printk(MCE_CRITICAL, "MCE: clear_bank map %lx on CPU%d\n", *((unsigned long*)clear_bank), smp_processor_id()); @@ -745,25 +791,35 @@ static void intel_machine_check(struct c } mce_spin_unlock(&mce_logout_lock); + mce_barrier_enter(&mce_trap_bar); + if ( mctc != NULL && mce_urgent_action(regs, mctc)) + cpu_set(smp_processor_id(), mce_fatal_cpus); + mce_barrier_exit(&mce_trap_bar); /* * Wait until everybody has processed the trap. */ mce_barrier_enter(&mce_trap_bar); - /* According to latest MCA OS writer guide, if no error bank found - * on all cpus, something unexpected happening, we can't do any - * recovery job but to reset the system. - */ - if (atomic_read(&found_error) == 0) - mc_panic("Unexpected condition for the MCE handler, need reset\n"); + if (atomic_read(&severity_cpu) == smp_processor_id()) + { + /* According to SDM, if no error bank found on any cpus, + * something unexpected happening, we can't do any + * recovery job but to reset the system. + */ + if (atomic_read(&found_error) == 0) + mc_panic("MCE: No CPU found valid MCE, need reset\n"); + if (!cpus_empty(mce_fatal_cpus)) + { + char *ebufp, ebuf[96] = "MCE: Fatal error happened on CPUs "; + ebufp = ebuf + strlen(ebuf); + cpumask_scnprintf(ebufp, 95 - strlen(ebuf), mce_fatal_cpus); + mc_panic(ebuf); + } + atomic_set(&found_error, 0); + } mce_barrier_exit(&mce_trap_bar); - /* Clear error finding flags after all cpus finishes above judgement */ + /* Clear flags after above fatal check */ mce_barrier_enter(&mce_trap_bar); - if (atomic_read(&found_error)) { - mce_printk(MCE_CRITICAL, "MCE: Choose one CPU " - "to clear error finding flag\n "); - atomic_set(&found_error, 0); - } mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); if ((gstatus & MCG_STATUS_MCIP) != 0) { mce_printk(MCE_CRITICAL, "MCE: Clear MCIP@ last step"); @@ -1158,6 +1214,8 @@ static void intel_init_mce(void) mce_dhandlers = intel_mce_dhandlers; mce_dhandler_num = sizeof(intel_mce_dhandlers)/sizeof(struct mca_error_handler); + mce_uhandlers = intel_mce_uhandlers; + mce_uhandler_num = sizeof(intel_mce_uhandlers)/sizeof(struct mca_error_handler); } static int intel_init_mca_banks(void) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |