Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 148885
b: refs/heads/master
c: 4efc067
h: refs/heads/master
i:
  148883: 58ce38e
v: v3
  • Loading branch information
Andi Kleen authored and H. Peter Anvin committed May 28, 2009
1 parent a3b14eb commit f4acdcf
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d896a940ef4f12a0a6bc432853b249dcfbacabf0
refs/heads/master: 4efc0670baf4b14bc95502e54a83ccf639146125
33 changes: 31 additions & 2 deletions trunk/arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,22 @@ config X86_MCE
to disable it. MCE support simply ignores non-MCE processors like
the 386 and 486, so nearly everyone can say Y here.

config X86_OLD_MCE
depends on X86_32 && X86_MCE
bool "Use legacy machine check code (will go away)"
default n
select X86_ANCIENT_MCE
---help---
Use the old i386 machine check code. This is merely intended for
testing in a transition period. Try this if you run into any machine
check related software problems, but report the problem to
linux-kernel. When in doubt say no.

config X86_NEW_MCE
depends on X86_MCE
bool
default y if (!X86_OLD_MCE && X86_32) || X86_64

config X86_MCE_INTEL
def_bool y
prompt "Intel MCE features"
Expand All @@ -805,14 +821,23 @@ config X86_MCE_AMD
Additional support for AMD specific MCE features such as
the DRAM Error Threshold.

config X86_ANCIENT_MCE
def_bool n
depends on X86_32
prompt "Support for old Pentium 5 / WinChip machine checks"
---help---
Include support for machine check handling on old Pentium 5 or WinChip
systems. These typically need to be enabled explicitely on the command
line.

config X86_MCE_THRESHOLD
depends on X86_MCE_AMD || X86_MCE_INTEL
bool
default y

config X86_MCE_NONFATAL
tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
depends on X86_32 && X86_MCE
depends on X86_OLD_MCE
---help---
Enabling this feature starts a timer that triggers every 5 seconds which
will look at the machine check registers to see if anything happened.
Expand All @@ -825,11 +850,15 @@ config X86_MCE_NONFATAL

config X86_MCE_P4THERMAL
bool "check for P4 thermal throttling interrupt."
depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP)
depends on X86_OLD_MCE && X86_MCE && (X86_UP_APIC || SMP)
---help---
Enabling this feature will cause a message to be printed when the P4
enters thermal throttling.

config X86_THERMAL_VECTOR
def_bool y
depends on X86_MCE_P4THERMAL || X86_MCE_INTEL

config VM86
bool "Enable VM86 support" if EMBEDDED
default y
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/include/asm/entry_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
BUILD_INTERRUPT(perf_counter_interrupt, LOCAL_PERF_VECTOR)
#endif

#ifdef CONFIG_X86_MCE_P4THERMAL
#ifdef CONFIG_X86_THERMAL_VECTOR
BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
#endif

Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ void clear_local_APIC(void)
}

/* lets not touch this if we didn't frob it */
#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
#ifdef CONFIG_X86_THERMAL_VECTOR
if (maxlvt >= 5) {
v = apic_read(APIC_LVTTHMR);
apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
Expand Down Expand Up @@ -1962,7 +1962,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
#ifdef CONFIG_X86_THERMAL_VECTOR
if (maxlvt >= 5)
apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
#endif
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/apic/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static inline unsigned int get_nmi_count(int cpu)

static inline int mce_in_progress(void)
{
#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
#if defined(CONFIG_X86_NEW_MCE)
return atomic_read(&mce_entry) > 0;
#endif
return 0;
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/x86/kernel/cpu/mcheck/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
obj-y = mce.o therm_throt.o

obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o
obj-$(CONFIG_X86_OLD_MCE) += k7.o p4.o p6.o
obj-$(CONFIG_X86_ANCIENT_MCE) += winchip.o p5.o
obj-$(CONFIG_X86_MCE_P4THERMAL) += mce_intel.o
obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o mce_intel.o
obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o
Expand Down
32 changes: 28 additions & 4 deletions trunk/arch/x86/kernel/cpu/mcheck/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void (*machine_check_vector)(struct pt_regs *, long error_code) =

int mce_disabled;

#ifdef CONFIG_X86_64
#ifdef CONFIG_X86_NEW_MCE

#define MISC_MCELOG_MINOR 227

Expand Down Expand Up @@ -662,6 +662,21 @@ static void mce_cpu_quirks(struct cpuinfo_x86 *c)
}
}

static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c)
{
if (c->x86 != 5)
return;
switch (c->x86_vendor) {
case X86_VENDOR_INTEL:
if (mce_p5_enabled())
intel_p5_mcheck_init(c);
break;
case X86_VENDOR_CENTAUR:
winchip_mcheck_init(c);
break;
}
}

