aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2009-05-27 15:56:51 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-06-03 17:45:33 -0400
commit1b2797dcc9f0ad89bc382ace26c6baafbc7e33c2 (patch)
treeb90669cb65373ca66a673a95c742c36e474b2802
parentac9603754dc7e286e62ae4f1067958d5b0075f99 (diff)
x86, mce: improve mce_get_rip
Assume IP on the stack is valid when either EIPV or RIPV are set. This influences whether the machine check exception handler decides to return or panic. This fixes a test case in the mce-test suite and is more compliant to the specification. This currently only makes a difference in a artificial testing scenario with the mce-test test suite. Also in addition do not force the EIPV to be valid with the exact register MSRs, and keep in trust the CS value on stack even if MSR is available. [AK: combination of patches from Huang Ying and Hidetoshi Seto, with new description by me] [add some description, no code changed - HS] Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index d5cb0b4c17ff..a7dc369a9974 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -306,21 +306,22 @@ int mce_available(struct cpuinfo_x86 *c)
306 return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); 306 return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
307} 307}
308 308
309/*
310 * Get the address of the instruction at the time of the machine check
311 * error.
312 */
309static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) 313static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
310{ 314{
311 if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) { 315
316 if (regs && (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV))) {
312 m->ip = regs->ip; 317 m->ip = regs->ip;
313 m->cs = regs->cs; 318 m->cs = regs->cs;
314 } else { 319 } else {
315 m->ip = 0; 320 m->ip = 0;
316 m->cs = 0; 321 m->cs = 0;
317 } 322 }
318 if (rip_msr) { 323 if (rip_msr)
319 /* Assume the RIP in the MSR is exact. Is this true? */
320 m->mcgstatus |= MCG_STATUS_EIPV;
321 m->ip = mce_rdmsrl(rip_msr); 324 m->ip = mce_rdmsrl(rip_msr);
322 m->cs = 0;
323 }
324} 325}
325 326
326#ifdef CONFIG_X86_LOCAL_APIC 327#ifdef CONFIG_X86_LOCAL_APIC