patch-2.4.0-test2 linux/arch/ia64/kernel/traps.c

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

diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/kernel/traps.c linux/arch/ia64/kernel/traps.c
@@ -3,8 +3,12 @@
  *
  * Copyright (C) 1998-2000 Hewlett-Packard Co
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
  */
 
+#define FPSWA_DEBUG	1
+
 /*
  * The fpu_fault() handler needs to be able to access and update all
  * floating point registers.  Those saved in pt_regs can be accessed
@@ -168,7 +172,7 @@
 	siginfo.si_signo = sig;
 	siginfo.si_errno = 0;
 	siginfo.si_code = code;
-	send_sig_info(sig, &siginfo, current);
+	force_sig_info(sig, &siginfo, current);
 }
 
 /*
@@ -300,6 +304,7 @@
 	if (copy_from_user(bundle, (void *) fault_ip, sizeof(bundle)))
 		return -1;
 
+#ifdef FPSWA_DEBUG
 	if (fpu_swa_count > 5 && jiffies - last_time > 5*HZ)
 		fpu_swa_count = 0;
 	if (++fpu_swa_count < 5) {
@@ -307,7 +312,7 @@
 		printk("%s(%d): floating-point assist fault at ip %016lx\n",
 		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri);
 	}
-
+#endif
 	exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
  			       &regs->cr_ifs, regs);
 	if (fp_fault) {
@@ -331,7 +336,8 @@
 			} else if (isr & 0x44) {
 				siginfo.si_code = FPE_FLTDIV;
 			}
-			send_sig_info(SIGFPE, &siginfo, current);
+			siginfo.si_isr = isr;
+			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	} else {
 		if (exception == -1) {
@@ -350,12 +356,49 @@
 			} else if (isr & 0x2200) {
 				siginfo.si_code = FPE_FLTRES;
 			}
-			send_sig_info(SIGFPE, &siginfo, current);
+			siginfo.si_isr = isr;
+			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	}
 	return 0;
 }
 
+struct illegal_op_return {
+	unsigned long fkt, arg1, arg2, arg3;
+};
+
+struct illegal_op_return
+ia64_illegal_op_fault (unsigned long ec, unsigned long arg1, unsigned long arg2,
+		       unsigned long arg3, unsigned long arg4, unsigned long arg5,
+		       unsigned long arg6, unsigned long arg7, unsigned long stack)
+{
+	struct pt_regs *regs = (struct pt_regs *) &stack;
+	struct illegal_op_return rv;
+	struct siginfo si;
+	char buf[128];
+
+#ifdef CONFIG_IA64_BRL_EMU	
+	{
+		extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
+
+		rv = ia64_emulate_brl(regs, ec);
+		if (rv.fkt != (unsigned long) -1)
+			return rv;
+	}
+#endif
+
+	sprintf(buf, "IA-64 Illegal operation fault");
+	die_if_kernel(buf, regs, 0);
+
+	memset(&si, 0, sizeof(si));
+	si.si_signo = SIGILL;
+	si.si_code = ILL_ILLOPC;
+	si.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+	force_sig_info(SIGILL, &si, current);
+	rv.fkt = 0;
+	return rv;
+}
+
 void
 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 	    unsigned long iim, unsigned long itir, unsigned long arg5,
@@ -449,11 +492,6 @@
 		siginfo.si_errno = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 		return;
-
-	      case 30: /* Unaligned fault */
-		sprintf(buf, "Kernel unaligned trap accessing %016lx (ip=%016lx)!",
-			ifa, regs->cr_iip + ia64_psr(regs)->ri);
-		break;
 
 	      case 32: /* fp fault */
 	      case 33: /* fp trap */

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