aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2009-05-26 15:55:32 +0800
committerHuang Ying <ying.huang@intel.com>2009-05-26 15:55:32 +0800
commit47886610f982190f20c2aa63eb30f1a03976f0ef (patch)
tree576ecb40496cc3ddffea1e33aa40b2b05e04f8d8
parent86d15fd02c989f09d1b94861748d4aff82294a5e (diff)
downloadmce-inject-47886610f982190f20c2aa63eb30f1a03976f0ef.tar.gz
Support specifying MCE raising mode, poll or exception
Raising logic is more complex for UCR errors, such as UCNA errors is uncorrected but not reported as exception. So add support to specify MCE raising mode. Signed-off-by: Huang Ying <ying.huang@intel.com>
-rw-r--r--mce-inject.c9
-rw-r--r--mce.h1
-rw-r--r--mce.lex2
-rw-r--r--mce.y5
-rw-r--r--parser.h1
5 files changed, 17 insertions, 1 deletions
diff --git a/mce-inject.c b/mce-inject.c
index 83fed65..52c23be 100644
--- a/mce-inject.c
+++ b/mce-inject.c
@@ -129,6 +129,7 @@ void do_inject_mce(int fd, struct mce *m)
if (m->status & MCI_STATUS_UC)
otherm.mcgstatus |= MCG_STATUS_RIPV;
otherm.status = m->status & MCI_STATUS_UC;
+ otherm.inject_flags |= MCJ_EXCEPTION;
blocked = 1;
barrier();
@@ -193,6 +194,12 @@ void inject_mce(struct mce *m)
{
int inject_fd;
+ if (!(mce_flags & MCE_RAISE_MODE)) {
+ if (m->status & MCI_STATUS_UC)
+ m->inject_flags |= MCJ_EXCEPTION;
+ else
+ m->inject_flags &= ~MCJ_EXCEPTION;
+ }
if (mce_flags & MCE_HOLD) {
int cpu_index = cpu_id_to_index(m->extcpu);
struct mce *nm;
@@ -205,7 +212,7 @@ void inject_mce(struct mce *m)
inject_fd = open("/dev/mcelog", O_RDWR);
if (inject_fd < 0)
err("opening of /dev/mcelog");
- if (!(m->status & MCI_STATUS_UC))
+ if (!(m->inject_flags & MCJ_EXCEPTION))
mce_flags |= MCE_NOBROADCAST;
do_inject_mce(inject_fd, m);
close(inject_fd);
diff --git a/mce.h b/mce.h
index 2edc936..ce9d5a1 100644
--- a/mce.h
+++ b/mce.h
@@ -38,6 +38,7 @@
#define MCJ_CTX_PROCESS 1 /* inject context: process */
#define MCJ_CTX_IRQ 2 /* inject context: IRQ */
#define MCJ_NMI_BROADCAST 4 /* do NMI broadcasting */
+#define MCJ_EXCEPTION 8 /* raise as exception */
#define MCJ_CTX_SET(flags, ctx) \
do { \
diff --git a/mce.lex b/mce.lex
index 9e350ad..d592f25 100644
--- a/mce.lex
+++ b/mce.lex
@@ -78,6 +78,8 @@ static struct key {
KEY(HOLD),
KEY(IN_IRQ),
KEY(IN_PROC),
+ KEY(POLL),
+ KEY(EXCP),
KEYVAL(CORRECTED, MCI_STATUS_VAL|MCI_STATUS_EN), // checkme
KEYVAL(UNCORRECTED, MCI_STATUS_VAL|MCI_STATUS_UC|MCI_STATUS_EN),
KEYVAL(FATAL, MCI_STATUS_VAL|MCI_STATUS_UC|MCI_STATUS_EN
diff --git a/mce.y b/mce.y
index 5499eb3..3dcf0b5 100644
--- a/mce.y
+++ b/mce.y
@@ -41,6 +41,7 @@ static void init(void);
%token STATUS RIP TSC ADDR MISC CPU BANK MCGSTATUS NOBROADCAST HOLD
%token IN_IRQ IN_PROC PROCESSOR TIME SOCKETID APICID MCGCAP
+%token POLL EXCP
%token CORRECTED UNCORRECTED FATAL MCE
%token NUMBER
%token SYMBOL
@@ -88,6 +89,10 @@ mce_term: STATUS status_list { m.status = $2; }
| HOLD { mce_flags |= MCE_HOLD; }
| IN_IRQ { MCJ_CTX_SET(m.inject_flags, MCJ_CTX_IRQ); }
| IN_PROC { MCJ_CTX_SET(m.inject_flags, MCJ_CTX_PROCESS); }
+ | POLL { mce_flags |= MCE_RAISE_MODE;
+ m.inject_flags &= ~MCJ_EXCEPTION; }
+ | EXCP { mce_flags |= MCE_RAISE_MODE;
+ m.inject_flags |= MCJ_EXCEPTION; }
;
mcgstatus_list: /* empty */ { $$ = 0; }
diff --git a/parser.h b/parser.h
index 049f9f0..c25b777 100644
--- a/parser.h
+++ b/parser.h
@@ -13,6 +13,7 @@ extern char *filename;
enum mceflags {
MCE_NOBROADCAST = (1 << 0),
MCE_HOLD = (1 << 1),
+ MCE_RAISE_MODE = (1 << 2),
};
extern enum mceflags mce_flags;