diff options
| author | David Greenman <dg@FreeBSD.org> | 1996-01-13 10:46:51 +0000 |
|---|---|---|
| committer | David Greenman <dg@FreeBSD.org> | 1996-01-13 10:46:51 +0000 |
| commit | 889e6518dc2c329f49ce8ca8620423f454ee9b0b (patch) | |
| tree | 7e1d5c219d1f7325e5b2677fda28555283823816 | |
| parent | 0ba45696f3eff1292ac60399069374656b830dda (diff) | |
Notes
| -rw-r--r-- | sys/i386/i386/exception.s | 4 | ||||
| -rw-r--r-- | sys/i386/i386/machdep.c | 76 | ||||
| -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 |
6 files changed, 87 insertions, 44 deletions
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index e0e7b3c68631..28f5085ace29 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.9 1995/06/11 19:31:13 rgrimes Exp $ + * $Id: exception.s,v 1.9.2.1 1995/08/23 05:22:34 davidg Exp $ */ #include "npx.h" /* NNPX */ @@ -111,8 +111,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 57d026f93715..1d62f2bb9d77 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.128.4.3 1995/09/08 04:22:49 davidg Exp $ + * $Id: machdep.c,v 1.128.4.4 1995/10/25 11:14:38 davidg Exp $ */ #include "npx.h" @@ -194,6 +194,8 @@ vm_offset_t pager_sva, pager_eva; extern int pager_map_size; extern struct linker_set netisr_set; +extern void dblfault_handler __P((void)); + #define offsetof(type, member) ((size_t)(&((type *)0)->member)) void @@ -1051,7 +1053,8 @@ union descriptor gdt[NGDT]; /* global descriptor table */ struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ union descriptor ldt[NLDT]; /* local descriptor table */ -struct i386tss tss, panic_tss; +static struct i386tss dblfault_tss; +static char dblfault_stack[PAGE_SIZE]; extern struct user *proc0paddr; @@ -1103,8 +1106,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 */ @@ -1113,7 +1116,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 */ @@ -1207,16 +1210,17 @@ 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; @@ -1229,7 +1233,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); @@ -1315,27 +1319,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); -#ifdef COMPAT_LINUX - setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL); + 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, GSEL(GCODE_SEL, SEL_KPL)); #endif #include "isa.h" @@ -1554,8 +1558,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 3883c3d16f72..c156ca42fbe7 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.53.2.2 1995/08/23 07:31:17 davidg Exp $ + * $Id: trap.c,v 1.53.2.3 1995/10/10 00:45:46 davidg Exp $ */ /* @@ -80,8 +80,9 @@ extern int trapwrite __P((unsigned addr)); extern void syscall __P((struct trapframe frame)); extern void linux_syscall __P((struct trapframe frame)); -int trap_pfault __P((struct trapframe *, int)); -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); @@ -748,6 +749,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 idle when the double fault occurred. The 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 a05ef1223e50..4880e4c8ebf1 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.37.4.2 1995/09/12 05:48:43 davidg Exp $ + * $Id: cpufunc.h,v 1.37.4.3 1995/12/20 17:06:35 nate Exp $ */ /* @@ -448,6 +448,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 eae0629c0902..3f52c84050cc 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.50 1995/05/30 08:02:35 rgrimes Exp $ + * $Id: isa.c,v 1.50.4.1 1996/01/04 08:54:12 gibbs Exp $ */ /* @@ -962,7 +962,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') @@ -1009,7 +1009,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 0a5327941724..e83a7aa301d4 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.22 1995/04/12 20:48:01 wollman Exp $ + * $Id: npx.c,v 1.23 1995/05/30 08:02:51 rgrimes Exp $ */ #include "npx.h" @@ -205,8 +205,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); |
