patch-2.2.8 linux/arch/alpha/kernel/traps.c
Next file: linux/arch/alpha/lib/copy_user.S
Previous file: linux/arch/alpha/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 139
- Date:
Mon May 10 09:55:21 1999
- Orig file:
v2.2.7/linux/arch/alpha/kernel/traps.c
- Orig date:
Tue Feb 23 15:21:32 1999
diff -u --recursive --new-file v2.2.7/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
@@ -125,13 +125,16 @@
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{
- if ((summary & 1)) {
- /*
- * Software-completion summary bit is set, so try to
- * emulate the instruction.
- */
- if (alpha_fp_emul_imprecise(®s, write_mask)) {
- return; /* emulation was successful */
+ if (summary & 1) {
+ /* Software-completion summary bit is set, so try to
+ emulate the instruction. */
+ if (implver() == IMPLVER_EV6) {
+ /* Whee! EV6 has precice exceptions. */
+ if (alpha_fp_emul(regs.pc - 4))
+ return;
+ } else {
+ if (alpha_fp_emul_imprecise(®s, write_mask))
+ return;
}
}
@@ -141,7 +144,7 @@
current->comm, regs.pc, summary, write_mask);
#endif
die_if_kernel("Arithmetic fault", ®s, 0, 0);
- force_sig(SIGFPE, current);
+ send_sig(SIGFPE, current, 1);
unlock_kernel();
}
@@ -150,14 +153,17 @@
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{
- lock_kernel();
die_if_kernel("Instruction fault", ®s, type, 0);
switch (type) {
case 0: /* breakpoint */
if (ptrace_cancel_bpt(current)) {
regs.pc -= 4; /* make pc point to former bpt */
}
- force_sig(SIGTRAP, current);
+ send_sig(SIGTRAP, current, 1);
+ break;
+
+ case 1: /* bugcheck */
+ send_sig(SIGTRAP, current, 1);
break;
case 2: /* gentrap */
@@ -171,14 +177,13 @@
switch ((long) regs.r16) {
case GEN_INTOVF: case GEN_INTDIV: case GEN_FLTOVF:
case GEN_FLTDIV: case GEN_FLTUND: case GEN_FLTINV:
- case GEN_FLTINE:
- force_sig(SIGFPE, current);
+ case GEN_FLTINE: case GEN_ROPRAND:
+ send_sig(SIGFPE, current, 1);
break;
case GEN_DECOVF:
case GEN_DECDIV:
case GEN_DECINV:
- case GEN_ROPRAND:
case GEN_ASSERTERR:
case GEN_NULPTRERR:
case GEN_STKOVF:
@@ -193,42 +198,29 @@
case GEN_SUBRNG5:
case GEN_SUBRNG6:
case GEN_SUBRNG7:
- force_sig(SIGILL, current);
+ send_sig(SIGTRAP, current, 1);
break;
}
break;
- case 1: /* bugcheck */
case 3: /* FEN fault */
- force_sig(SIGILL, current);
+ send_sig(SIGILL, current, 1);
break;
case 4: /* opDEC */
-#ifdef CONFIG_ALPHA_NEED_ROUNDING_EMULATION
- {
- unsigned int opcode;
-
- /* get opcode of faulting instruction: */
- get_user(opcode, (__u32*)(regs.pc - 4));
- opcode >>= 26;
- if (opcode == 0x16) {
- /*
- * It's a FLTI instruction, emulate it
- * (we don't do no stinkin' VAX fp...)
- */
- if (!alpha_fp_emul(regs.pc - 4))
- force_sig(SIGFPE, current);
- break;
- }
+ if (implver() == IMPLVER_EV4) {
+ /* EV4 does not implement anything except normal
+ rounding. Everything else will come here as
+ an illegal instruction. Emulate them. */
+ if (alpha_fp_emul(regs.pc - 4))
+ return;
}
-#endif
- force_sig(SIGILL, current);
+ send_sig(SIGILL, current, 1);
break;
default:
panic("do_entIF: unexpected instruction-fault type");
}
- unlock_kernel();
}
/* There is an ifdef in the PALcode in MILO that enables a
@@ -877,14 +869,14 @@
give_sigsegv:
regs->pc -= 4; /* make pc point to faulting insn */
lock_kernel();
- force_sig(SIGSEGV, current);
+ send_sig(SIGSEGV, current, 1);
unlock_kernel();
return;
give_sigbus:
regs->pc -= 4;
lock_kernel();
- force_sig(SIGBUS, current);
+ send_sig(SIGBUS, current, 1);
unlock_kernel();
return;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)