sparc64: Don't bark so loudly about 32-bit tasks generating 64-bit fault addresses.
This was found using Dave Jone's trinity tool. When a user process which is 32-bit performs a load or a store, the cpu chops off the top 32-bits of the effective address before translating it. This is because we run 32-bit tasks with the PSTATE_AM (address masking) bit set. We can't run the kernel with that bit set, so when the kernel accesses userspace no address masking occurs. Since a 32-bit process will have no mappings in that region we will properly fault, so we don't try to handle this using access_ok(), which can safely just be a NOP on sparc64. Real faults from 32-bit processes should never generate such addresses so a bug check was added long ago, and it barks in the logs if this happens. But it also barks when a kernel user access causes this condition, and that _can_ happen. For example, if a pointer passed into a system call is "0xfffffffc" and the kernel access 4 bytes offset from that pointer. Just handle such faults normally via the exception entries. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
256cf4c438
commit
e5c460f46a
|
@ -281,18 +281,6 @@ static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void noinline __kprobes 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)
|
asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
enum ctx_state prev_state = exception_enter();
|
enum ctx_state prev_state = exception_enter();
|
||||||
|
@ -322,11 +310,9 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
||||||
goto intr_or_no_mm;
|
goto intr_or_no_mm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unlikely((address >> 32) != 0)) {
|
if (unlikely((address >> 32) != 0))
|
||||||
bogus_32bit_fault_address(regs, address);
|
|
||||||
goto intr_or_no_mm;
|
goto intr_or_no_mm;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
unsigned long tpc = regs->tpc;
|
unsigned long tpc = regs->tpc;
|
||||||
|
|
Loading…
Reference in New Issue