diff options
author | Borislav Petkov <bp@alien8.de> | 2012-10-15 13:59:18 -0400 |
---|---|---|
committer | Borislav Petkov <bp@alien8.de> | 2012-10-26 08:37:57 -0400 |
commit | 84c2559dee2d69606f1fd4ce6563e79e7611a7b7 (patch) | |
tree | 086357642419bb7d887071e5ce0ec832411abc7d | |
parent | d203f0b82481abc048e134ee4d0ea3efbee77bb1 (diff) |
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: Borislav Petkov <bp@alien8.de>
Acked-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/x86/include/asm/mce.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 51 |
2 files changed, 30 insertions, 24 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index e4060de88476..73ba1853951a 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -123,7 +123,10 @@ struct mce_log { | |||
123 | struct mca_config { | 123 | struct mca_config { |
124 | bool dont_log_ce; | 124 | bool dont_log_ce; |
125 | u8 banks; | 125 | u8 banks; |
126 | s8 bootlog; | ||
126 | int tolerant; | 127 | int tolerant; |
128 | int monarch_timeout; | ||
129 | u32 rip_msr; | ||
127 | }; | 130 | }; |
128 | 131 | ||
129 | extern void mce_register_decode_chain(struct notifier_block *nb); | 132 | extern void mce_register_decode_chain(struct notifier_block *nb); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 10f4d256d9e8..aa11019eeb0e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -66,9 +66,6 @@ atomic_t mce_entry; | |||
66 | 66 | ||
67 | DEFINE_PER_CPU(unsigned, mce_exception_count); | 67 | DEFINE_PER_CPU(unsigned, mce_exception_count); |
68 | 68 | ||
69 | static int rip_msr __read_mostly; | ||
70 | static int mce_bootlog __read_mostly = -1; | ||
71 | static int monarch_timeout __read_mostly = -1; | ||
72 | static int mce_panic_timeout __read_mostly; | 69 | static int mce_panic_timeout __read_mostly; |
73 | int mce_cmci_disabled __read_mostly; | 70 | int mce_cmci_disabled __read_mostly; |
74 | int mce_ignore_ce __read_mostly; | 71 | int mce_ignore_ce __read_mostly; |
@@ -78,6 +75,7 @@ int mce_bios_cmci_threshold __read_mostly; | |||
78 | struct mce_bank *mce_banks __read_mostly; | 75 | struct mce_bank *mce_banks __read_mostly; |
79 | 76 | ||
80 | struct mca_config mca_cfg __read_mostly = { | 77 | struct mca_config mca_cfg __read_mostly = { |
78 | .bootlog = -1, | ||
81 | /* | 79 | /* |
82 | * Tolerant levels: | 80 | * Tolerant levels: |
83 | * 0: always panic on uncorrected errors, log corrected errors | 81 | * 0: always panic on uncorrected errors, log corrected errors |
@@ -85,7 +83,8 @@ struct mca_config mca_cfg __read_mostly = { | |||
85 | * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors | 83 | * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors |
86 | * 3: never panic or SIGBUS, log all errors (for testing only) | 84 | * 3: never panic or SIGBUS, log all errors (for testing only) |
87 | */ | 85 | */ |
88 | .tolerant = 1 | 86 | .tolerant = 1, |
87 | .monarch_timeout = -1 | ||
89 | }; | 88 | }; |
90 | 89 | ||
91 | /* User mode helper program triggered by machine check event */ | 90 | /* User mode helper program triggered by machine check event */ |
@@ -373,7 +372,7 @@ static int msr_to_offset(u32 msr) | |||
373 | { | 372 | { |
374 | unsigned bank = __this_cpu_read(injectm.bank); | 373 | unsigned bank = __this_cpu_read(injectm.bank); |
375 | 374 | ||
376 | if (msr == rip_msr) | 375 | if (msr == mca_cfg.rip_msr) |
377 | return offsetof(struct mce, ip); | 376 | return offsetof(struct mce, ip); |
378 | if (msr == MSR_IA32_MCx_STATUS(bank)) | 377 | if (msr == MSR_IA32_MCx_STATUS(bank)) |
379 | return offsetof(struct mce, status); | 378 | return offsetof(struct mce, status); |
@@ -452,8 +451,8 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs) | |||
452 | m->cs |= 3; | 451 | m->cs |= 3; |
453 | } | 452 | } |
454 | /* Use accurate RIP reporting if available. */ | 453 | /* Use accurate RIP reporting if available. */ |
455 | if (rip_msr) | 454 | if (mca_cfg.rip_msr) |
456 | m->ip = mce_rdmsrl(rip_msr); | 455 | m->ip = mce_rdmsrl(mca_cfg.rip_msr); |
457 | } | 456 | } |
458 | } | 457 | } |
459 | 458 | ||
@@ -697,7 +696,7 @@ static int mce_timed_out(u64 *t) | |||
697 | rmb(); | 696 | rmb(); |
698 | if (atomic_read(&mce_paniced)) | 697 | if (atomic_read(&mce_paniced)) |
699 | wait_for_panic(); | 698 | wait_for_panic(); |
700 | if (!monarch_timeout) | 699 | if (!mca_cfg.monarch_timeout) |
701 | goto out; | 700 | goto out; |
702 | if ((s64)*t < SPINUNIT) { | 701 | if ((s64)*t < SPINUNIT) { |
703 | /* CHECKME: Make panic default for 1 too? */ | 702 | /* CHECKME: Make panic default for 1 too? */ |
@@ -803,7 +802,7 @@ static int mce_start(int *no_way_out) | |||
803 | { | 802 | { |
804 | int order; | 803 | int order; |
805 | int cpus = num_online_cpus(); | 804 | int cpus = num_online_cpus(); |
806 | u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; | 805 | u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; |
807 | 806 | ||
808 | if (!timeout) | 807 | if (!timeout) |
809 | return -1; | 808 | return -1; |
@@ -867,7 +866,7 @@ static int mce_start(int *no_way_out) | |||
867 | static int mce_end(int order) | 866 | static int mce_end(int order) |
868 | { | 867 | { |
869 | int ret = -1; | 868 | int ret = -1; |
870 | u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; | 869 | u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; |
871 | 870 | ||
872 | if (!timeout) | 871 | if (!timeout) |
873 | goto reset; | 872 | goto reset; |
@@ -1427,7 +1426,7 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
1427 | 1426 | ||
1428 | /* Use accurate RIP reporting if available. */ | 1427 | /* Use accurate RIP reporting if available. */ |
1429 | if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9) | 1428 | if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9) |
1430 | rip_msr = MSR_IA32_MCG_EIP; | 1429 | mca_cfg.rip_msr = MSR_IA32_MCG_EIP; |
1431 | 1430 | ||
1432 | if (cap & MCG_SER_P) | 1431 | if (cap & MCG_SER_P) |
1433 | mce_ser = 1; | 1432 | mce_ser = 1; |
@@ -1437,15 +1436,19 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
1437 | 1436 | ||
1438 | static void __mcheck_cpu_init_generic(void) | 1437 | static void __mcheck_cpu_init_generic(void) |
1439 | { | 1438 | { |
1439 | enum mcp_flags m_fl = 0; | ||
1440 | mce_banks_t all_banks; | 1440 | mce_banks_t all_banks; |
1441 | u64 cap; | 1441 | u64 cap; |
1442 | int i; | 1442 | int i; |
1443 | 1443 | ||
1444 | if (!mca_cfg.bootlog) | ||
1445 | m_fl = MCP_DONTLOG; | ||
1446 | |||
1444 | /* | 1447 | /* |
1445 | * Log the machine checks left over from the previous reset. | 1448 | * Log the machine checks left over from the previous reset. |
1446 | */ | 1449 | */ |
1447 | bitmap_fill(all_banks, MAX_NR_BANKS); | 1450 | bitmap_fill(all_banks, MAX_NR_BANKS); |
1448 | machine_check_poll(MCP_UC|(!mce_bootlog ? MCP_DONTLOG : 0), &all_banks); | 1451 | machine_check_poll(MCP_UC | m_fl, &all_banks); |
1449 | 1452 | ||
1450 | set_in_cr4(X86_CR4_MCE); | 1453 | set_in_cr4(X86_CR4_MCE); |
1451 | 1454 | ||
@@ -1511,12 +1514,12 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
1511 | */ | 1514 | */ |
1512 | clear_bit(10, (unsigned long *)&mce_banks[4].ctl); | 1515 | clear_bit(10, (unsigned long *)&mce_banks[4].ctl); |
1513 | } | 1516 | } |
1514 | if (c->x86 <= 17 && mce_bootlog < 0) { | 1517 | if (c->x86 <= 17 && cfg->bootlog < 0) { |
1515 | /* | 1518 | /* |
1516 | * Lots of broken BIOS around that don't clear them | 1519 | * Lots of broken BIOS around that don't clear them |
1517 | * by default and leave crap in there. Don't log: | 1520 | * by default and leave crap in there. Don't log: |
1518 | */ | 1521 | */ |
1519 | mce_bootlog = 0; | 1522 | cfg->bootlog = 0; |
1520 | } | 1523 | } |
1521 | /* | 1524 | /* |
1522 | * Various K7s with broken bank 0 around. Always disable | 1525 | * 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 | * synchronization with a one second timeout. | 1584 | * synchronization with a one second timeout. |
1582 | */ | 1585 | */ |
1583 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && | 1586 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && |
1584 | monarch_timeout < 0) | 1587 | cfg->monarch_timeout < 0) |
1585 | monarch_timeout = USEC_PER_SEC; | 1588 | cfg->monarch_timeout = USEC_PER_SEC; |
1586 | 1589 | ||
1587 | /* | 1590 | /* |
1588 | * There are also broken BIOSes on some Pentium M and | 1591 | * There are also broken BIOSes on some Pentium M and |
1589 | * earlier systems: | 1592 | * earlier systems: |
1590 | */ | 1593 | */ |
1591 | if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) | 1594 | if (c->x86 == 6 && c->x86_model <= 13 && cfg->bootlog < 0) |
1592 | mce_bootlog = 0; | 1595 | cfg->bootlog = 0; |
1593 | 1596 | ||
1594 | if (c->x86 == 6 && c->x86_model == 45) | 1597 | if (c->x86 == 6 && c->x86_model == 45) |
1595 | quirk_no_way_out = quirk_sandybridge_ifu; | 1598 | quirk_no_way_out = quirk_sandybridge_ifu; |
1596 | } | 1599 | } |
1597 | if (monarch_timeout < 0) | 1600 | if (cfg->monarch_timeout < 0) |
1598 | monarch_timeout = 0; | 1601 | cfg->monarch_timeout = 0; |
1599 | if (mce_bootlog != 0) | 1602 | if (cfg->bootlog != 0) |
1600 | mce_panic_timeout = 30; | 1603 | mce_panic_timeout = 30; |
1601 | 1604 | ||
1602 | return 0; | 1605 | return 0; |
@@ -1975,14 +1978,14 @@ static int __init mcheck_enable(char *str) | |||
1975 | else if (!strcmp(str, "ignore_ce")) | 1978 | else if (!strcmp(str, "ignore_ce")) |
1976 | mce_ignore_ce = 1; | 1979 | mce_ignore_ce = 1; |
1977 | else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) | 1980 | else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) |
1978 | mce_bootlog = (str[0] == 'b'); | 1981 | cfg->bootlog = (str[0] == 'b'); |
1979 | else if (!strcmp(str, "bios_cmci_threshold")) | 1982 | else if (!strcmp(str, "bios_cmci_threshold")) |
1980 | mce_bios_cmci_threshold = 1; | 1983 | mce_bios_cmci_threshold = 1; |
1981 | else if (isdigit(str[0])) { | 1984 | else if (isdigit(str[0])) { |
1982 | get_option(&str, &(cfg->tolerant)); | 1985 | get_option(&str, &(cfg->tolerant)); |
1983 | if (*str == ',') { | 1986 | if (*str == ',') { |
1984 | ++str; | 1987 | ++str; |
1985 | get_option(&str, &monarch_timeout); | 1988 | get_option(&str, &(cfg->monarch_timeout)); |
1986 | } | 1989 | } |
1987 | } else { | 1990 | } else { |
1988 | pr_info("mce argument %s ignored. Please use /sys\n", str); | 1991 | 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 | 2203 | ||
2201 | static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); | 2204 | static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); |
2202 | static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); | 2205 | static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); |
2203 | static DEVICE_INT_ATTR(monarch_timeout, 0644, monarch_timeout); | 2206 | static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout); |
2204 | static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); | 2207 | static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); |
2205 | 2208 | ||
2206 | static struct dev_ext_attribute dev_attr_check_interval = { | 2209 | static struct dev_ext_attribute dev_attr_check_interval = { |