Commit a1bae672 authored by Andi Kleen's avatar Andi Kleen Committed by Andi Kleen

[PATCH] i386: Disable nmi watchdog on all ThinkPads

Even newer Thinkpads have bugs in SMM code that causes hangs with
NMI watchdog.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 581910e2
......@@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void)
int cpu;
/* Enable NMI watchdog for newer systems.
Actually it should be safe for most systems before 2004 too except
for some IBM systems that corrupt registers when NMI happens
during SMM. Unfortunately we don't have more exact information
on these and use this coarse check. */
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
Probably safe on most older systems too, but let's be careful.
IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
which hangs the system. Disable watchdog for all thinkpads */
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
!dmi_name_in_vendors("ThinkPad"))
nmi_watchdog = NMI_LOCAL_APIC;
if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
......
......@@ -326,6 +326,26 @@ char *dmi_get_system_info(int field)
}
EXPORT_SYMBOL(dmi_get_system_info);
/**
* dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
* @str: Case sensitive Name
*/
int dmi_name_in_vendors(char *str)
{
static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
int i;
for (i = 0; fields[i] != DMI_NONE; i++) {
int f = fields[i];
if (dmi_ident[f] && strstr(dmi_ident[f], str))
return 1;
}
return 0;
}
EXPORT_SYMBOL(dmi_name_in_vendors);
/**
* dmi_find_device - find onboard device by type/name
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
......
......@@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from);
extern void dmi_scan_machine(void);
extern int dmi_get_year(int field);
extern int dmi_name_in_vendors(char *str);
#else
......@@ -77,6 +78,7 @@ static inline char * dmi_get_system_info(int field) { return NULL; }
static inline struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from) { return NULL; }
static inline int dmi_get_year(int year) { return 0; }
static inline int dmi_name_in_vendors(char *s) { return 0; }
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment