X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fmm%2Ffault.c;h=cc857f681d97a49351556efbc85d924fbabea9f1;hb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;hp=ea2a40a46ef68be2547e9b87694fc8a658e97d17;hpb=c449269f45c2cdf53af08c8d0af37472f66539d9;p=linux-2.6.git diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index ea2a40a46..cc857f681 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -201,6 +201,25 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, return 0; } +extern unsigned long safe_compute_effective_address(struct pt_regs *, + unsigned int); + +static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) +{ + unsigned int insn; + + if (text_fault) + return regs->pc; + + if (regs->psr & PSR_PS) { + insn = *(unsigned int *) regs->pc; + } else { + __get_user(insn, (unsigned int *) regs->pc); + } + + return safe_compute_effective_address(regs, insn); +} + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long address) { @@ -307,7 +326,7 @@ bad_area_nosemaphore: info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ - info.si_addr = (void *)address; + info.si_addr = (void *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); return; @@ -361,7 +380,7 @@ do_sigbus: info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; + info.si_addr = (void *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); if (!from_user) @@ -412,10 +431,10 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, address = regs->pc; } else if (!write && !(regs->psr & PSR_PS)) { - unsigned int insn, *ip; + unsigned int insn, __user *ip; - ip = (unsigned int *)regs->pc; - if (! get_user(insn, ip)) { + ip = (unsigned int __user *)regs->pc; + if (!get_user(insn, ip)) { if ((insn & 0xc1680000) == 0xc0680000) write = 1; } @@ -530,7 +549,7 @@ bad_area: info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ - info.si_addr = (void *)address; + info.si_addr = (void *) address; info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); return; @@ -540,7 +559,7 @@ do_sigbus: info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; + info.si_addr = (void *) address; info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); }