diff options
-rw-r--r-- | sys/amd64/amd64/exception.S | 4 | ||||
-rw-r--r-- | sys/amd64/amd64/exception.s | 4 | ||||
-rw-r--r-- | sys/amd64/amd64/fpu.c | 6 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 73 | ||||
-rw-r--r-- | sys/amd64/amd64/trap.c | 34 | ||||
-rw-r--r-- | sys/amd64/include/cpufunc.h | 4 | ||||
-rw-r--r-- | sys/amd64/isa/isa.c | 7 | ||||
-rw-r--r-- | sys/amd64/isa/npx.c | 6 | ||||
-rw-r--r-- | sys/i386/i386/exception.s | 4 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 73 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 34 | ||||
-rw-r--r-- | sys/i386/include/cpufunc.h | 4 | ||||
-rw-r--r-- | sys/i386/isa/isa.c | 7 | ||||
-rw-r--r-- | sys/i386/isa/npx.c | 6 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 34 |
15 files changed, 205 insertions, 95 deletions
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index bba2272..e7b44be 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.11 1995/09/07 21:36:17 davidg Exp $ + * $Id: exception.s,v 1.12 1995/12/14 14:35:33 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -105,8 +105,6 @@ IDTVEC(ill) pushl $0; TRAP(T_PRIVINFLT) IDTVEC(dna) pushl $0; TRAP(T_DNA) -IDTVEC(dble) - TRAP(T_DOUBLEFLT) IDTVEC(fpusegm) pushl $0; TRAP(T_FPOPFLT) IDTVEC(tss) diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s index bba2272..e7b44be 100644 --- a/sys/amd64/amd64/exception.s +++ b/sys/amd64/amd64/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.11 1995/09/07 21:36:17 davidg Exp $ + * $Id: exception.s,v 1.12 1995/12/14 14:35:33 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -105,8 +105,6 @@ IDTVEC(ill) pushl $0; TRAP(T_PRIVINFLT) IDTVEC(dna) pushl $0; TRAP(T_DNA) -IDTVEC(dble) - TRAP(T_DOUBLEFLT) IDTVEC(fpusegm) pushl $0; TRAP(T_FPOPFLT) IDTVEC(tss) diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 54cb5bf..8f274db 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 - * $Id: npx.c,v 1.25 1995/10/28 13:07:21 phk Exp $ + * $Id: npx.c,v 1.26 1995/12/10 13:39:02 phk Exp $ */ #include "npx.h" @@ -212,8 +212,8 @@ npxprobe(dvp) save_idt_npxtrap = idt[16]; outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq)); outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8)); - setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL); - setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL); + setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); npx_idt_probeintr = idt[npx_intrno]; enable_intr(); result = npxprobe1(dvp); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index f95285d..947200e 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.159 1995/12/14 14:35:34 peter Exp $ + * $Id: machdep.c,v 1.160 1995/12/16 18:52:08 peter Exp $ */ #include "npx.h" @@ -115,6 +115,7 @@ extern void init386 __P((int first)); extern int ptrace_set_pc __P((struct proc *p, unsigned int addr)); extern int ptrace_single_step __P((struct proc *p)); extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data)); +extern void dblfault_handler __P((void)); static void cpu_startup __P((void *)); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) @@ -1066,7 +1067,8 @@ union descriptor gdt[NGDT]; /* global descriptor table */ struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ union descriptor ldt[NLDT]; /* local descriptor table */ -static struct i386tss tss, panic_tss; +static struct i386tss dblfault_tss; +static char dblfault_stack[512]; extern struct user *proc0paddr; @@ -1118,8 +1120,8 @@ struct soft_segment_descriptor gdt_segs[] = { 0, /* default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, /* GPANIC_SEL 5 Panic Tss Descriptor */ -{ (int) &panic_tss, /* segment base address */ - sizeof(tss)-1, /* length - all address space */ +{ (int) &dblfault_tss, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ 1, /* segment descriptor present */ @@ -1128,7 +1130,7 @@ struct soft_segment_descriptor gdt_segs[] = { 0 /* limit granularity (byte/page units)*/ }, /* GPROC0_SEL 6 Proc 0 Tss Descriptor */ { (int) kstack, /* segment base address */ - sizeof(tss)-1, /* length - all address space */ + sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ 1, /* segment descriptor present */ @@ -1222,16 +1224,17 @@ static struct soft_segment_descriptor ldt_segs[] = { }; void -setidt(idx, func, typ, dpl) +setidt(idx, func, typ, dpl, selec) int idx; inthand_t *func; int typ; int dpl; + int selec; { struct gate_descriptor *ip = idt + idx; ip->gd_looffset = (int)func; - ip->gd_selector = 8; + ip->gd_selector = selec; ip->gd_stkcpy = 0; ip->gd_xx = 0; ip->gd_type = typ; @@ -1244,7 +1247,7 @@ setidt(idx, func, typ, dpl) extern inthand_t IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), - IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm), + IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall); @@ -1329,27 +1332,27 @@ init386(first) /* exceptions */ for (x = 0; x < NIDT; x++) - setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); - setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL); - setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL); - setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL); - setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL); - setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL); - setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL); - setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL); - setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL); - setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL); - setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL); - setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL); - setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL); - setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL); - setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL); - setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL); - setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); - setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL); - setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL); + setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(8, 0, SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL)); + setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #if defined(COMPAT_LINUX) || defined(LINUX) - setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL); + setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); #endif #include "isa.h" @@ -1569,8 +1572,20 @@ init386(first) proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = + dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; + dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = + dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_cr3 = IdlePTD; + dblfault_tss.tss_eip = (int) dblfault_handler; + dblfault_tss.tss_eflags = PSL_KERNEL; + dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = dblfault_tss.tss_gs = + GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); + dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt = - (sizeof(tss))<<16; + (sizeof(struct i386tss))<<16; ltr(gsel_tss); diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 21f1f8e..acee977 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.65 1995/12/14 08:21:29 phk Exp $ + * $Id: trap.c,v 1.66 1995/12/14 14:35:36 peter Exp $ */ /* @@ -89,8 +89,9 @@ extern int trapwrite __P((unsigned addr)); extern void syscall __P((struct trapframe frame)); extern void linux_syscall __P((struct trapframe frame)); -static int trap_pfault __P((struct trapframe *, int)); -static void trap_fatal __P((struct trapframe *)); +static int trap_pfault __P((struct trapframe *, int)); +static void trap_fatal __P((struct trapframe *)); +void dblfault_handler __P((void)); extern inthand_t IDTVEC(syscall); @@ -756,6 +757,33 @@ trap_fatal(frame) } /* + * Double fault handler. Called when a fault occurs while writing + * a frame for a trap/exception onto the stack. This usually occurs + * when the stack overflows (such is the case with infinite recursion, + * for example). + * + * XXX Note that the current PTD gets replaced by IdlePTD when the + * task switch occurs. This means that the stack that was active at + * the time of the double fault is not available at <kstack> unless + * the machine was idlewhen the double fault occurred. This downside + * of this is that "trace <ebp>" in ddb won't work. + */ +void +dblfault_handler() +{ + struct pcb *pcb = curpcb; + + if (pcb != NULL) { + printf("\nFatal double fault:\n"); + printf("eip = 0x%x\n", pcb->pcb_tss.tss_eip); + printf("esp = 0x%x\n", pcb->pcb_tss.tss_esp); + printf("ebp = 0x%x\n", pcb->pcb_tss.tss_ebp); + } + + panic("double fault"); +} + +/* * Compensate for 386 brain damage (missing URKR). * This is a little simpler than the pagefault handler in trap() because * it the page tables have already been faulted in and high addresses diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 11774bf..e82b4f0 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.41 1995/10/05 10:32:47 phk Exp $ + * $Id: cpufunc.h,v 1.42 1995/12/03 13:45:27 bde Exp $ */ /* @@ -412,6 +412,6 @@ u_long kvtop __P((void *addr)); typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); void setidt __P((int idx, alias_for_inthand_t *func, int typ, - int dpl)); + int dpl, int selec)); #endif /* !_MACHINE_CPUFUNC_H_ */ diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c index e04a500..54a11e1 100644 --- a/sys/amd64/isa/isa.c +++ b/sys/amd64/isa/isa.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: isa.c,v 1.57 1995/11/20 13:24:18 bde Exp $ + * $Id: isa.c,v 1.58 1995/12/07 12:46:01 davidg Exp $ */ /* @@ -936,7 +936,7 @@ register_intr(intr, device_id, flags, handler, maskptr, unit) intr_unit[intr] = unit; setidt(ICU_OFFSET + intr, flags & RI_FAST ? fastintr[intr] : slowintr[intr], - SDT_SYS386IGT, SEL_KPL); + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); write_eflags(ef); for (cp = intrnames, id = 0; id <= device_id; id++) while (*cp++ != '\0') @@ -983,7 +983,8 @@ unregister_intr(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; - setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL); + setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); write_eflags(ef); return (0); } diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c index 54cb5bf..8f274db 100644 --- a/sys/amd64/isa/npx.c +++ b/sys/amd64/isa/npx.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 - * $Id: npx.c,v 1.25 1995/10/28 13:07:21 phk Exp $ + * $Id: npx.c,v 1.26 1995/12/10 13:39:02 phk Exp $ */ #include "npx.h" @@ -212,8 +212,8 @@ npxprobe(dvp) save_idt_npxtrap = idt[16]; outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq)); outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8)); - setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL); - setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL); + setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); npx_idt_probeintr = idt[npx_intrno]; enable_intr(); result = npxprobe1(dvp); diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index bba2272..e7b44be 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.11 1995/09/07 21:36:17 davidg Exp $ + * $Id: exception.s,v 1.12 1995/12/14 14:35:33 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -105,8 +105,6 @@ IDTVEC(ill) pushl $0; TRAP(T_PRIVINFLT) IDTVEC(dna) pushl $0; TRAP(T_DNA) -IDTVEC(dble) - TRAP(T_DOUBLEFLT) IDTVEC(fpusegm) pushl $0; TRAP(T_FPOPFLT) IDTVEC(tss) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index f95285d..947200e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.159 1995/12/14 14:35:34 peter Exp $ + * $Id: machdep.c,v 1.160 1995/12/16 18:52:08 peter Exp $ */ #include "npx.h" @@ -115,6 +115,7 @@ extern void init386 __P((int first)); extern int ptrace_set_pc __P((struct proc *p, unsigned int addr)); extern int ptrace_single_step __P((struct proc *p)); extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data)); +extern void dblfault_handler __P((void)); static void cpu_startup __P((void *)); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) @@ -1066,7 +1067,8 @@ union descriptor gdt[NGDT]; /* global descriptor table */ struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ union descriptor ldt[NLDT]; /* local descriptor table */ -static struct i386tss tss, panic_tss; +static struct i386tss dblfault_tss; +static char dblfault_stack[512]; extern struct user *proc0paddr; @@ -1118,8 +1120,8 @@ struct soft_segment_descriptor gdt_segs[] = { 0, /* default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, /* GPANIC_SEL 5 Panic Tss Descriptor */ -{ (int) &panic_tss, /* segment base address */ - sizeof(tss)-1, /* length - all address space */ +{ (int) &dblfault_tss, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ 1, /* segment descriptor present */ @@ -1128,7 +1130,7 @@ struct soft_segment_descriptor gdt_segs[] = { 0 /* limit granularity (byte/page units)*/ }, /* GPROC0_SEL 6 Proc 0 Tss Descriptor */ { (int) kstack, /* segment base address */ - sizeof(tss)-1, /* length - all address space */ + sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ 1, /* segment descriptor present */ @@ -1222,16 +1224,17 @@ static struct soft_segment_descriptor ldt_segs[] = { }; void -setidt(idx, func, typ, dpl) +setidt(idx, func, typ, dpl, selec) int idx; inthand_t *func; int typ; int dpl; + int selec; { struct gate_descriptor *ip = idt + idx; ip->gd_looffset = (int)func; - ip->gd_selector = 8; + ip->gd_selector = selec; ip->gd_stkcpy = 0; ip->gd_xx = 0; ip->gd_type = typ; @@ -1244,7 +1247,7 @@ setidt(idx, func, typ, dpl) extern inthand_t IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), - IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm), + IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall); @@ -1329,27 +1332,27 @@ init386(first) /* exceptions */ for (x = 0; x < NIDT; x++) - setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); - setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL); - setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL); - setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL); - setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL); - setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL); - setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL); - setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL); - setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL); - setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL); - setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL); - setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL); - setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL); - setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL); - setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL); - setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL); - setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); - setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL); - setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL); + setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(8, 0, SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL)); + setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #if defined(COMPAT_LINUX) || defined(LINUX) - setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL); + setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); #endif #include "isa.h" @@ -1569,8 +1572,20 @@ init386(first) proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = + dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; + dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = + dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_cr3 = IdlePTD; + dblfault_tss.tss_eip = (int) dblfault_handler; + dblfault_tss.tss_eflags = PSL_KERNEL; + dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = dblfault_tss.tss_gs = + GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); + dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt = - (sizeof(tss))<<16; + (sizeof(struct i386tss))<<16; ltr(gsel_tss); diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 21f1f8e..acee977 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.65 1995/12/14 08:21:29 phk Exp $ + * $Id: trap.c,v 1.66 1995/12/14 14:35:36 peter Exp $ */ /* @@ -89,8 +89,9 @@ extern int trapwrite __P((unsigned addr)); extern void syscall __P((struct trapframe frame)); extern void linux_syscall __P((struct trapframe frame)); -static int trap_pfault __P((struct trapframe *, int)); -static void trap_fatal __P((struct trapframe *)); +static int trap_pfault __P((struct trapframe *, int)); +static void trap_fatal __P((struct trapframe *)); +void dblfault_handler __P((void)); extern inthand_t IDTVEC(syscall); @@ -756,6 +757,33 @@ trap_fatal(frame) } /* + * Double fault handler. Called when a fault occurs while writing + * a frame for a trap/exception onto the stack. This usually occurs + * when the stack overflows (such is the case with infinite recursion, + * for example). + * + * XXX Note that the current PTD gets replaced by IdlePTD when the + * task switch occurs. This means that the stack that was active at + * the time of the double fault is not available at <kstack> unless + * the machine was idlewhen the double fault occurred. This downside + * of this is that "trace <ebp>" in ddb won't work. + */ +void +dblfault_handler() +{ + struct pcb *pcb = curpcb; + + if (pcb != NULL) { + printf("\nFatal double fault:\n"); + printf("eip = 0x%x\n", pcb->pcb_tss.tss_eip); + printf("esp = 0x%x\n", pcb->pcb_tss.tss_esp); + printf("ebp = 0x%x\n", pcb->pcb_tss.tss_ebp); + } + + panic("double fault"); +} + +/* * Compensate for 386 brain damage (missing URKR). * This is a little simpler than the pagefault handler in trap() because * it the page tables have already been faulted in and high addresses diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index 11774bf..e82b4f0 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.41 1995/10/05 10:32:47 phk Exp $ + * $Id: cpufunc.h,v 1.42 1995/12/03 13:45:27 bde Exp $ */ /* @@ -412,6 +412,6 @@ u_long kvtop __P((void *addr)); typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); void setidt __P((int idx, alias_for_inthand_t *func, int typ, - int dpl)); + int dpl, int selec)); #endif /* !_MACHINE_CPUFUNC_H_ */ diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c index e04a500..54a11e1 100644 --- a/sys/i386/isa/isa.c +++ b/sys/i386/isa/isa.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: isa.c,v 1.57 1995/11/20 13:24:18 bde Exp $ + * $Id: isa.c,v 1.58 1995/12/07 12:46:01 davidg Exp $ */ /* @@ -936,7 +936,7 @@ register_intr(intr, device_id, flags, handler, maskptr, unit) intr_unit[intr] = unit; setidt(ICU_OFFSET + intr, flags & RI_FAST ? fastintr[intr] : slowintr[intr], - SDT_SYS386IGT, SEL_KPL); + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); write_eflags(ef); for (cp = intrnames, id = 0; id <= device_id; id++) while (*cp++ != '\0') @@ -983,7 +983,8 @@ unregister_intr(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; - setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL); + setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); write_eflags(ef); return (0); } diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index 54cb5bf..8f274db 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 - * $Id: npx.c,v 1.25 1995/10/28 13:07:21 phk Exp $ + * $Id: npx.c,v 1.26 1995/12/10 13:39:02 phk Exp $ */ #include "npx.h" @@ -212,8 +212,8 @@ npxprobe(dvp) save_idt_npxtrap = idt[16]; outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq)); outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8)); - setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL); - setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL); + setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); npx_idt_probeintr = idt[npx_intrno]; enable_intr(); result = npxprobe1(dvp); diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 21f1f8e..acee977 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.65 1995/12/14 08:21:29 phk Exp $ + * $Id: trap.c,v 1.66 1995/12/14 14:35:36 peter Exp $ */ /* @@ -89,8 +89,9 @@ extern int trapwrite __P((unsigned addr)); extern void syscall __P((struct trapframe frame)); extern void linux_syscall __P((struct trapframe frame)); -static int trap_pfault __P((struct trapframe *, int)); -static void trap_fatal __P((struct trapframe *)); +static int trap_pfault __P((struct trapframe *, int)); +static void trap_fatal __P((struct trapframe *)); +void dblfault_handler __P((void)); extern inthand_t IDTVEC(syscall); @@ -756,6 +757,33 @@ trap_fatal(frame) } /* + * Double fault handler. Called when a fault occurs while writing + * a frame for a trap/exception onto the stack. This usually occurs + * when the stack overflows (such is the case with infinite recursion, + * for example). + * + * XXX Note that the current PTD gets replaced by IdlePTD when the + * task switch occurs. This means that the stack that was active at + * the time of the double fault is not available at <kstack> unless + * the machine was idlewhen the double fault occurred. This downside + * of this is that "trace <ebp>" in ddb won't work. + */ +void +dblfault_handler() +{ + struct pcb *pcb = curpcb; + + if (pcb != NULL) { + printf("\nFatal double fault:\n"); + printf("eip = 0x%x\n", pcb->pcb_tss.tss_eip); + printf("esp = 0x%x\n", pcb->pcb_tss.tss_esp); + printf("ebp = 0x%x\n", pcb->pcb_tss.tss_ebp); + } + + panic("double fault"); +} + +/* * Compensate for 386 brain damage (missing URKR). * This is a little simpler than the pagefault handler in trap() because * it the page tables have already been faulted in and high addresses |