(fwd) Pentium Bug Fixed (probably) - please test

Andrey Gerzhov (kittle@freeland.alex-ua.com)
Sun, 16 Nov 1997 14:54:54 +0200 (EET)

-- forwarded message --
Path: freeland.alex-ua.com!barmaglot.alexradio.kiev.ua!f188.n463.z2!f385.n463.z2!f159.n463!f238.n5020!f443.n5020!f400.n5020!ddt.demos.su!fido-news-server
Newsgroups: fido.ru.unix.bsd
Distribution: fido
X-Comment-To: All
From: ivt@gamma.ru (Igor Timkin)
X-FTN-Sender: Igor Timkin <Igor.Timkin@f400.n5020.z2.fidonet.org>
Date: Sat, 15 Nov 97 20:52:12 +0200
Subject: Pentium Bug Fixed (probably) - please test
Message-ID: <64kndu$8k2$1@news.gamma.ru>
Organization: Gamma Ltd., Moscow, Russia
X-FTN-AREA: RU.UNIX.BSD
X-FTN-MSGID: news.gamma.ru 62ee4d8a
X-FTN-Tearline: ifmail v.2.10dev
X-FTN-Origin: Gamma Ltd., Moscow, Russia (2:5020/400@fidonet)
X-FTN-SEEN-BY: 1/6 50/381 520 450/40 461/121 463/5 18 58 94 159 166 188 385 666
X-FTN-SEEN-BY: 464/100 467/67 469/38 999 478/20 4615/21 4626/5 4643/2 5000/7
X-FTN-SEEN-BY: 5001/211 5002/16 5004/16 5006/1 5007/1 5010/21 5011/13 201 5015/28
X-FTN-SEEN-BY: 5020/35 47 52 68 118 193 194 200 204 225 238 240 255 300 302 400
X-FTN-SEEN-BY: 5020/423 443 477 487 509 510 604 1057 5022/5 5023/8 11 5024/8 11
X-FTN-SEEN-BY: 5029/5 5030/87 115 5031/3 5033/2 3 5034/1 5036/1 5048/1 4 5049/1
X-FTN-SEEN-BY: 5049/256 5050/5050 5051/15 5053/16 5054/9 10 5057/1 5060/88 5061/7
X-FTN-SEEN-BY: 5061/15 5064/5 5065/10 5066/2 5069/1 2 5075/10 5077/3 5080/80 1003
X-FTN-SEEN-BY: 5083/21 5084/10 5085/250 5090/2 5100/21
X-FTN-PATH: 5020/400 443 238 463/159 385
X-FTN-PATH: 463/188
Lines: 138
Xref: freeland.alex-ua.com fido.ru.unix.bsd:1628

>From: Troy Curtiss <troyc@frii.com>
>Newsgroups: comp.unix.bsd.freebsd.misc
>Subject: Pentium Bug Fixed (probably) - please test
>Date: Sat, 15 Nov 1997 00:21:13 -0700
>Organization: Front Range Internet, Inc.

Here's a patch from Johnathan Lemon that fixed the pentium f00f bug
on the following machines of mine at home and/or work:

P90 P100 P166MMX
3.0-current untestd FIXED FIXED
2.2.5-stable FIXED FIXED FIXED
2.2.2 FIXED FIXED FIXED

Now instead of a nasty hang, you get a Bus Error/core dump from the
offending process. Hats off to Jonathan!!

-Troy

Here's the original message & patch sent to hackers today:

>From: Jonathan Lemon <jlemon@americantv.com>
>To: hackers@FreeBSD.ORG
>Subject: FreeBSD Pentium Bug fix (proposed)

Alright, I've been watching the debate about the LOCK CMPXCHG8 bug,
and decided to take a crack at it. While I believe that for the most
case, this is probably just a tempest in a teapot, for some, it probably
represents a serious DOS that should be addressed.

IMHO, the "take page fault on any trapno < 7" solution is a very ugly
hack, but it got me thinking about a better way to solve this. The
solution seems to depend on the fact that a page fault has a higher
priority than an illegal instruction fault, and thus, if both are posted
first, then the page fault takes precedence.

This made me think that there might be other faults that also have
higher
precedence than the illegal instruction fault, and which could be
localized
to just the #UD handler. It turns out that exceeding the segment limit
is one of them.

My ``fix'' is to have the IDT descriptor reference a segemnt which has
a length of 0. This has the effect of mapping SIGILL into SIGBUS, so
that
the `cmpxchg8' crash now generates a Bus error. (I didn't bother
returning
the correct signal; it can probably be added if it is important)

This fix works on my machine, takes no overhead, and the only breaks
BDE_DEBUGGER, which wants to hoard all the GDT entries for itself. :-)

I'd appreciate it if interested parties could try this out and see if
it also fixes the problem on other machines.

--
Jonathan

--------------------------------- cut here --------------------------------- Index: machdep.c =================================================================== RCS file: /tuna/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.270 diff -c -r1.270 machdep.c *************** *** 981,986 **** - --- 993,1009 ---- 0, 0, 1, /* default 32 vs 16 bit size */ 1 /* limit granularity (byte/page units)*/ }, + #ifdef CMPXCHG8_BUG + /* GBUG_SEL 11 Invalid Descriptor for CMPXCHG8_BUG */ + { 0x0, /* segment base address */ + 0x0, /* length - none */ + SDT_MEMERA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, + #endif }; static struct soft_segment_descriptor ldt_segs[] = { *************** *** 1209,1216 **** - --- 1232,1244 ---- #endif finishidentcpu(); /* Final stage of CPU initialization */ + #ifdef CMPXCHG8_BUG + setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GBUG_SEL, SEL_KPL)); + #else setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + #endif initializecpu(); /* Initialize CPU registers */ + /* Use BIOS values stored in RTC CMOS RAM, since probing * breaks certain 386 AT relics. Index: include/segments.h =================================================================== RCS file: /tuna/ncvs/src/sys/i386/include/segments.h,v retrieving revision 1.17 diff -c -r1.17 segments.h *** segments.h 1997/08/21 06:32:49 1.17 - --- segments.h 1997/11/14 22:34:58 *************** *** 215,225 **** - --- 215,232 ---- #define GAPMCODE32_SEL 8 /* APM BIOS 32-bit interface (32bit Code) */ #define GAPMCODE16_SEL 9 /* APM BIOS 32-bit interface (16bit Code) */ #define GAPMDATA_SEL 10 /* APM BIOS 32-bit interface (Data) */ + #ifdef CMPXCHG8_BUG + #define GBUG_SEL 11 /* Invalid Descriptor for CMPXCHG8_BUG */ + #endif #ifdef BDE_DEBUGGER #define NGDT 18 /* some of 11-17 are reserved for debugger */ #else + #ifdef CMPXCHG8_BUG + #define NGDT (GBUG_SEL + 1) + #else #define NGDT (GAPMDATA_SEL + 1) + #endif #endif /*

-- end of forwarded message --

-- 

Kittle