patch-2.1.16 linux/arch/ppc/kernel/traps.c

Next file: linux/arch/ppc/kernel/usercpy.c
Previous file: linux/arch/ppc/kernel/time.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.15/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 1995  Gary Thomas
  *  Adapted for PowerPC by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
  */
 
 /*
@@ -17,7 +18,6 @@
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
 #include <linux/malloc.h>
-#include <linux/ldt.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 
@@ -40,44 +40,62 @@
 void
 _exception(int signr, struct pt_regs *regs)
 {
-/*	dump_regs(regs);*/
-	force_sig(signr, current);
-	if (!user_mode(regs))
-	{
-		printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
-		while (1) ;
-	}
+  /*	dump_regs(regs);*/
+  force_sig(signr, current);
+  if (!user_mode(regs))
+    {
+      printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
+      while (1) ;
+    }
 }
 
 MachineCheckException(struct pt_regs *regs)
 {
-/*	printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
-	_exception(SIGSEGV, regs);	
+  printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+  _exception(SIGSEGV, regs);	
 }
 
 ProgramCheckException(struct pt_regs *regs)
 {
-/*	printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
-	if (current->flags & PF_PTRACED)
-	{
-		_exception(SIGTRAP, regs);
-	} else
-	{
-		_exception(SIGILL, regs);
-	}
+#if 0
+  printk("Program check at PC: %x[%x], SR: %x\n",
+	 regs->nip, va_to_phys(regs->nip), regs->msr);
+  #endif
+  if (current->flags & PF_PTRACED)
+  {
+    _exception(SIGTRAP, regs);
+  } else
+  {
+    _exception(SIGILL, regs);
+  }
 }
 
 SingleStepException(struct pt_regs *regs)
 {
-/*	printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 	_exception(SIGTRAP, regs);	
 }
 
 FloatingPointCheckException(struct pt_regs *regs)
 {
-/*	printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
-	_exception(SIGFPE, regs);	
+  /* if fpu already on -- then exception was generated by an error */
+  if ( (unsigned long)(regs->msr) & (unsigned long)MSR_FP )
+  {
+    _exception(SIGFPE, regs);
+    return 0;
+  }
+
+#if 0
+  printk("fpu off -- turning on: %s pc %x fpscr %x msr %x ksp %x r1 %x\n",
+	 current->comm,regs->nip,regs->fpcsr,regs->msr,regs,regs->gpr[1]);
+#endif
+
+  /* if the fpu is off then turn it on and return */
+  regs->msr |= MSR_FP;
+  current->tss.fp_used++;
+  /* tells return_from_int to restore fp regs since fp was turned on
+     see head.S -- Cort */  
+  return MSR_FP;		
 }
 
 AlignmentException(struct pt_regs *regs)
@@ -88,11 +106,20 @@
 	_exception(SIGBUS, regs);	
 }
 
-bad_stack(struct pt_regs *regs)
+
+/* see CHECK_STACK macro in head.S for argument definitions */
+bad_stack(unsigned int r3, unsigned int r4, unsigned int r5, unsigned int r6)
 {
-/*	printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
-	dump_regs(regs);*/
-	while (1) ;
+  /* r6 (was r1) kernel stack pointer */
+  /* r5 (was r2) kernel stack page */
+  /* r4 kernel stack magic */
+  /* r3 stack magic or ksp masked to page boundary */
+  printk("bad_stack(): Kernel stack bad.\n");
+  printk("ksp %x kpage %x stack magic %x r3 %x\n",
+	 r6,r5,r4,r3);
+  printk("current: %s/%d\n",
+	 current->comm,current->pid);
+  while(1);
 }
 
 dump_regs(struct pt_regs *regs)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov