2 * linux/arch/arm/mm/fault-common.c
4 * Copyright (C) 1995 Linus Torvalds
5 * Modifications for ARM processor (c) 1995-1999 Russell King
7 #include <linux/config.h>
9 extern void die(char *msg
, struct pt_regs
*regs
, unsigned int err
);
11 void __bad_pmd(pmd_t
*pmd
)
13 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd
));
14 #ifdef CONFIG_DEBUG_ERRORS
17 set_pmd(pmd
, mk_user_pmd(BAD_PAGETABLE
));
20 void __bad_pmd_kernel(pmd_t
*pmd
)
22 printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd
));
23 #ifdef CONFIG_DEBUG_ERRORS
26 set_pmd(pmd
, mk_kernel_pmd(BAD_PAGETABLE
));
30 * This is useful to dump out the page tables associated with
33 void show_pte(struct mm_struct
*mm
, unsigned long addr
)
37 pgd
= pgd_offset(mm
, addr
);
38 printk(KERN_ALERT
"*pgd = %08lx", pgd_val(*pgd
));
52 pmd
= pmd_offset(pgd
, addr
);
53 printk(", *pmd = %08lx", pmd_val(*pmd
));
63 pte
= pte_offset(pmd
, addr
);
64 printk(", *pte = %08lx", pte_val(*pte
));
65 printk(", *ppte = %08lx", pte_val(pte
[-PTRS_PER_PTE
]));
72 * Oops. The kernel tried to access some bad page. We'll have to
73 * terminate things with extreme prejudice.
76 kernel_page_fault(unsigned long addr
, int mode
, struct pt_regs
*regs
,
77 struct task_struct
*tsk
, struct mm_struct
*mm
)
82 reason
= "NULL pointer dereference";
84 reason
= "paging request";
86 printk(KERN_ALERT
"Unable to handle kernel %s at virtual address %08lx\n",
91 printk(KERN_ALERT
"pgd = %p\n", mm
->pgd
);
93 die("Oops", regs
, mode
);
98 static void do_page_fault(unsigned long addr
, int mode
, struct pt_regs
*regs
)
100 struct task_struct
*tsk
;
101 struct mm_struct
*mm
;
102 struct vm_area_struct
*vma
;
109 * If we're in an interrupt or have no user
110 * context, we must not take the fault..
112 if (in_interrupt() || !mm
)
116 vma
= find_vma(mm
, addr
);
119 if (vma
->vm_start
<= addr
)
121 if (!(vma
->vm_flags
& VM_GROWSDOWN
) || expand_stack(vma
, addr
))
125 * Ok, we have a good vm_area for this memory access, so
129 if (READ_FAULT(mode
)) { /* read? */
130 if (!(vma
->vm_flags
& (VM_READ
|VM_EXEC
)))
133 if (!(vma
->vm_flags
& VM_WRITE
))
138 * If for any reason at all we couldn't handle the fault,
139 * make sure we exit gracefully rather than endlessly redo
142 if (!handle_mm_fault(tsk
, vma
, addr
& PAGE_MASK
, DO_COW(mode
)))
149 * Something tried to access memory that isn't in our memory map..
150 * Fix it, but check if it's kernel or user first..
155 /* User mode accesses just cause a SIGSEGV */
156 if (mode
& FAULT_CODE_USER
) {
157 tsk
->thread
.error_code
= mode
;
158 tsk
->thread
.trap_no
= 14;
159 #ifdef CONFIG_DEBUG_USER
160 printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
161 tsk
->comm
, regs
->ARM_pc
, regs
->ARM_lr
, addr
, mode
);
163 force_sig(SIGSEGV
, tsk
);
168 /* Are we prepared to handle this kernel fault? */
169 if ((fixup
= search_exception_table(instruction_pointer(regs
))) != 0) {
171 printk(KERN_DEBUG
"%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
172 tsk
->comm
, regs
->ARM_pc
, addr
, fixup
);
174 regs
->ARM_pc
= fixup
;
178 kernel_page_fault(addr
, mode
, regs
, tsk
, mm
);
183 * We ran out of memory, or some other thing happened to us that made
184 * us unable to handle the page fault gracefully.
189 * Send a sigbus, regardless of whether we were in kernel
192 tsk
->thread
.error_code
= mode
;
193 tsk
->thread
.trap_no
= 14;
194 force_sig(SIGBUS
, tsk
);
196 /* Kernel mode? Handle exceptions or die */
197 if (!(mode
& FAULT_CODE_USER
))