4 * Copyright (C) 2000-2010 Axis Communications AB
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/wait.h>
11 #include <asm/uaccess.h>
12 #include <arch/system.h>
14 extern int find_fixup_code(struct pt_regs
*);
15 extern void die_if_kernel(const char *, struct pt_regs
*, long);
16 extern void show_registers(struct pt_regs
*regs
);
18 /* debug of low-level TLB reload */
27 /* debug of higher-level faults */
30 /* current active page directory */
32 DEFINE_PER_CPU(pgd_t
*, current_pgd
);
33 unsigned long cris_signal_return_page
;
36 * This routine handles page faults. It determines the address,
37 * and the problem, and then passes it off to one of the appropriate
40 * Notice that the address we're given is aligned to the page the fault
41 * occurred in, since we only get the PFN in R_MMU_CAUSE not the complete
45 * bit 0 == 0 means no page found, 1 means protection fault
46 * bit 1 == 0 means read, 1 means write
48 * If this routine detects a bad access, it returns 1, otherwise it
53 do_page_fault(unsigned long address
, struct pt_regs
*regs
,
54 int protection
, int writeaccess
)
56 struct task_struct
*tsk
;
58 struct vm_area_struct
* vma
;
61 unsigned int flags
= FAULT_FLAG_ALLOW_RETRY
| FAULT_FLAG_KILLABLE
;
64 "Page fault for %lX on %X at %lX, prot %d write %d\n",
65 address
, smp_processor_id(), instruction_pointer(regs
),
66 protection
, writeaccess
));
71 * We fault-in kernel-space virtual memory on-demand. The
72 * 'reference' page table is init_mm.pgd.
74 * NOTE! We MUST NOT take any locks for this case. We may
75 * be in an interrupt or a critical region, and should
76 * only copy the information from the master page table,
79 * NOTE2: This is done so that, when updating the vmalloc
80 * mappings we don't have to walk all processes pgdirs and
81 * add the high mappings all at once. Instead we do it as they
82 * are used. However vmalloc'ed page entries have the PAGE_GLOBAL
83 * bit set so sometimes the TLB can use a lingering entry.
85 * This verifies that the fault happens in kernel space
86 * and that the fault was not a protection error (error_code & 1).
89 if (address
>= VMALLOC_START
&&
94 /* When stack execution is not allowed we store the signal
95 * trampolines in the reserved cris_signal_return_page.
96 * Handle this in the exact same way as vmalloc (we know
97 * that the mapping is there and is valid so no need to
98 * call handle_mm_fault).
100 if (cris_signal_return_page
&&
101 address
== cris_signal_return_page
&&
102 !protection
&& user_mode(regs
))
105 /* we can and should enable interrupts at this point */
109 info
.si_code
= SEGV_MAPERR
;
112 * If we're in an interrupt or "atomic" operation or have no
113 * user context, we must not take the fault.
116 if (in_atomic() || !mm
)
120 flags
|= FAULT_FLAG_USER
;
122 down_read(&mm
->mmap_sem
);
123 vma
= find_vma(mm
, address
);
126 if (vma
->vm_start
<= address
)
128 if (!(vma
->vm_flags
& VM_GROWSDOWN
))
130 if (user_mode(regs
)) {
132 * accessing the stack below usp is always a bug.
133 * we get page-aligned addresses so we can only check
134 * if we're within a page from usp, but that might be
135 * enough to catch brutal errors at least.
137 if (address
+ PAGE_SIZE
< rdusp())
140 if (expand_stack(vma
, address
))
144 * Ok, we have a good vm_area for this memory access, so
149 info
.si_code
= SEGV_ACCERR
;
151 /* first do some preliminary protection checks */
153 if (writeaccess
== 2){
154 if (!(vma
->vm_flags
& VM_EXEC
))
156 } else if (writeaccess
== 1) {
157 if (!(vma
->vm_flags
& VM_WRITE
))
159 flags
|= FAULT_FLAG_WRITE
;
161 if (!(vma
->vm_flags
& (VM_READ
| VM_EXEC
)))
166 * If for any reason at all we couldn't handle the fault,
167 * make sure we exit gracefully rather than endlessly redo
171 fault
= handle_mm_fault(mm
, vma
, address
, flags
);
173 if ((fault
& VM_FAULT_RETRY
) && fatal_signal_pending(current
))
176 if (unlikely(fault
& VM_FAULT_ERROR
)) {
177 if (fault
& VM_FAULT_OOM
)
179 else if (fault
& VM_FAULT_SIGBUS
)
184 if (flags
& FAULT_FLAG_ALLOW_RETRY
) {
185 if (fault
& VM_FAULT_MAJOR
)
189 if (fault
& VM_FAULT_RETRY
) {
190 flags
&= ~FAULT_FLAG_ALLOW_RETRY
;
191 flags
|= FAULT_FLAG_TRIED
;
194 * No need to up_read(&mm->mmap_sem) as we would
195 * have already released it in __lock_page_or_retry
203 up_read(&mm
->mmap_sem
);
207 * Something tried to access memory that isn't in our memory map..
208 * Fix it, but check if it's kernel or user first..
212 up_read(&mm
->mmap_sem
);
214 bad_area_nosemaphore
:
215 DPG(show_registers(regs
));
217 /* User mode accesses just cause a SIGSEGV */
219 if (user_mode(regs
)) {
220 printk(KERN_NOTICE
"%s (pid %d) segfaults for page "
221 "address %08lx at pc %08lx\n",
223 address
, instruction_pointer(regs
));
225 /* With DPG on, we've already dumped registers above. */
227 show_registers(regs
);
229 #ifdef CONFIG_NO_SEGFAULT_TERMINATION
230 DECLARE_WAIT_QUEUE_HEAD(wq
);
231 wait_event_interruptible(wq
, 0 == 1);
233 info
.si_signo
= SIGSEGV
;
235 /* info.si_code has been set above */
236 info
.si_addr
= (void *)address
;
237 force_sig_info(SIGSEGV
, &info
, tsk
);
244 /* Are we prepared to handle this kernel fault?
246 * (The kernel has valid exception-points in the source
247 * when it accesses user-memory. When it fails in one
248 * of those points, we find it in a table and do a jump
249 * to some fixup code that loads an appropriate error
253 if (find_fixup_code(regs
))
257 * Oops. The kernel tried to access some bad page. We'll have to
258 * terminate things with extreme prejudice.
261 if (!oops_in_progress
) {
262 oops_in_progress
= 1;
263 if ((unsigned long) (address
) < PAGE_SIZE
)
264 printk(KERN_ALERT
"Unable to handle kernel NULL "
265 "pointer dereference");
267 printk(KERN_ALERT
"Unable to handle kernel access"
268 " at virtual address %08lx\n", address
);
270 die_if_kernel("Oops", regs
, (writeaccess
<< 1) | protection
);
271 oops_in_progress
= 0;
277 * We ran out of memory, or some other thing happened to us that made
278 * us unable to handle the page fault gracefully.
282 up_read(&mm
->mmap_sem
);
283 if (!user_mode(regs
))
285 pagefault_out_of_memory();
289 up_read(&mm
->mmap_sem
);
292 * Send a sigbus, regardless of whether we were in kernel
295 info
.si_signo
= SIGBUS
;
297 info
.si_code
= BUS_ADRERR
;
298 info
.si_addr
= (void *)address
;
299 force_sig_info(SIGBUS
, &info
, tsk
);
301 /* Kernel mode? Handle exceptions or die */
302 if (!user_mode(regs
))
309 * Synchronize this task's top level page-table
310 * with the 'reference' page table.
312 * Use current_pgd instead of tsk->active_mm->pgd
313 * since the latter might be unavailable if this
314 * code is executed in a misfortunately run irq
315 * (like inside schedule() between switch_mm and
319 int offset
= pgd_index(address
);
325 pgd
= (pgd_t
*)per_cpu(current_pgd
, smp_processor_id()) + offset
;
326 pgd_k
= init_mm
.pgd
+ offset
;
328 /* Since we're two-level, we don't need to do both
329 * set_pgd and set_pmd (they do the same thing). If
330 * we go three-level at some point, do the right thing
331 * with pgd_present and set_pgd here.
333 * Also, since the vmalloc area is global, we don't
334 * need to copy individual PTE's, it is enough to
335 * copy the pgd pointer into the pte page of the
336 * root task. If that is there, we'll find our pte if
340 pud
= pud_offset(pgd
, address
);
341 pud_k
= pud_offset(pgd_k
, address
);
342 if (!pud_present(*pud_k
))
345 pmd
= pmd_offset(pud
, address
);
346 pmd_k
= pmd_offset(pud_k
, address
);
348 if (!pmd_present(*pmd_k
))
349 goto bad_area_nosemaphore
;
351 set_pmd(pmd
, *pmd_k
);
353 /* Make sure the actual PTE exists as well to
354 * catch kernel vmalloc-area accesses to non-mapped
355 * addresses. If we don't do this, this will just
356 * silently loop forever.
359 pte_k
= pte_offset_kernel(pmd_k
, address
);
360 if (!pte_present(*pte_k
))
367 /* Find fixup code. */
369 find_fixup_code(struct pt_regs
*regs
)
371 const struct exception_table_entry
*fixup
;
372 /* in case of delay slot fault (v32) */
373 unsigned long ip
= (instruction_pointer(regs
) & ~0x1);
375 fixup
= search_exception_tables(ip
);
377 /* Adjust the instruction pointer in the stackframe. */
378 instruction_pointer(regs
) = fixup
->fixup
;