Pentium F00F bugfix not working properly.

David Woodhouse (dwmw2@cam.ac.uk)
Thu, 13 Nov 1997 04:36:50 +0000


This is a multipart MIME message.

--==_Exmh_15875177080
Content-Type: text/plain; charset=us-ascii

The F00F bug fix doesn't seem to work on SMP machines.

(This is vger-63, but I don't think the real 63 will be different)

If I boot with init=/bin/bash, and run Crashme, it says

<c4800fc8/c4800ff8>
<handler c0109934... ...done>
Illegal instruction

This is much as expected.

However, if I type "Crashme & Crashme", it dies.
The second Crashme gets as far as "<handler ... done>" before the machine stops
responding. The keyboard still echoes to the screen, VT-switching and sysrq
work, but nothing else happens until the software watchdog kicks in and
reboots it.

With the following patch, it can survive "Crashme & Crashme" at a single-user
prompt (either init=/bin/bash or runlevel 1), but it still does the same as
above when in multi-user mode.

I suppose it's only working on one processor. That was obvious when the idt
was only being changed on one processor, but now what's up with it? The page
fault handler is getting run OK, but it's failing after that.

Any ideas, anyone?

--==_Exmh_15875177080
Content-Type: text/plain ; name="f00fbug-smp-63v"; charset=us-ascii
Content-Description: f00fbug-smp-63v
Content-Disposition: attachment; filename="f00fbug-smp-63v"

--- linux/arch/i386/kernel/smp.c.orig Thu Nov 13 02:39:01 1997
+++ linux/arch/i386/kernel/smp.c Thu Nov 13 03:44:15 1997
@@ -644,6 +644,7 @@
static int cpucount = 0;

extern int cpu_idle(void * unused);
+extern struct f00fbug_idt_struct idt_d;

/*
* Activate a secondary processor.
@@ -651,6 +652,9 @@
__initfunc(int start_secondary(void *unused))
{
smp_callin();
+ if (boot_cpu_data.f00f_bug) {
+ __asm__ __volatile__("\tlidt %0": "=m" (idt_d));
+ }
while (!smp_commenced)
barrier();
return cpu_idle(NULL);
--- linux/arch/i386/kernel/traps.c.orig Thu Nov 13 03:11:19 1997
+++ linux/arch/i386/kernel/traps.c Thu Nov 13 03:41:40 1997
@@ -411,13 +411,7 @@

#endif /* CONFIG_MATH_EMULATION */

-static struct
-{
- short limit __attribute__((packed));
- void * addr __attribute__((packed));
- short __pad __attribute__((packed));
-} idt_d;
-
+struct f00fbug_idt_struct idt_d;
void * idt2;

__initfunc(void trap_init_f00f_bug(void))
--- linux/include/asm-i386/processor.h.orig Thu Nov 13 03:29:48 1997
+++ linux/include/asm-i386/processor.h Thu Nov 13 03:29:52 1997
@@ -216,4 +216,10 @@
#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)

+struct f00fbug_idt_struct {
+ short limit __attribute__((packed));
+ void * addr __attribute__((packed));
+ short __pad __attribute__((packed));
+};
+
#endif /* __ASM_I386_PROCESSOR_H */

--==_Exmh_15875177080
Content-Type: text/plain; charset=us-ascii

---- ---- ----
David Woodhouse, Robinson College, CB3 9AN, England. (+44) 0976 658355
dwmw2@cam.ac.uk http://dwmw2.robinson.cam.ac.uk
finger pgp@dwmw2.robinson.cam.ac.uk for PGP key.

--==_Exmh_15875177080--