patch-2.4.0-test2 linux/arch/ia64/ia32/ia32_traps.c

Next file: linux/arch/ia64/ia32/sys_ia32.c
Previous file: linux/arch/ia64/ia32/ia32_support.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/ia32/ia32_traps.c linux/arch/ia64/ia32/ia32_traps.c
@@ -1,3 +1,9 @@
+/*
+ * IA32 exceptions handler
+ *
+ * 06/16/00	A. Mallick	added siginfo for most cases (close to IA32)
+ */
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
@@ -9,9 +15,11 @@
 {
 	struct siginfo siginfo;
 
+	siginfo.si_errno = 0;
 	switch ((isr >> 16) & 0xff) {
 	      case 1:
 	      case 2:
+		siginfo.si_signo = SIGTRAP;
 		if (isr == 0)
 			siginfo.si_code = TRAP_TRACE;
 		else if (isr & 0x4)
@@ -21,27 +29,96 @@
 		break;
 
 	      case 3:
+		siginfo.si_signo = SIGTRAP;
 		siginfo.si_code = TRAP_BRKPT;
 		break;
 
 	      case 0:	/* Divide fault */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = FPE_INTDIV;
+		break;
+
 	      case 4:	/* Overflow */
 	      case 5:	/* Bounds fault */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = 0;
+		break;
+
 	      case 6:	/* Invalid Op-code */
+		siginfo.si_signo = SIGILL;
+		siginfo.si_code = ILL_ILLOPN;
+		break;
+
 	      case 7:	/* FP DNA */
 	      case 8:	/* Double Fault */
 	      case 9:	/* Invalid TSS */
 	      case 11:	/* Segment not present */
 	      case 12:	/* Stack fault */
 	      case 13:	/* General Protection Fault */
+		siginfo.si_signo = SIGSEGV;
+		siginfo.si_code = 0;
+		break;
+
 	      case 16:	/* Pending FP error */
+		{
+			unsigned long fsr, fcr;
+
+			asm ("mov %0=ar.fsr;"
+			     "mov %1=ar.fcr;"
+			     : "=r"(fsr), "=r"(fcr));
+
+			siginfo.si_signo = SIGFPE;
+			/*
+			 * (~cwd & swd) will mask out exceptions that are not set to unmasked
+			 * status.  0x3f is the exception bits in these regs, 0x200 is the
+			 * C1 reg you need in case of a stack fault, 0x040 is the stack
+			 * fault bit.  We should only be taking one exception at a time,
+			 * so if this combination doesn't produce any single exception,
+			 * then we have a bad program that isn't syncronizing its FPU usage
+			 * and it will suffer the consequences since we won't be able to
+			 * fully reproduce the context of the exception
+			 */
+			switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) {
+				case 0x000:
+				default:
+					siginfo.si_code = 0;
+					break;
+				case 0x001: /* Invalid Op */
+				case 0x040: /* Stack Fault */
+				case 0x240: /* Stack Fault | Direction */
+					siginfo.si_code = FPE_FLTINV;
+					break;
+				case 0x002: /* Denormalize */
+				case 0x010: /* Underflow */
+					siginfo.si_code = FPE_FLTUND;
+					break;
+				case 0x004: /* Zero Divide */
+					siginfo.si_code = FPE_FLTDIV;
+					break;
+				case 0x008: /* Overflow */
+					siginfo.si_code = FPE_FLTOVF;
+					break;
+				case 0x020: /* Precision */
+					siginfo.si_code = FPE_FLTRES;
+					break;
+			}
+
+			break;
+		}
+
 	      case 17:	/* Alignment check */
+		siginfo.si_signo = SIGSEGV;
+		siginfo.si_code = BUS_ADRALN;
+		break;
+
 	      case 19:	/* SSE Numeric error */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = 0;
+		break;
+
 	      default:
 		return -1;
 	}
-	siginfo.si_signo = SIGTRAP;
-	siginfo.si_errno = 0;
-	send_sig_info(SIGTRAP, &siginfo, current);
+	force_sig_info(SIGTRAP, &siginfo, current);
 	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)