From 72f8c1311e27806ce9eb0083b1c7fc2f556fd3a2 Mon Sep 17 00:00:00 2001 From: bde Date: Fri, 18 Jun 1999 14:32:21 +0000 Subject: Changed the global `idt' from an array to a pointer so that npx.c automatically hacks on the active copy of the IDT if f00f_hack() has changed it. This also allows simplifications in setidt(). This fixes breakage of FP exception handling by rev.1.55 of sys/kernel.h. FP exceptions were sent to npx.c's probe handlers because npx.c "restored" the old handlers to the wrong copy of the IDT. The SYSINIT for f00f_hack() was purposely run quite late to avoid problems like this, but it is bogusly associated with the SYSINIT for proc0 so it was moved with the latter. Problem reported and fix tested by: Martin Cracauer --- sys/amd64/amd64/locore.S | 4 ++-- sys/amd64/amd64/locore.s | 4 ++-- sys/amd64/amd64/machdep.c | 22 ++++++++++------------ sys/amd64/amd64/trap.c | 5 ++--- sys/amd64/include/segments.h | 4 ++-- 5 files changed, 18 insertions(+), 21 deletions(-) (limited to 'sys/amd64') diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index 4e29fd4..fbede9b 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.122 1999/05/09 19:01:49 peter Exp $ + * $Id: locore.s,v 1.123 1999/06/01 18:19:39 jlemon Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -958,7 +958,7 @@ bdb_prepare_paging: movl %eax,R(bdb_bpt_ljmp+1) movl 24+2(%esi),%eax movw %ax,R(bdb_bpt_ljmp+5) - movl $R(_idt),%edi + movl R(_idt),%edi movl %edi,2(%esp) /* prepare to load kernel idt */ movl $8*4/4,%ecx cld diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index 4e29fd4..fbede9b 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.122 1999/05/09 19:01:49 peter Exp $ + * $Id: locore.s,v 1.123 1999/06/01 18:19:39 jlemon Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -958,7 +958,7 @@ bdb_prepare_paging: movl %eax,R(bdb_bpt_ljmp+1) movl 24+2(%esi),%eax movw %ax,R(bdb_bpt_ljmp+5) - movl $R(_idt),%edi + movl R(_idt),%edi movl %edi,2(%esp) /* prepare to load kernel idt */ movl $8*4/4,%ecx cld diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index ae9df8b..7cc1e5f 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.340 1999/06/10 02:48:51 jlemon Exp $ + * $Id: machdep.c,v 1.341 1999/06/13 19:20:25 alc Exp $ */ #include "apm.h" @@ -887,7 +887,8 @@ union descriptor gdt[NGDT * NCPU]; /* global descriptor table */ #else union descriptor gdt[NGDT]; /* global descriptor table */ #endif -struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ +static struct gate_descriptor idt0[NIDT]; +struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ union descriptor ldt[NLDT]; /* local descriptor table */ #ifdef SMP /* table descriptors - used to load tables by microp */ @@ -900,7 +901,6 @@ extern struct segment_descriptor common_tssd, *tss_gdt; int private_tss; /* flag indicating private tss */ #if defined(I586_CPU) && !defined(NO_F00F_HACK) -struct gate_descriptor *t_idt; extern int has_f00f_bug; #endif @@ -1090,11 +1090,7 @@ setidt(idx, func, typ, dpl, selec) { struct gate_descriptor *ip; -#if defined(I586_CPU) && !defined(NO_F00F_HACK) - ip = (t_idt != NULL ? t_idt : idt) + idx; -#else ip = idt + idx; -#endif ip->gd_looffset = (int)func; ip->gd_selector = selec; ip->gd_stkcpy = 0; @@ -1610,7 +1606,7 @@ init386(first) setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); - r_idt.rd_limit = sizeof(idt) - 1; + r_idt.rd_limit = sizeof(idt0) - 1; r_idt.rd_base = (int) idt; lidt(&r_idt); @@ -1714,6 +1710,7 @@ SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL); static void f00f_hack(void *unused) { + struct gate_descriptor *new_idt; #ifndef SMP struct region_descriptor r_idt; #endif @@ -1724,7 +1721,7 @@ f00f_hack(void *unused) { printf("Intel Pentium detected, installing workaround for F00F bug\n"); - r_idt.rd_limit = sizeof(idt) - 1; + r_idt.rd_limit = sizeof(idt0) - 1; tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2); if (tmp == 0) @@ -1732,10 +1729,11 @@ f00f_hack(void *unused) { if (((unsigned int)tmp & (PAGE_SIZE-1)) != 0) panic("kmem_alloc returned non-page-aligned memory"); /* Put the first seven entries in the lower page */ - t_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8)); - bcopy(idt, t_idt, sizeof(idt)); - r_idt.rd_base = (int)t_idt; + new_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8)); + bcopy(idt, new_idt, sizeof(idt0)); + r_idt.rd_base = (int)new_idt; lidt(&r_idt); + idt = new_idt; if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE, VM_PROT_READ, FALSE) != KERN_SUCCESS) panic("vm_map_protect failed"); diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index df6e295..1d9d216 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.137 1999/05/06 18:12:17 peter Exp $ + * $Id: trap.c,v 1.138 1999/06/01 18:19:47 jlemon Exp $ */ /* @@ -147,7 +147,6 @@ static __inline void userret __P((struct proc *p, struct trapframe *frame, u_quad_t oticks)); #if defined(I586_CPU) && !defined(NO_F00F_HACK) -extern struct gate_descriptor *t_idt; extern int has_f00f_bug; #endif @@ -727,7 +726,7 @@ trap_pfault(frame, usermode, eva) * fault. */ #if defined(I586_CPU) && !defined(NO_F00F_HACK) - if ((eva == (unsigned int)&t_idt[6]) && has_f00f_bug) { + if ((eva == (unsigned int)&idt[6]) && has_f00f_bug) { frame->tf_trapno = T_PRIVINFLT; return -2; } diff --git a/sys/amd64/include/segments.h b/sys/amd64/include/segments.h index eaecfa3..7028185 100644 --- a/sys/amd64/include/segments.h +++ b/sys/amd64/include/segments.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 - * $Id: segments.h,v 1.18 1999/01/28 11:45:49 newton Exp $ + * $Id: segments.h,v 1.19 1999/04/28 01:04:06 luoqi Exp $ */ #ifndef _MACHINE_SEGMENTS_H_ @@ -246,7 +246,7 @@ extern int currentldt; extern int _default_ldt; extern union descriptor gdt[]; extern struct soft_segment_descriptor gdt_segs[]; -extern struct gate_descriptor idt[NIDT]; +extern struct gate_descriptor *idt; extern union descriptor ldt[NLDT]; void lgdt __P((struct region_descriptor *rdp)); -- cgit v1.1