Skip to content

Commit

Permalink
[PATCH] x86_64: Use the extended RIP MSR for machine check reporting …
Browse files Browse the repository at this point in the history
…if available.

They are rumoured to be much more reliable than the RIP in the stack frame on
P4s.

This is a borderline case because the code is very simple.  Please note there
are no plans to add support for all the MCE register MSRs.

Cc: <venkatesh.pallipadi@intel.com>
Cc: <racing.guo@intel.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Apr 16, 2005
1 parent 1c17340 commit 94ad847
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions arch/x86_64/kernel/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static int banks;
static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
static unsigned long console_logged;
static int notify_user;
static int rip_msr;

/*
* Lockless MCE logging infrastructure.
Expand Down Expand Up @@ -124,6 +125,23 @@ static int mce_available(struct cpuinfo_x86 *c)
test_bit(X86_FEATURE_MCA, &c->x86_capability);
}

static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
{
if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) {
m->rip = regs->rip;
m->cs = regs->cs;
} else {
m->rip = 0;
m->cs = 0;
}
if (rip_msr) {
/* Assume the RIP in the MSR is exact. Is this true? */
m->mcgstatus |= MCG_STATUS_EIPV;
rdmsrl(rip_msr, m->rip);
m->cs = 0;
}
}

/*
* The actual machine check handler
*/
Expand Down Expand Up @@ -176,14 +194,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
if (m.status & MCI_STATUS_ADDRV)
rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);

if (regs && (m.mcgstatus & MCG_STATUS_RIPV)) {
m.rip = regs->rip;
m.cs = regs->cs;
} else {
m.rip = 0;
m.cs = 0;
}

mce_get_rip(&m, regs);
if (error_code != -1)
rdtscll(m.tsc);
wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
Expand Down Expand Up @@ -296,6 +307,9 @@ static void mce_init(void *dummy)
printk(KERN_INFO "MCE: warning: using only %d banks\n", banks);
banks = NR_BANKS;
}
/* Use accurate RIP reporting if available. */
if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9)
rip_msr = MSR_IA32_MCG_EIP;

/* Log the machine checks left over from the previous reset.
This also clears all registers */
Expand Down

0 comments on commit 94ad847

Please sign in to comment.