diff options
Diffstat (limited to 'arch/parisc/mm/fault.c')
-rw-r--r-- | arch/parisc/mm/fault.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index deab89a8915a..32ec22146141 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c | |||
@@ -150,6 +150,23 @@ int fixup_exception(struct pt_regs *regs) | |||
150 | d->fault_space = regs->isr; | 150 | d->fault_space = regs->isr; |
151 | d->fault_addr = regs->ior; | 151 | d->fault_addr = regs->ior; |
152 | 152 | ||
153 | /* | ||
154 | * Fix up get_user() and put_user(). | ||
155 | * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant | ||
156 | * bit in the relative address of the fixup routine to indicate | ||
157 | * that %r8 should be loaded with -EFAULT to report a userspace | ||
158 | * access error. | ||
159 | */ | ||
160 | if (fix->fixup & 1) { | ||
161 | regs->gr[8] = -EFAULT; | ||
162 | |||
163 | /* zero target register for get_user() */ | ||
164 | if (parisc_acctyp(0, regs->iir) == VM_READ) { | ||
165 | int treg = regs->iir & 0x1f; | ||
166 | regs->gr[treg] = 0; | ||
167 | } | ||
168 | } | ||
169 | |||
153 | regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup; | 170 | regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup; |
154 | regs->iaoq[0] &= ~3; | 171 | regs->iaoq[0] &= ~3; |
155 | /* | 172 | /* |