>
> Is the f00f bug workaround in pre-2.0.32-4 supposed to work on SMP
> systems?
Not without patch.
> It doesn't do any good on this dual P120 (instant freeze
> on the first run). (sorry if i'm missing some new patch but
> kernel.org seems to be down).
For SMP you need the below (first) patch, which works fine on my machine.
If all fails you may apply the second patch to disable the workaround via
kernel commandline param 'f00f=no' and take advantage of the rest of fixes
in pre-2.0.32-4.
Hans
<lermen@fgan.de>
first patch:
-------------------- SMP fix for pre-2.0.32-4 -------------------------
--- ../linux-pre-2.0.32-4-clean/arch/i386/kernel/traps.c Fri Nov 14 10:10:13 1997
+++ arch/i386/kernel/traps.c Fri Nov 14 12:28:33 1997
@@ -338,6 +338,10 @@
#endif /* CONFIG_MATH_EMULATION */
struct desc_struct *idt = __idt+0;
+struct {
+ unsigned short limit;
+ unsigned long addr __attribute__((packed));
+} idt_descriptor;
void trap_init_f00f_bug(void)
{
@@ -346,10 +350,6 @@
pte_t * pte;
unsigned long twopage;
struct desc_struct *new_idt;
- struct {
- unsigned short limit;
- unsigned long addr __attribute__((packed));
- } idt_descriptor;
printk("moving IDT ... ");
--- ../linux-pre-2.0.32-4-clean/arch/i386/kernel/smp.c Fri Oct 24 11:34:13 1997
+++ arch/i386/kernel/smp.c Fri Nov 14 14:46:46 1997
@@ -537,7 +537,13 @@
extern void calibrate_delay(void);
int cpuid=GET_APIC_ID(apic_read(APIC_ID));
unsigned long l;
+ extern struct desc_struct idt_descriptor;
+ extern int pentium_f00f_bug;
+ if (pentium_f00f_bug) {
+ __asm__ __volatile__("\tlidt %0": "=m" (idt_descriptor));
+ }
+
/*
* Activate our APIC
*/
-----------------------------------------------------------------------
second patch:
-------------------- f00f workaround switchable via kernel param ------
--- linux-pre-2.0.32-4-clean/include/asm-i386/bugs.h Fri Nov 14 20:48:13 1997
+++ linux/include/asm-i386/bugs.h Fri Nov 14 21:42:10 1997
@@ -130,6 +130,7 @@
* have the F0 0F bug, which lets nonpriviledged users lock up the system:
*/
extern int pentium_f00f_bug;
+extern int pentium_f00f_bug_enable;
extern void trap_init_f00f_bug(void);
static void check_pentium_f00f(void)
@@ -137,8 +138,12 @@
/*
* Pentium and Pentium MMX
*/
- pentium_f00f_bug = 0;
- if (x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12)) {
+ if (pentium_f00f_bug_enable < 0) {
+ pentium_f00f_bug = 0;
+ return;
+ }
+ pentium_f00f_bug = pentium_f00f_bug_enable;
+ if (pentium_f00f_bug || (x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12))) {
printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n");
pentium_f00f_bug = 1;
trap_init_f00f_bug();
--- linux-pre-2.0.32-4-clean/arch/i386/kernel/setup.c Fri Nov 14 20:48:13 1997
+++ linux/arch/i386/kernel/setup.c Fri Nov 14 21:52:13 1997
@@ -43,6 +43,7 @@
int x86_capability = 0; /* set by kernel/head.S */
int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */
int pentium_f00f_bug = 0; /* set if Pentium(TM) with F00F bug */
+int pentium_f00f_bug_enable = -1; /* set via kernel parameter 'f00f={no|yes|force}' */
int have_cpuid = 0; /* set if CPUID instruction works */
char x86_vendor_id[13] = "unknown";
@@ -170,6 +171,24 @@
memory_end = memory_end << 20;
from++;
}
+ }
+ }
+ else if (c == ' ' && !memcmp(from, "f00f=", 5)) {
+ if (to != command_line) to--;
+ if (!memcmp(from+5, "no", 2)) {
+ from += 5+2;
+ pentium_f00f_bug_enable = -1;
+ }
+ else if (!memcmp(from+5, "yes", 3)) {
+ from += 5+3;
+ pentium_f00f_bug_enable = 0;
+ }
+ else if (!memcmp(from+5, "force", 5)) {
+ from += 5+5;
+ /* NOTE: this just to test the f00f workaround
+ * on a PPro or above
+ */
+ pentium_f00f_bug_enable = 1;
}
}
c = *(from++);
-----------------------------------------------------------------------