static void mce_cpu_features(struct cpuinfo_x86 *c)
{
switch (c->x86_vendor) {
Expand Down Expand Up @@ -695,6 +710,11 @@ static void mce_init_timer(void)
*/
void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
{
if (mce_disabled)
return;

mce_ancient_init(c);

if (!mce_available(c))
return;

Expand Down Expand Up @@ -893,20 +913,24 @@ static struct miscdevice mce_log_device = {
*/
static int __init mcheck_enable(char *str)
{
if (*str == 0)
enable_p5_mce();
if (*str == '=')
str++;
if (!strcmp(str, "off"))
mce_disabled = 1;
else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog"))
mce_bootlog = (str[0] == 'b');
else if (isdigit(str[0]))
get_option(&str, &tolerant);
else {
printk(KERN_INFO "mce= argument %s ignored. Please use /sys\n",
printk(KERN_INFO "mce argument %s ignored. Please use /sys\n",
str);
return 0;
}
return 1;
}
__setup("mce=", mcheck_enable);
__setup("mce", mcheck_enable);

/*
* Sysfs support
Expand Down Expand Up @@ -1259,7 +1283,7 @@ static __init int mce_init_device(void)

device_initcall(mce_init_device);

#else /* CONFIG_X86_32: */
#else /* CONFIG_X86_OLD_MCE: */

int nr_mce_banks;
EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */
Expand Down
18 changes: 15 additions & 3 deletions trunk/arch/x86/kernel/cpu/mcheck/mce.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
#include <linux/init.h>
#include <asm/mce.h>

#ifdef CONFIG_X86_OLD_MCE
void amd_mcheck_init(struct cpuinfo_x86 *c);
void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
void winchip_mcheck_init(struct cpuinfo_x86 *c);
#endif

#ifdef CONFIG_X86_ANCIENT_MCE
void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
void winchip_mcheck_init(struct cpuinfo_x86 *c);
extern int mce_p5_enable;
static inline int mce_p5_enabled(void) { return mce_p5_enable; }
static inline void enable_p5_mce(void) { mce_p5_enable = 1; }
#else
static inline void intel_p5_mcheck_init(struct cpuinfo_x86 *c) {}
static inline void winchip_mcheck_init(struct cpuinfo_x86 *c) {}
static inline int mce_p5_enabled(void) { return 0; }
static inline void enable_p5_mce(void) { }
#endif

/* Call the installed machine check handler for this CPU setup. */
extern void (*machine_check_vector)(struct pt_regs *, long error_code);

#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_OLD_MCE

extern int nr_mce_banks;

Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/x86/kernel/cpu/mcheck/p5.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#include "mce.h"

/* By default disabled */
int mce_p5_enable;

/* Machine check handler for Pentium class Intel CPUs: */
static void pentium_machine_check(struct pt_regs *regs, long error_code)
{
Expand Down Expand Up @@ -44,9 +47,11 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
if (!cpu_has(c, X86_FEATURE_MCE))
return;

#ifdef CONFIG_X86_OLD_MCE
/* Default P5 to off as its often misconnected: */
if (mce_disabled != -1)
return;
#endif

machine_check_vector = pentium_machine_check;
/* Make sure the vector pointer is visible before we enable MCEs: */
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static int show_other_interrupts(struct seq_file *p, int prec)
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
seq_printf(p, " Thermal event interrupts\n");
# ifdef CONFIG_X86_64
# ifdef CONFIG_X86_MCE_THRESHOLD
seq_printf(p, "%*s: ", prec, "THR");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
Expand Down Expand Up @@ -176,7 +176,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
#endif
#ifdef CONFIG_X86_MCE
sum += irq_stats(cpu)->irq_thermal_count;
# ifdef CONFIG_X86_64
# ifdef CONFIG_X86_MCE_THRESHOLD
sum += irq_stats(cpu)->irq_threshold_count;
#endif
#endif
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/x86/kernel/irqinit_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void __init native_init_IRQ(void)
alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
#endif

#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_MCE_P4THERMAL)
#ifdef CONFIG_X86_THERMAL_VECTOR
/* thermal monitor LVT interrupt */
alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
#include <asm/ucontext.h>
#include <asm/i387.h>
#include <asm/vdso.h>
#include <asm/mce.h>

#ifdef CONFIG_X86_64
#include <asm/proto.h>
#include <asm/ia32_unistd.h>
#include <asm/mce.h>
#endif /* CONFIG_X86_64 */

#include <asm/syscall.h>
Expand Down Expand Up @@ -857,7 +857,7 @@ static void do_signal(struct pt_regs *regs)
void
do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
{
#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
#ifdef CONFIG_X86_NEW_MCE
/* notify userspace of pending MCEs */
if (thread_info_flags & _TIF_MCE_NOTIFY)
mce_notify_user();
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,15 +798,15 @@ unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)

return new_kesp;
}
#else
#endif

asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
{
}

asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
{
}
#endif

/*
* 'math_state_restore()' saves the current math information in the
Expand Down

0 comments on commit f4acdcf

Please sign in to comment.