Implemented a (sorely needed for years) double fault handler to catch stack
overflows. It sure would be nice if there was an unmapped page between the PCB and the stack (and that the size of the stack was configurable!). With the way things are now, the PCB will get clobbered before the double fault handler gets control, making somewhat of a mess of things. Despite this, it is still fairly easy to poke around in the overflowed stack to figure out the cause.
This commit is contained in:
parent
bee3d17d06
commit
2838c9682a
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -755,6 +756,33 @@ trap_fatal(frame)
|
||||
panic("unknown/reserved trap");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -755,6 +756,33 @@ trap_fatal(frame)
|
||||
panic("unknown/reserved trap");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
@ -755,6 +756,33 @@ trap_fatal(frame)
|
||||
panic("unknown/reserved trap");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user