diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-11 18:15:25 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-11 18:15:25 +0900 |
commit | 78d4a42069b4815040a857a4e9bb0e4fb0aa1dc8 (patch) | |
tree | ec7d095a3ad7aa78933d970b16ba55c667fb4b63 /arch/parisc/mm/fault.c | |
parent | f9efbce6334844c7f8b9b9459f6d7a6fbc2928e0 (diff) | |
parent | dce0ce46ca9a676e4d9b36432fea77330a0e901d (diff) |
Merge branch 'parisc-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc update from Helge Deller:
- a bugfix for sticon (parisc text console driver) to not crash the
64bit kernel on machines with more than 4GB RAM
- added kernel audit support
- made udelay() implementation SMP-safe
- "make install" now does not depend on vmlinux
- added defconfigs for 32- and 64-kernels
* 'parisc-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: add generic 32- and 64-bit defconfigs
parisc: sticon - unbreak on 64bit kernel
parisc: signal fixup - SIGBUS vs. SIGSEGV
parisc: implement full version of access_ok()
parisc: correctly display number of active CPUs
parisc: do not count IPI calls twice
parisc: make udelay() SMP-safe
parisc: remove duplicate define
parisc: make "make install" not depend on vmlinux
parisc: add kernel audit feature
parisc: provide macro to create exception table entries
Diffstat (limited to 'arch/parisc/mm/fault.c')
-rw-r--r-- | arch/parisc/mm/fault.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 0293588d5b8c..7584a5df0fa4 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fix; + /* If we only stored 32bit addresses in the exception table we can drop + * out if we faulted on a 64bit address. */ + if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn)) + && (regs->iaoq[0] >> 32)) + return 0; + fix = search_exception_tables(regs->iaoq[0]); if (fix) { struct exception_data *d; @@ -274,12 +280,22 @@ bad_area: } show_regs(regs); #endif - /* FIXME: actually we need to get the signo and code correct */ - si.si_signo = SIGSEGV; + switch (code) { + case 15: /* Data TLB miss fault/Data page fault */ + case 17: /* NA data TLB miss / page fault */ + case 18: /* Unaligned access - PCXS only */ + si.si_signo = SIGBUS; + si.si_code = BUS_ADRERR; + break; + case 16: /* Non-access instruction TLB miss fault */ + case 26: /* PCXL: Data memory access rights trap */ + default: + si.si_signo = SIGSEGV; + si.si_code = SEGV_MAPERR; + } si.si_errno = 0; - si.si_code = SEGV_MAPERR; si.si_addr = (void __user *) address; - force_sig_info(SIGSEGV, &si, current); + force_sig_info(si.si_signo, &si, current); return; } |