summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Greenman <dg@FreeBSD.org>1996-01-13 10:46:51 +0000
committerDavid Greenman <dg@FreeBSD.org>1996-01-13 10:46:51 +0000
commit889e6518dc2c329f49ce8ca8620423f454ee9b0b (patch)
tree7e1d5c219d1f7325e5b2677fda28555283823816
parent0ba45696f3eff1292ac60399069374656b830dda (diff)
Notes
-rw-r--r--sys/i386/i386/exception.s4
-rw-r--r--sys/i386/i386/machdep.c76
-rw-r--r--sys/i386/i386/trap.c34
-rw-r--r--sys/i386/include/cpufunc.h4
-rw-r--r--sys/i386/isa/isa.c7
-rw-r--r--sys/i386/isa/npx.c6
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);