summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/exception.S4
-rw-r--r--sys/amd64/amd64/exception.s4
-rw-r--r--sys/amd64/amd64/fpu.c6
-rw-r--r--sys/amd64/amd64/machdep.c73
-rw-r--r--sys/amd64/amd64/trap.c34
-rw-r--r--sys/amd64/include/cpufunc.h4
-rw-r--r--sys/amd64/isa/isa.c7
-rw-r--r--sys/amd64/isa/npx.c6
-rw-r--r--sys/i386/i386/exception.s4
-rw-r--r--sys/i386/i386/machdep.c73
-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
-rw-r--r--sys/kern/subr_trap.c34
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
OpenPOWER on IntegriCloud