fault.c (3eb0f5193b497083391aa05d35210d5645211eef) | fault.c (75bfb9a1c89ae1f28cd09f7ae0d236ebde9b97ec) |
---|---|
1/* 2 * OpenRISC fault.c 3 * 4 * Linux architectural port borrowing liberally from similar works of 5 * others. All original copyrights apply as per the original source 6 * declaration. 7 * 8 * Modifications for the OpenRISC architecture: --- 38 unchanged lines hidden (view full) --- 47 */ 48 49asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, 50 unsigned long vector, int write_acc) 51{ 52 struct task_struct *tsk; 53 struct mm_struct *mm; 54 struct vm_area_struct *vma; | 1/* 2 * OpenRISC fault.c 3 * 4 * Linux architectural port borrowing liberally from similar works of 5 * others. All original copyrights apply as per the original source 6 * declaration. 7 * 8 * Modifications for the OpenRISC architecture: --- 38 unchanged lines hidden (view full) --- 47 */ 48 49asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address, 50 unsigned long vector, int write_acc) 51{ 52 struct task_struct *tsk; 53 struct mm_struct *mm; 54 struct vm_area_struct *vma; |
55 siginfo_t info; | 55 int si_code; |
56 int fault; 57 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; 58 | 56 int fault; 57 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; 58 |
59 clear_siginfo(&info); | |
60 tsk = current; 61 62 /* 63 * We fault-in kernel-space virtual memory on-demand. The 64 * 'reference' page table is init_mm.pgd. 65 * 66 * NOTE! We MUST NOT take any locks for this case. We may 67 * be in an interrupt or a critical region, and should --- 25 unchanged lines hidden (view full) --- 93 * been enabled or disabled. If they were enabled, 94 * reenable them. 95 */ 96 if (regs->sr && (SPR_SR_IEE | SPR_SR_TEE)) 97 local_irq_enable(); 98 } 99 100 mm = tsk->mm; | 59 tsk = current; 60 61 /* 62 * We fault-in kernel-space virtual memory on-demand. The 63 * 'reference' page table is init_mm.pgd. 64 * 65 * NOTE! We MUST NOT take any locks for this case. We may 66 * be in an interrupt or a critical region, and should --- 25 unchanged lines hidden (view full) --- 92 * been enabled or disabled. If they were enabled, 93 * reenable them. 94 */ 95 if (regs->sr && (SPR_SR_IEE | SPR_SR_TEE)) 96 local_irq_enable(); 97 } 98 99 mm = tsk->mm; |
101 info.si_code = SEGV_MAPERR; | 100 si_code = SEGV_MAPERR; |
102 103 /* 104 * If we're in an interrupt or have no user 105 * context, we must not take the fault.. 106 */ 107 108 if (in_interrupt() || !mm) 109 goto no_context; --- 25 unchanged lines hidden (view full) --- 135 goto bad_area; 136 137 /* 138 * Ok, we have a good vm_area for this memory access, so 139 * we can handle it.. 140 */ 141 142good_area: | 101 102 /* 103 * If we're in an interrupt or have no user 104 * context, we must not take the fault.. 105 */ 106 107 if (in_interrupt() || !mm) 108 goto no_context; --- 25 unchanged lines hidden (view full) --- 134 goto bad_area; 135 136 /* 137 * Ok, we have a good vm_area for this memory access, so 138 * we can handle it.. 139 */ 140 141good_area: |
143 info.si_code = SEGV_ACCERR; | 142 si_code = SEGV_ACCERR; |
144 145 /* first do some preliminary protection checks */ 146 147 if (write_acc) { 148 if (!(vma->vm_flags & VM_WRITE)) 149 goto bad_area; 150 flags |= FAULT_FLAG_WRITE; 151 } else { --- 57 unchanged lines hidden (view full) --- 209bad_area: 210 up_read(&mm->mmap_sem); 211 212bad_area_nosemaphore: 213 214 /* User mode accesses just cause a SIGSEGV */ 215 216 if (user_mode(regs)) { | 143 144 /* first do some preliminary protection checks */ 145 146 if (write_acc) { 147 if (!(vma->vm_flags & VM_WRITE)) 148 goto bad_area; 149 flags |= FAULT_FLAG_WRITE; 150 } else { --- 57 unchanged lines hidden (view full) --- 208bad_area: 209 up_read(&mm->mmap_sem); 210 211bad_area_nosemaphore: 212 213 /* User mode accesses just cause a SIGSEGV */ 214 215 if (user_mode(regs)) { |
217 info.si_signo = SIGSEGV; 218 info.si_errno = 0; 219 /* info.si_code has been set above */ 220 info.si_addr = (void *)address; 221 force_sig_info(SIGSEGV, &info, tsk); | 216 force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk); |
222 return; 223 } 224 225no_context: 226 227 /* Are we prepared to handle this kernel fault? 228 * 229 * (The kernel has valid exception-points in the source --- 48 unchanged lines hidden (view full) --- 278 279do_sigbus: 280 up_read(&mm->mmap_sem); 281 282 /* 283 * Send a sigbus, regardless of whether we were in kernel 284 * or user mode. 285 */ | 217 return; 218 } 219 220no_context: 221 222 /* Are we prepared to handle this kernel fault? 223 * 224 * (The kernel has valid exception-points in the source --- 48 unchanged lines hidden (view full) --- 273 274do_sigbus: 275 up_read(&mm->mmap_sem); 276 277 /* 278 * Send a sigbus, regardless of whether we were in kernel 279 * or user mode. 280 */ |
286 info.si_signo = SIGBUS; 287 info.si_errno = 0; 288 info.si_code = BUS_ADRERR; 289 info.si_addr = (void *)address; 290 force_sig_info(SIGBUS, &info, tsk); | 281 force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk); |
291 292 /* Kernel mode? Handle exceptions or die */ 293 if (!user_mode(regs)) 294 goto no_context; 295 return; 296 297vmalloc_fault: 298 { --- 65 unchanged lines hidden --- | 282 283 /* Kernel mode? Handle exceptions or die */ 284 if (!user_mode(regs)) 285 goto no_context; 286 return; 287 288vmalloc_fault: 289 { --- 65 unchanged lines hidden --- |