提交 84c2559d 编写于 作者: B Borislav Petkov

x86, MCA: Convert rip_msr, mce_bootlog, monarch_timeout

Move above configuration variables into struct mca_config and adjust
usage places accordingly.
Signed-off-by: NBorislav Petkov <bp@alien8.de>
Acked-by: NTony Luck <tony.luck@intel.com>
上级 d203f0b8
...@@ -123,7 +123,10 @@ struct mce_log { ...@@ -123,7 +123,10 @@ struct mce_log {
struct mca_config { struct mca_config {
bool dont_log_ce; bool dont_log_ce;
u8 banks; u8 banks;
s8 bootlog;
int tolerant; int tolerant;
int monarch_timeout;
u32 rip_msr;
}; };
extern void mce_register_decode_chain(struct notifier_block *nb); extern void mce_register_decode_chain(struct notifier_block *nb);
......
...@@ -66,9 +66,6 @@ atomic_t mce_entry; ...@@ -66,9 +66,6 @@ atomic_t mce_entry;
DEFINE_PER_CPU(unsigned, mce_exception_count); DEFINE_PER_CPU(unsigned, mce_exception_count);
static int rip_msr __read_mostly;
static int mce_bootlog __read_mostly = -1;
static int monarch_timeout __read_mostly = -1;
static int mce_panic_timeout __read_mostly; static int mce_panic_timeout __read_mostly;
int mce_cmci_disabled __read_mostly; int mce_cmci_disabled __read_mostly;
int mce_ignore_ce __read_mostly; int mce_ignore_ce __read_mostly;
...@@ -78,6 +75,7 @@ int mce_bios_cmci_threshold __read_mostly; ...@@ -78,6 +75,7 @@ int mce_bios_cmci_threshold __read_mostly;
struct mce_bank *mce_banks __read_mostly; struct mce_bank *mce_banks __read_mostly;
struct mca_config mca_cfg __read_mostly = { struct mca_config mca_cfg __read_mostly = {
.bootlog = -1,
/* /*
* Tolerant levels: * Tolerant levels:
* 0: always panic on uncorrected errors, log corrected errors * 0: always panic on uncorrected errors, log corrected errors
...@@ -85,7 +83,8 @@ struct mca_config mca_cfg __read_mostly = { ...@@ -85,7 +83,8 @@ struct mca_config mca_cfg __read_mostly = {
* 2: SIGBUS or log uncorrected errors (if possible), log corr. errors * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors
* 3: never panic or SIGBUS, log all errors (for testing only) * 3: never panic or SIGBUS, log all errors (for testing only)
*/ */
.tolerant = 1 .tolerant = 1,
.monarch_timeout = -1
}; };
/* User mode helper program triggered by machine check event */ /* User mode helper program triggered by machine check event */
...@@ -373,7 +372,7 @@ static int msr_to_offset(u32 msr) ...@@ -373,7 +372,7 @@ static int msr_to_offset(u32 msr)
{ {
unsigned bank = __this_cpu_read(injectm.bank); unsigned bank = __this_cpu_read(injectm.bank);
if (msr == rip_msr) if (msr == mca_cfg.rip_msr)
return offsetof(struct mce, ip); return offsetof(struct mce, ip);
if (msr == MSR_IA32_MCx_STATUS(bank)) if (msr == MSR_IA32_MCx_STATUS(bank))
return offsetof(struct mce, status); return offsetof(struct mce, status);
...@@ -452,8 +451,8 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs) ...@@ -452,8 +451,8 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs)
m->cs |= 3; m->cs |= 3;
} }
/* Use accurate RIP reporting if available. */ /* Use accurate RIP reporting if available. */
if (rip_msr) if (mca_cfg.rip_msr)
m->ip = mce_rdmsrl(rip_msr); m->ip = mce_rdmsrl(mca_cfg.rip_msr);
} }
} }
...@@ -697,7 +696,7 @@ static int mce_timed_out(u64 *t) ...@@ -697,7 +696,7 @@ static int mce_timed_out(u64 *t)
rmb(); rmb();
if (atomic_read(&mce_paniced)) if (atomic_read(&mce_paniced))
wait_for_panic(); wait_for_panic();
if (!monarch_timeout) if (!mca_cfg.monarch_timeout)
goto out; goto out;
if ((s64)*t < SPINUNIT) { if ((s64)*t < SPINUNIT) {
/* CHECKME: Make panic default for 1 too? */ /* CHECKME: Make panic default for 1 too? */
...@@ -803,7 +802,7 @@ static int mce_start(int *no_way_out) ...@@ -803,7 +802,7 @@ static int mce_start(int *no_way_out)
{ {
int order; int order;
int cpus = num_online_cpus(); int cpus = num_online_cpus();
u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC;
if (!timeout) if (!timeout)
return -1; return -1;
...@@ -867,7 +866,7 @@ static int mce_start(int *no_way_out) ...@@ -867,7 +866,7 @@ static int mce_start(int *no_way_out)
static int mce_end(int order) static int mce_end(int order)
{ {
int ret = -1; int ret = -1;
u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC;
if (!timeout) if (!timeout)
goto reset; goto reset;
...@@ -1427,7 +1426,7 @@ static int __cpuinit __mcheck_cpu_cap_init(void) ...@@ -1427,7 +1426,7 @@ static int __cpuinit __mcheck_cpu_cap_init(void)
/* Use accurate RIP reporting if available. */ /* Use accurate RIP reporting if available. */
if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9) if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9)
rip_msr = MSR_IA32_MCG_EIP; mca_cfg.rip_msr = MSR_IA32_MCG_EIP;
if (cap & MCG_SER_P) if (cap & MCG_SER_P)
mce_ser = 1; mce_ser = 1;
...@@ -1437,15 +1436,19 @@ static int __cpuinit __mcheck_cpu_cap_init(void) ...@@ -1437,15 +1436,19 @@ static int __cpuinit __mcheck_cpu_cap_init(void)
static void __mcheck_cpu_init_generic(void) static void __mcheck_cpu_init_generic(void)
{ {
enum mcp_flags m_fl = 0;
mce_banks_t all_banks; mce_banks_t all_banks;
u64 cap; u64 cap;
int i; int i;
if (!mca_cfg.bootlog)
m_fl = MCP_DONTLOG;
/* /*
* Log the machine checks left over from the previous reset. * Log the machine checks left over from the previous reset.
*/ */
bitmap_fill(all_banks, MAX_NR_BANKS); bitmap_fill(all_banks, MAX_NR_BANKS);
machine_check_poll(MCP_UC|(!mce_bootlog ? MCP_DONTLOG : 0), &all_banks); machine_check_poll(MCP_UC | m_fl, &all_banks);
set_in_cr4(X86_CR4_MCE); set_in_cr4(X86_CR4_MCE);
...@@ -1511,12 +1514,12 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) ...@@ -1511,12 +1514,12 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
*/ */
clear_bit(10, (unsigned long *)&mce_banks[4].ctl); clear_bit(10, (unsigned long *)&mce_banks[4].ctl);
} }
if (c->x86 <= 17 && mce_bootlog < 0) { if (c->x86 <= 17 && cfg->bootlog < 0) {
/* /*
* Lots of broken BIOS around that don't clear them * Lots of broken BIOS around that don't clear them
* by default and leave crap in there. Don't log: * by default and leave crap in there. Don't log:
*/ */
mce_bootlog = 0; cfg->bootlog = 0;
} }
/* /*
* Various K7s with broken bank 0 around. Always disable * Various K7s with broken bank 0 around. Always disable
...@@ -1581,22 +1584,22 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) ...@@ -1581,22 +1584,22 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
* synchronization with a one second timeout. * synchronization with a one second timeout.
*/ */
if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) &&
monarch_timeout < 0) cfg->monarch_timeout < 0)
monarch_timeout = USEC_PER_SEC; cfg->monarch_timeout = USEC_PER_SEC;
/* /*
* There are also broken BIOSes on some Pentium M and * There are also broken BIOSes on some Pentium M and
* earlier systems: * earlier systems:
*/ */
if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) if (c->x86 == 6 && c->x86_model <= 13 && cfg->bootlog < 0)
mce_bootlog = 0; cfg->bootlog = 0;
if (c->x86 == 6 && c->x86_model == 45) if (c->x86 == 6 && c->x86_model == 45)
quirk_no_way_out = quirk_sandybridge_ifu; quirk_no_way_out = quirk_sandybridge_ifu;
} }
if (monarch_timeout < 0) if (cfg->monarch_timeout < 0)
monarch_timeout = 0; cfg->monarch_timeout = 0;
if (mce_bootlog != 0) if (cfg->bootlog != 0)
mce_panic_timeout = 30; mce_panic_timeout = 30;
return 0; return 0;
...@@ -1975,14 +1978,14 @@ static int __init mcheck_enable(char *str) ...@@ -1975,14 +1978,14 @@ static int __init mcheck_enable(char *str)
else if (!strcmp(str, "ignore_ce")) else if (!strcmp(str, "ignore_ce"))
mce_ignore_ce = 1; mce_ignore_ce = 1;
else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog"))
mce_bootlog = (str[0] == 'b'); cfg->bootlog = (str[0] == 'b');
else if (!strcmp(str, "bios_cmci_threshold")) else if (!strcmp(str, "bios_cmci_threshold"))
mce_bios_cmci_threshold = 1; mce_bios_cmci_threshold = 1;
else if (isdigit(str[0])) { else if (isdigit(str[0])) {
get_option(&str, &(cfg->tolerant)); get_option(&str, &(cfg->tolerant));
if (*str == ',') { if (*str == ',') {
++str; ++str;
get_option(&str, &monarch_timeout); get_option(&str, &(cfg->monarch_timeout));
} }
} else { } else {
pr_info("mce argument %s ignored. Please use /sys\n", str); pr_info("mce argument %s ignored. Please use /sys\n", str);
...@@ -2200,7 +2203,7 @@ static ssize_t store_int_with_restart(struct device *s, ...@@ -2200,7 +2203,7 @@ static ssize_t store_int_with_restart(struct device *s,
static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger);
static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant);
static DEVICE_INT_ATTR(monarch_timeout, 0644, monarch_timeout); static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout);
static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce);
static struct dev_ext_attribute dev_attr_check_interval = { static struct dev_ext_attribute dev_attr_check_interval = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册