aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/mm/fault_64.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 1a786abdada..4ab8993b086 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -225,6 +225,30 @@ cannot_handle:
unhandled_fault (address, current, regs);
}
+static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
+{
+ static int times;
+
+ if (times++ < 10)
+ printk(KERN_ERR "FAULT[%s:%d]: 32-bit process reports "
+ "64-bit TPC [%lx]\n",
+ current->comm, current->pid,
+ regs->tpc);
+ show_regs(regs);
+}
+
+static void noinline bogus_32bit_fault_address(struct pt_regs *regs,
+ unsigned long addr)
+{
+ static int times;
+
+ if (times++ < 10)
+ printk(KERN_ERR "FAULT[%s:%d]: 32-bit process "
+ "reports 64-bit fault address [%lx]\n",
+ current->comm, current->pid, addr);
+ show_regs(regs);
+}
+
asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
{
struct mm_struct *mm = current->mm;
@@ -246,13 +270,20 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
BUG();
if (test_thread_flag(TIF_32BIT)) {
- if (!(regs->tstate & TSTATE_PRIV))
- regs->tpc &= 0xffffffff;
- address &= 0xffffffff;
+ if (!(regs->tstate & TSTATE_PRIV)) {
+ if (unlikely((regs->tpc >> 32) != 0)) {
+ bogus_32bit_fault_tpc(regs);
+ goto intr_or_no_mm;
+ }
+ }
+ if (unlikely((address >> 32) != 0)) {
+ bogus_32bit_fault_address(regs, address);
+ goto intr_or_no_mm;
+ }
}
if (regs->tstate & TSTATE_PRIV) {
- unsigned long eaddr, tpc = regs->tpc;
+ unsigned long tpc = regs->tpc;
/* Sanity check the PC. */
if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
@@ -262,16 +293,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
bad_kernel_pc(regs, address);
return;
}
-
- insn = get_fault_insn(regs, insn);
- eaddr = compute_effective_address(regs, insn, 0);
- if (WARN_ON_ONCE((eaddr & PAGE_MASK) != (address & PAGE_MASK))){
- printk(KERN_ERR "FAULT: Mismatch kernel fault "
- "address: addr[%lx] eaddr[%lx] TPC[%lx]\n",
- address, eaddr, tpc);
- show_regs(regs);
- goto handle_kernel_fault;
- }
}
/*