From owner-freebsd-security Fri Nov 14 12:41:51 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id MAA02023 for security-outgoing; Fri, 14 Nov 1997 12:41:51 -0800 (PST) (envelope-from owner-freebsd-security) Received: from room101.sysc.com (qmailr@richmojm2.student.rose-hulman.edu [137.112.206.126]) by hub.freebsd.org (8.8.7/8.8.7) with SMTP id MAA02015 for ; Fri, 14 Nov 1997 12:41:47 -0800 (PST) (envelope-from jayrich@room101.sysc.com) Received: (qmail 20400 invoked by uid 1000); 14 Nov 1997 20:41:26 -0000 Date: Fri, 14 Nov 1997 15:41:26 -0500 (EST) From: "Jay M. Richmond" To: freebsd-security@freebsd.org Subject: Re: Pentium bug workaround in NetBSD (was Re: Intel Pentium Bug: BSDI Releases a patch) (fwd) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.2 mQCNAzQe9IMAAAEEAKVCBVhfVHCyNOsNvCwXbamYDslPoBoUgllJxGWrjYr8+XOS mAIo6VNyR6E0Q57SICfxAlw8CfrW3jSFZxCalyAr7f4SU/ioF7qOx9AEeRePKbQD XQYT/eUirjo4h1TzQPWMrlGtnehTJfX4LKLeu8WRsMog/6LMzxBohdeuTAY9AAUR tCJKYXkgTS4gUmljaG1vbmQgPGpheXJpY2hAc3lzYy5jb20+ =PTZq -----END PGP PUBLIC KEY BLOCK----- ---------- Forwarded message ---------- Date: Fri, 14 Nov 1997 09:49:27 -0500 From: "Charles M. Hannum" To: BUGTRAQ@NETSPACE.ORG Subject: Re: Pentium bug workaround in NetBSD (was Re: Intel Pentium Bug: BSDI Releases a patch) It occurs to me that there may be another way to solve this -- with a slightly higher performance penalty. To put it simply: return to user mode and let the instruction be executed again. To make this work, I suggest: * Create the partially mapped IDT as per the BSDI patch. Use it. * Create a second copy of the IDT that it fully mapped. For each vector in this second copy, install a routine which first reloads the IDT pointer to point to the partially mapped IDT and then uses the normal routine. * When we get a page fault, check to see if the fault was in the second IDT, and if so turn off interrupts (with a CLI), load the pointer to the first IDT, gratuitously fetch the IDT descriptor for exception 6 to make sure it's in the cache, and return to user mode (doing an implicit CLI during the IRET). The theory is that we reexecute the faulting instruction with a normal-looking IDT, making sure that the descriptor is in the L1 cache, so we don't get the hang. The only way it would get rotated out of the cache before the instruction is reexecuted would be if an interrupt or exception occurs (i.e. some other code is caused to execute) between when we reload the IDT pointer to the fully mapped IDT and when the instruction is reexecuted. To prevent this, we arrange for any such interrupt or exception to cause the partially mapped IDT to be loaded again, and thus when the interrupt or exception completes, the instruction would cause another page fault. This has a bit more performance impact on debuggers (because trace and breakpoint traps are handled through this mechanism, with an additional ~100 cycles on a 486), but it shouldn't have any of the caveats I previously mentioned. [I'd implement this right now and try it, but I *really* have to go sleep now. Recovering from a cold. *sigh*]