|
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; }
|