From: Andy P. <at...@us...> - 2001-09-06 23:39:45
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv4874 Modified Files: interrupt.c interrupt.h signal.c Log Message: Add new fault handlers - change debugging level in signal.c Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- interrupt.c 2001/09/02 20:48:39 1.16 +++ interrupt.c 2001/09/06 23:39:42 1.17 @@ -51,8 +51,8 @@ { pte_t p, *q; unsigned char *t, *s; - t = &interrupt_stack[0]; - s = SPT_BASE; + t = (unsigned char *)&interrupt_stack[0]; + s = (unsigned char *)SPT_BASE; /* Do we need more than a page for the int stack? */ if (INT_STACK_SIZE <= PAGE_SIZE) { printk("Interrupt stack too small, must be > PAGE_SIZE\n"); @@ -61,7 +61,7 @@ /* FIXME: kenn - does this want to be a 4k page or a hardware page ? */ /* see include/asm/mm/pgtable.h */ /* q = (((unsigned long) &interrupt_stack[smp_processor_id()])-PAGE_OFFSET)>>PAGELET_SHIFT;*/ - q = GET_HWSPTE_VIRT(&interrupt_stack[smp_processor_id()]); + q = (pte_t *)GET_HWSPTE_VIRT(&interrupt_stack[smp_processor_id()]); /* Set first page of interrupt stack area to kernel read, thus @@ -69,7 +69,7 @@ to expand the interrupt stack before they can do any damage. */ /* if this is a 4k page - need to use set_pte here */ - p = __mk_pte(&interrupt_stack[smp_processor_id()],__pgprot(_PAGE_KR|_PAGE_VALID)); + p = __mk_pte((unsigned long int)&interrupt_stack[smp_processor_id()],__pgprot(_PAGE_KR|_PAGE_VALID)); /* debug hwpte calculations FIXME: remove */ /* asm("movl %0, r2\n" @@ -103,7 +103,7 @@ /* register the machine check handler. */ void register_mcheck_handler(void) { - extern void machine_check_handler(void); + extern void machine_check_handler(struct pt_regs *regs, void *unused); struct irqvector *vector; unsigned char *inside_vec; @@ -174,7 +174,18 @@ printk("Panic: unable to register corrected read handler\n"); machine_halt(); } - + + /* other faults */ + if (register_excep_handler(SCB_RESAM,"reserved addressing mode (resam_handler)", resam_handler, 0, 0)) { + printk("Panic: unable to register reserved addressing mode handler\n"); + machine_halt(); + } + if (register_excep_handler(SCB_ARITH,"arithmetic fault (arith_handler)", arith_handler, 1, 0)) { + printk("Panic: unable to register arithmetic fault handler\n"); + machine_halt(); + } + + } void init_IRQ(void) @@ -230,12 +241,66 @@ machine_halt(); } + +/* This is the handler for reserved addressing mode exceptions. + Eventually this will have to check if the fault was from user + mode or kernel mode and either throw a SIGILL or panic. */ + +void resam_handler(struct pt_regs *regs, void *unused) +{ + unsigned short instr = *(unsigned short *)(regs->pc); + + if ((instr == 0xfeff) || (instr == 0xfdff)) { + printk("\nKernel bugcheck at PC=%08lx\n", regs->pc); + } else { + printk("\nReserved addressing mode fault at PC=%08lx\n", regs->pc); + } + + printk("\nStack dump\n"); + hex_dump((void *)(regs->sp), 256); + show_regs(regs); + show_cpu_regs(); + + if (user_mode(regs)) { + force_sig(SIGILL,current); + return; + } + machine_halt(); +} + /* This is the handler for corrected memory read errors */ void corrected_read_handler(struct pt_regs *regs, void *unused) { printk("Corrected memory read error. " "RAM failing or cache incorrectly initialized?\n"); +} + +/* This is the handler for arithmetic faults */ +char *arith_faults[] = { + "none", + "Integer Overflow", + "Integer Division by Zero", + "Floating Overflow Trap", + "Floating or Decimal Division by Zero Trap", + "Floating Underflow Trap", + "Decimal Overflow", + "Subscript Range", + "Floating Overflow Fault", + "Floating or Decimal Division by Zero Fault", + "Floating Underflow Fault" +}; + +void arith_handler(struct pt_regs *regs, void *excep_info) +{ + int code = *(unsigned int *)(excep_info); + printk("Arithmetic Fault at PC=%8lx, %s, (code=%lx)\n",regs->pc,arith_faults[code],code); + /* FIXME: need to code up the info for user handler */ + if (user_mode(regs)) { + force_sig(SIGFPE,current); + return; + } + } Index: interrupt.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- interrupt.h 2001/06/26 18:59:00 1.5 +++ interrupt.h 2001/09/06 23:39:42 1.6 @@ -65,3 +65,5 @@ extern void reserved_instr_handler(struct pt_regs *regs, void *excep_info); extern void corrected_read_handler(struct pt_regs *regs, void *excep_info); extern void syscall_handler(struct pt_regs *regs, void *excep_info); +extern void resam_handler(struct pt_regs *regs, void *unused); +extern void arith_handler(struct pt_regs *regs, void *excep_info); Index: signal.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- signal.c 2001/09/02 20:48:39 1.6 +++ signal.c 2001/09/06 23:39:42 1.7 @@ -32,7 +32,7 @@ #include <asm/ucontext.h> #include <asm/uaccess.h> -#define DEBUG_SIG 0 +#undef DEBUG_SIG /* FIXME: Check this & fixup other regs, like r0 */ #define RESTART_VAX_SYSCALL(regs) { (regs)->pc -= 4; } |