patch-1.3.12 linux/arch/alpha/kernel/traps.c
Next file: linux/drivers/block/README.aztcd
Previous file: linux/arch/alpha/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 71
- Date:
Mon Jul 24 17:38:25 1995
- Orig file:
v1.3.11/linux/arch/alpha/kernel/traps.c
- Orig date:
Thu Jul 13 16:20:19 1995
diff -u --recursive --new-file v1.3.11/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
@@ -67,8 +67,6 @@
if (ptrace_cancel_bpt(current)) {
regs.pc -= 4; /* make pc point to former bpt */
}
- if (current->flags & PF_PTRACED)
- current->blocked &= ~(1 << (SIGTRAP - 1));
send_sig(SIGTRAP, current, 1);
break;
@@ -90,9 +88,8 @@
* fp-regs), and it needs to have them in order for simpler access.
*
* Due to the non-standard register layout (and because we don't want
- * to handle floating-point regs), we disallow user-mode unaligned
- * accesses (we'd need to do "verify_area()" checking, as well as
- * do a full "ret_from_sys_call" return).
+ * to handle floating-point regs), user-mode unaligned accesses are
+ * handled separately by do_entUnaUser below.
*
* Oh, btw, we don't handle the "gp" register correctly, but if we fault
* on a gp-register unaligned load/store, something is _very_ wrong
@@ -103,17 +100,24 @@
unsigned long ps, pc, gp, a0, a1, a2;
};
+struct unaligned_stat {
+ unsigned long count, va, pc;
+} unaligned;
+
asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
unsigned long a3, unsigned long a4, unsigned long a5,
struct allregs regs)
{
static int cnt = 0;
- if (regs.ps & 8)
- do_exit(SIGSEGV);
if (++cnt < 5)
printk("Unaligned trap at %016lx: %p %lx %ld\n",
regs.pc, va, opcode, reg);
+
+ ++unaligned.count;
+ unaligned.va = (unsigned long) va - 4;
+ unaligned.pc = regs.pc;
+
/* $16-$18 are PAL-saved, and are offset by 19 entries */
if (reg >= 16 && reg <= 18)
reg += 19;
@@ -134,6 +138,22 @@
printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
regs.pc, va, opcode, reg);
do_exit(SIGSEGV);
+}
+
+/*
+ * Handle user-level unaligned fault. For now, simply send a
+ * SIGSEGV---there should be little reason for users not wanting to
+ * fix their code instead. Notice that we have the regular kernel
+ * stack layout here, so finding the appropriate registers is a little
+ * more difficult than in the kernel case. Also, we'd need to do
+ * a "verify_area()" before accessing memory on behalf of the user.
+ */
+asmlinkage void do_entUnaUser(void *va, unsigned long opcode, unsigned long reg,
+ unsigned long a3, unsigned long a4, unsigned long a5,
+ struct pt_regs regs)
+{
+ regs.pc -= 4; /* make pc point to faulting insn */
+ send_sig(SIGSEGV, current, 1);
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this