patch-2.4.20 linux-2.4.20/arch/ia64/kernel/traps.c
Next file: linux-2.4.20/arch/ia64/kernel/unaligned.c
Previous file: linux-2.4.20/arch/ia64/kernel/time.c
Back to the patch index
Back to the overall index
- Lines: 157
- Date:
Thu Nov 28 15:53:09 2002
- Orig file:
linux-2.4.19/arch/ia64/kernel/traps.c
- Orig date:
Fri Aug 2 17:39:42 2002
diff -urN linux-2.4.19/arch/ia64/kernel/traps.c linux-2.4.20/arch/ia64/kernel/traps.c
@@ -48,10 +48,15 @@
void __init
trap_init (void)
{
- printk("fpswa interface at %lx\n", ia64_boot_param->fpswa);
- if (ia64_boot_param->fpswa)
+ if (ia64_boot_param->fpswa) {
/* FPSWA fixup: make the interface pointer a kernel virtual address: */
fpswa_interface = __va(ia64_boot_param->fpswa);
+ printk("FPSWA interface at 0x%lx, revision %d.%d\n",
+ ia64_boot_param->fpswa,
+ fpswa_interface->revision >> 16,
+ fpswa_interface->revision & 0xffff);
+ } else
+ printk("No FPSWA interface\n");
}
/*
@@ -185,6 +190,10 @@
sig = SIGSEGV; code = __SEGV_PSTKOVF;
break;
+ case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
+ sig = SIGILL; code = __ILL_BNDMOD;
+ break;
+
default:
if (break_num < 0x40000 || break_num > 0x100000)
die_if_kernel("Bad break", regs, break_num);
@@ -213,7 +222,8 @@
{
struct pt_regs *regs = (struct pt_regs *) &stack;
- printk("<sc%ld(%lx,%lx,%lx,%lx)>\n", regs->r15, arg0, arg1, arg2, arg3);
+ printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+ regs->r15, arg0, arg1, arg2, arg3);
return -ENOSYS;
}
@@ -242,9 +252,9 @@
if (fpu_owner)
ia64_flush_fph(fpu_owner);
- ia64_set_fpu_owner(current);
}
#endif /* !CONFIG_SMP */
+ ia64_set_fpu_owner(current);
if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
__ia64_load_fpu(current->thread.fph);
psr->mfh = 0;
@@ -429,7 +439,7 @@
unsigned long code, error = isr;
struct siginfo siginfo;
char buf[128];
- int result;
+ int result, sig;
static const char *reason[] = {
"IA-64 Illegal Operation fault",
"IA-64 Privileged Operation fault",
@@ -441,30 +451,14 @@
"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
};
-#if 0
- /* this is for minimal trust debugging; yeah this kind of stuff is useful at times... */
-
- if (vector != 25) {
- static unsigned long last_time;
- static char count;
- unsigned long n = vector;
- char buf[32], *cp;
-
- if (jiffies - last_time > 5*HZ)
- count = 0;
-
- if (count++ < 5) {
- last_time = jiffies;
- cp = buf + sizeof(buf);
- *--cp = '\0';
- while (n) {
- *--cp = "0123456789abcdef"[n & 0xf];
- n >>= 4;
- }
- printk("<0x%s>", cp);
- }
+ if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
+ /*
+ * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
+ * the lfetch.
+ */
+ ia64_psr(regs)->ed = 1;
+ return;
}
-#endif
switch (vector) {
case 24: /* General Exception */
@@ -489,6 +483,30 @@
break;
case 26: /* NaT Consumption */
+ if (user_mode(regs)) {
+ if (((isr >> 4) & 0xf) == 2) {
+ /* NaT page consumption */
+ sig = SIGSEGV;
+ code = SEGV_ACCERR;
+ } else {
+ /* register NaT consumption */
+ sig = SIGILL;
+ code = ILL_ILLOPN;
+ }
+ siginfo.si_signo = sig;
+ siginfo.si_code = code;
+ siginfo.si_errno = 0;
+ siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+ siginfo.si_imm = vector;
+ siginfo.si_flags = __ISR_VALID;
+ siginfo.si_isr = isr;
+ force_sig_info(sig, &siginfo, current);
+ return;
+ } else if (done_with_exception(regs))
+ return;
+ sprintf(buf, "NaT consumption");
+ break;
+
case 31: /* Unsupported Data Reference */
if (user_mode(regs)) {
siginfo.si_signo = SIGILL;
@@ -501,7 +519,7 @@
force_sig_info(SIGILL, &siginfo, current);
return;
}
- sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference");
+ sprintf(buf, "Unsupported data reference");
break;
case 29: /* Debug */
@@ -518,16 +536,15 @@
if (ia64_psr(regs)->is == 0)
ifa = regs->cr_iip;
#endif
- siginfo.si_addr = (void *) ifa;
break;
- case 35: siginfo.si_code = TRAP_BRANCH; break;
- case 36: siginfo.si_code = TRAP_TRACE; break;
+ case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
+ case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
}
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0;
siginfo.si_flags = 0;
siginfo.si_isr = 0;
- siginfo.si_addr = 0;
+ siginfo.si_addr = (void *) ifa;
siginfo.si_imm = 0;
force_sig_info(SIGTRAP, &siginfo, current);
return;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)