summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Roedel <joro@8bytes.org>2008-08-17 00:25:07 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-20 11:15:47 -0700
commit7f455504768b59700186ca291aa6a7b68a787330 (patch)
tree0bd4718cf106314146125c9265928442fce51f4e
parent139d09bb6ec8af8de216b0e8b04304d3f5f396bf (diff)
downloadlinux-stable-7f455504768b59700186ca291aa6a7b68a787330.tar.gz
linux-stable-7f455504768b59700186ca291aa6a7b68a787330.tar.bz2
linux-stable-7f455504768b59700186ca291aa6a7b68a787330.zip
x86: fix setup code crashes on my old 486 box
commit 7b27718bdb1b70166383dec91391df5534d449ee upstream yesterday I tried to reactivate my old 486 box and wanted to install a current Linux with latest kernel on it. But it turned out that the latest kernel does not boot because the machine crashes early in the setup code. After some debugging it turned out that the problem is the query_ist() function. If this interrupt with that function is called the machine simply locks up. It looks like a BIOS bug. Looking for a workaround for this problem I wrote the attached patch. It checks for the CPUID instruction and if it is not implemented it does not call the speedstep BIOS function. As far as I know speedstep should be available since some Pentium earliest. Alan Cox observed that it's available since the Pentium II, so cpuid levels 4 and 5 can be excluded altogether. H. Peter Anvin cleaned up the code some more: > Right in concept, but I dislike the implementation (duplication of the > CPU detect code we already have). Could you try this patch and see if > it works for you? which, with a small modification to fix a build error with it the resulting kernel boots on my machine. Signed-off-by: Joerg Roedel <joro@8bytes.org> Signed-off-by: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/x86/boot/boot.h8
-rw-r--r--arch/x86/boot/cpucheck.c8
-rw-r--r--arch/x86/boot/main.c4
3 files changed, 13 insertions, 7 deletions
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index 7822a4983da2..4f199c1f8186 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -27,6 +27,8 @@
#include <asm/boot.h>
#include <asm/setup.h>
+#define NCAPINTS 8
+
/* Useful macros */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
@@ -244,6 +246,12 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);
/* cpu.c, cpucheck.c */
+struct cpu_features {
+ int level; /* Family, or 64 for x86-64 */
+ int model;
+ u32 flags[NCAPINTS];
+};
+extern struct cpu_features cpu;
int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
int validate_cpu(void);
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 769065bd23d7..b93b194bb533 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -32,13 +32,7 @@
#include <asm/required-features.h>
#include <asm/msr-index.h>
-struct cpu_features {
- int level; /* Family, or 64 for x86-64 */
- int model;
- u32 flags[NCAPINTS];
-};
-
-static struct cpu_features cpu;
+struct cpu_features cpu;
static u32 cpu_vendor[3];
static u32 err_flags[NCAPINTS];
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 7828da5cfd07..3d86d659021b 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -75,6 +75,10 @@ static void keyboard_set_repeat(void)
*/
static void query_ist(void)
{
+ /* Some 486 BIOSes apparently crash on this call */
+ if (cpu.level < 6)
+ return;
+
asm("int $0x15"
: "=a" (boot_params.ist_info.signature),
"=b" (boot_params.ist_info.command),