summaryrefslogtreecommitdiffstats
path: root/include/asm-i386/bugs.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
commit545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch)
treee9ce4bc598d06374bda906f18365984bf22a526a /include/asm-i386/bugs.h
parent4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff)
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'include/asm-i386/bugs.h')
-rw-r--r--include/asm-i386/bugs.h73
1 files changed, 58 insertions, 15 deletions
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index a19ff035e..2e83b1b48 100644
--- a/include/asm-i386/bugs.h
+++ b/include/asm-i386/bugs.h
@@ -12,15 +12,16 @@
*/
#include <linux/config.h>
+#include <asm/processor.h>
#define CONFIG_BUGi386
-static void no_halt(char *s, int *ints)
+__initfunc(static void no_halt(char *s, int *ints))
{
hlt_works_ok = 0;
}
-static void no_387(char *s, int *ints)
+__initfunc(static void no_387(char *s, int *ints))
{
hard_math = 0;
__asm__("movl %%cr0,%%eax\n\t"
@@ -28,9 +29,9 @@ static void no_387(char *s, int *ints)
"movl %%eax,%%cr0\n\t" : : : "ax");
}
-static char fpu_error = 0;
+static char __initdata fpu_error = 0;
-static void copro_timeout(void)
+__initfunc(static void copro_timeout(void))
{
fpu_error = 1;
timer_table[COPRO_TIMER].expires = jiffies+100;
@@ -41,10 +42,11 @@ static void copro_timeout(void)
outb_p(0,0xf0);
}
-static void check_fpu(void)
+static double __initdata x = 4195835.0;
+static double __initdata y = 3145727.0;
+
+__initfunc(static void check_fpu(void))
{
- static double x = 4195835.0;
- static double y = 3145727.0;
unsigned short control_word;
if (!hard_math) {
@@ -91,15 +93,13 @@ static void check_fpu(void)
"fninit"
: "=m" (*&fdiv_bug)
: "m" (*&x), "m" (*&y));
- if (!fdiv_bug) {
+ if (!fdiv_bug)
printk("Ok, fpu using exception 16 error reporting.\n");
- return;
-
- }
- printk("Hmm, FDIV bug i%c86 system\n", '0'+x86);
+ else
+ printk("Hmm, fpu using exception 16 error reporting with FDIV bug.\n");
}
-static void check_hlt(void)
+__initfunc(static void check_hlt(void))
{
printk(KERN_INFO "Checking 'hlt' instruction... ");
if (!hlt_works_ok) {
@@ -110,7 +110,7 @@ static void check_hlt(void)
printk("Ok.\n");
}
-static void check_tlb(void)
+__initfunc(static void check_tlb(void))
{
#ifndef CONFIG_M386
/*
@@ -125,10 +125,53 @@ static void check_tlb(void)
#endif
}
-static void check_bugs(void)
+/*
+ * Most 386 processors have a bug where a POPAD can lock the
+ * machine even from user space.
+ */
+
+__initfunc(static void check_popad(void))
+{
+#ifdef CONFIG_M386
+ int res, inp = (int) &res;
+
+ printk(KERN_INFO "Checking for popad bug... ");
+ __asm__ __volatile__(
+ "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx "
+ : "=eax" (res)
+ : "edx" (inp)
+ : "eax", "ecx", "edx", "edi" );
+ /* If this fails, it means that any user program may lock CPU hard. Too bad. */
+ if (res != 12345678) printk( "Bad.\n" );
+ else printk( "Ok.\n" );
+#endif
+}
+
+/*
+ * B step AMD K6 before B 9729AIJW have hardware bugs that can cause
+ * misexecution of code under Linux. Owners of such processors should
+ * contact AMD for precise details and a CPU swap.
+ *
+ * See http://www.creaweb.fr/bpc/k6bug_faq.html
+ * http://www.amd.com/K6/k6docs/revgd.html
+ */
+
+__initfunc(static void check_amd_k6(void))
+{
+ /* B Step AMD K6 */
+ if(x86_model==6 && x86_mask==1 && memcmp(x86_vendor_id, "AuthenticAMD", 12)==0)
+ {
+ printk(KERN_INFO "AMD K6 stepping B detected - system stability may be impaired. Please see.\n");
+ printk(KERN_INFO "http://www.creaweb.fr/bpc/k6bug_faq.html");
+ }
+}
+
+__initfunc(static void check_bugs(void))
{
check_tlb();
check_fpu();
check_hlt();
+ check_popad();
+ check_amd_k6();
system_utsname.machine[1] = '0' + x86;
}