Re: New pentium bug workaround - please test..

Mikael Pettersson (Mikael.Pettersson@sophia.inria.fr)
Fri, 21 Nov 1997 11:19:55 +0100 (MET)


On Thu, 20 Nov 1997, Hans Lermen wrote:
>
> On Wed, 19 Nov 1997, Linus Torvalds wrote:
>
> > What we could just do, is to re-use the original page that contained the
> > very original IDT - and keep modifying that original page through its
> > original address.
>
> Ok, done, tested, works. Patch for vanilla 2.0.32 is appended.

Good work. Just to clean up things a little: with the new version
of the workaround, we no longer need the indirect pointer to the
idt that was introduced to support the previous workaround.
The patch below (apply to 2.0.32 after Hans' patch) fixes that.
(Oh, and it also moves a duplicated type definition into
include/linux/head.h. Why isn't that x86-specific file in asm-i386?)

/Mikael

--- include/linux/head.h.~1~ Fri Nov 14 00:53:58 1997
+++ include/linux/head.h Fri Nov 21 01:50:11 1997
@@ -1,12 +1,20 @@
#ifndef _LINUX_HEAD_H
#define _LINUX_HEAD_H

-typedef struct desc_struct {
+struct desc_struct {
unsigned long a,b;
-} desc_table[256];
+};

-extern desc_table __idt,gdt;
-extern struct desc_struct *idt;
+extern struct desc_struct idt[], gdt[];
+
+/*
+ * gt_desc_struct describes the layout of the global table
+ * descriptors loaded by the x86 LGDT and LIDT instructions
+ */
+struct gt_desc_struct {
+ unsigned short limit;
+ unsigned long addr __attribute__((packed));
+};

#define GDT_NUL 0
#define GDT_CODE 1
--- arch/i386/mm/fault.c.~1~ Thu Nov 20 19:33:11 1997
+++ arch/i386/mm/fault.c Fri Nov 21 01:45:08 1997
@@ -127,10 +127,7 @@
*/
if ( pentium_f00f_bug ) {
unsigned long nr;
- extern struct {
- unsigned short limit;
- unsigned long addr __attribute__((packed));
- } idt_descriptor;
+ extern struct gt_desc_struct idt_descriptor;

nr = (address - idt_descriptor.addr) >> 3;

--- arch/i386/kernel/head.S.~1~ Thu Nov 20 19:33:11 1997
+++ arch/i386/kernel/head.S Fri Nov 21 02:03:41 1997
@@ -260,7 +260,7 @@
movw %dx,%ax /* selector = 0x0010 = cs */
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */

- lea SYMBOL_NAME(__idt),%edi
+ lea SYMBOL_NAME(idt),%edi
mov $256,%ecx
rp_sidt:
movl %eax,(%edi)
@@ -342,9 +342,9 @@
.long SYMBOL_NAME(init_user_stack)+4096
.long KERNEL_DS

-/* NOTE: keep the __idt short behind the above '.org 0x6000'
+/* NOTE: keep the idt short behind the above '.org 0x6000'
It must fit completely within _one_ page */
-ENTRY(__idt)
+ENTRY(idt)
.fill 256,8,0 # idt is uninitialized

/* This is the default interrupt "handler" :-) */
@@ -381,7 +381,7 @@
.word 0
idt_descr:
.word 256*8-1 # idt contains 256 entries
- .long 0xc0000000+SYMBOL_NAME(__idt)
+ .long 0xc0000000+SYMBOL_NAME(idt)

ALIGN
.word 0
--- arch/i386/kernel/traps.c.~1~ Thu Nov 20 19:33:11 1997
+++ arch/i386/kernel/traps.c Fri Nov 21 01:44:55 1997
@@ -337,11 +337,7 @@

#endif /* CONFIG_MATH_EMULATION */

-struct desc_struct *idt = __idt+0;
-struct {
- unsigned short limit;
- unsigned long addr __attribute__((packed));
-} idt_descriptor;
+struct gt_desc_struct idt_descriptor;

void trap_init_f00f_bug(void)
{
--- arch/i386/kernel/smp.c.~1~ Fri Nov 14 17:12:25 1997
+++ arch/i386/kernel/smp.c Fri Nov 21 01:16:29 1997
@@ -537,7 +537,7 @@
extern void calibrate_delay(void);
int cpuid=GET_APIC_ID(apic_read(APIC_ID));
unsigned long l;
- extern struct desc_struct idt_descriptor;
+ extern struct gt_desc_struct idt_descriptor;
extern int pentium_f00f_bug;

if (pentium_f00f_bug) {