Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.38-rc7 359 lines 8.9 kB view raw
1/* 2 * arch/cris/mm/fault.c 3 * 4 * Copyright (C) 2000-2010 Axis Communications AB 5 */ 6 7#include <linux/mm.h> 8#include <linux/interrupt.h> 9#include <linux/module.h> 10#include <linux/wait.h> 11#include <asm/uaccess.h> 12 13extern int find_fixup_code(struct pt_regs *); 14extern void die_if_kernel(const char *, struct pt_regs *, long); 15extern void show_registers(struct pt_regs *regs); 16 17/* debug of low-level TLB reload */ 18#undef DEBUG 19 20#ifdef DEBUG 21#define D(x) x 22#else 23#define D(x) 24#endif 25 26/* debug of higher-level faults */ 27#define DPG(x) 28 29/* current active page directory */ 30 31DEFINE_PER_CPU(pgd_t *, current_pgd); 32unsigned long cris_signal_return_page; 33 34/* 35 * This routine handles page faults. It determines the address, 36 * and the problem, and then passes it off to one of the appropriate 37 * routines. 38 * 39 * Notice that the address we're given is aligned to the page the fault 40 * occurred in, since we only get the PFN in R_MMU_CAUSE not the complete 41 * address. 42 * 43 * error_code: 44 * bit 0 == 0 means no page found, 1 means protection fault 45 * bit 1 == 0 means read, 1 means write 46 * 47 * If this routine detects a bad access, it returns 1, otherwise it 48 * returns 0. 49 */ 50 51asmlinkage void 52do_page_fault(unsigned long address, struct pt_regs *regs, 53 int protection, int writeaccess) 54{ 55 struct task_struct *tsk; 56 struct mm_struct *mm; 57 struct vm_area_struct * vma; 58 siginfo_t info; 59 int fault; 60 61 D(printk(KERN_DEBUG 62 "Page fault for %lX on %X at %lX, prot %d write %d\n", 63 address, smp_processor_id(), instruction_pointer(regs), 64 protection, writeaccess)); 65 66 tsk = current; 67 68 /* 69 * We fault-in kernel-space virtual memory on-demand. The 70 * 'reference' page table is init_mm.pgd. 71 * 72 * NOTE! We MUST NOT take any locks for this case. We may 73 * be in an interrupt or a critical region, and should 74 * only copy the information from the master page table, 75 * nothing more. 76 * 77 * NOTE2: This is done so that, when updating the vmalloc 78 * mappings we don't have to walk all processes pgdirs and 79 * add the high mappings all at once. Instead we do it as they 80 * are used. However vmalloc'ed page entries have the PAGE_GLOBAL 81 * bit set so sometimes the TLB can use a lingering entry. 82 * 83 * This verifies that the fault happens in kernel space 84 * and that the fault was not a protection error (error_code & 1). 85 */ 86 87 if (address >= VMALLOC_START && 88 !protection && 89 !user_mode(regs)) 90 goto vmalloc_fault; 91 92 /* When stack execution is not allowed we store the signal 93 * trampolines in the reserved cris_signal_return_page. 94 * Handle this in the exact same way as vmalloc (we know 95 * that the mapping is there and is valid so no need to 96 * call handle_mm_fault). 97 */ 98 if (cris_signal_return_page && 99 address == cris_signal_return_page && 100 !protection && user_mode(regs)) 101 goto vmalloc_fault; 102 103 /* we can and should enable interrupts at this point */ 104 local_irq_enable(); 105 106 mm = tsk->mm; 107 info.si_code = SEGV_MAPERR; 108 109 /* 110 * If we're in an interrupt or "atomic" operation or have no 111 * user context, we must not take the fault. 112 */ 113 114 if (in_atomic() || !mm) 115 goto no_context; 116 117 down_read(&mm->mmap_sem); 118 vma = find_vma(mm, address); 119 if (!vma) 120 goto bad_area; 121 if (vma->vm_start <= address) 122 goto good_area; 123 if (!(vma->vm_flags & VM_GROWSDOWN)) 124 goto bad_area; 125 if (user_mode(regs)) { 126 /* 127 * accessing the stack below usp is always a bug. 128 * we get page-aligned addresses so we can only check 129 * if we're within a page from usp, but that might be 130 * enough to catch brutal errors at least. 131 */ 132 if (address + PAGE_SIZE < rdusp()) 133 goto bad_area; 134 } 135 if (expand_stack(vma, address)) 136 goto bad_area; 137 138 /* 139 * Ok, we have a good vm_area for this memory access, so 140 * we can handle it.. 141 */ 142 143 good_area: 144 info.si_code = SEGV_ACCERR; 145 146 /* first do some preliminary protection checks */ 147 148 if (writeaccess == 2){ 149 if (!(vma->vm_flags & VM_EXEC)) 150 goto bad_area; 151 } else if (writeaccess == 1) { 152 if (!(vma->vm_flags & VM_WRITE)) 153 goto bad_area; 154 } else { 155 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 156 goto bad_area; 157 } 158 159 /* 160 * If for any reason at all we couldn't handle the fault, 161 * make sure we exit gracefully rather than endlessly redo 162 * the fault. 163 */ 164 165 fault = handle_mm_fault(mm, vma, address, (writeaccess & 1) ? FAULT_FLAG_WRITE : 0); 166 if (unlikely(fault & VM_FAULT_ERROR)) { 167 if (fault & VM_FAULT_OOM) 168 goto out_of_memory; 169 else if (fault & VM_FAULT_SIGBUS) 170 goto do_sigbus; 171 BUG(); 172 } 173 if (fault & VM_FAULT_MAJOR) 174 tsk->maj_flt++; 175 else 176 tsk->min_flt++; 177 178 up_read(&mm->mmap_sem); 179 return; 180 181 /* 182 * Something tried to access memory that isn't in our memory map.. 183 * Fix it, but check if it's kernel or user first.. 184 */ 185 186 bad_area: 187 up_read(&mm->mmap_sem); 188 189 bad_area_nosemaphore: 190 DPG(show_registers(regs)); 191 192 /* User mode accesses just cause a SIGSEGV */ 193 194 if (user_mode(regs)) { 195 printk(KERN_NOTICE "%s (pid %d) segfaults for page " 196 "address %08lx at pc %08lx\n", 197 tsk->comm, tsk->pid, 198 address, instruction_pointer(regs)); 199 200 /* With DPG on, we've already dumped registers above. */ 201 DPG(if (0)) 202 show_registers(regs); 203 204#ifdef CONFIG_NO_SEGFAULT_TERMINATION 205 DECLARE_WAIT_QUEUE_HEAD(wq); 206 wait_event_interruptible(wq, 0 == 1); 207#else 208 info.si_signo = SIGSEGV; 209 info.si_errno = 0; 210 /* info.si_code has been set above */ 211 info.si_addr = (void *)address; 212 force_sig_info(SIGSEGV, &info, tsk); 213#endif 214 return; 215 } 216 217 no_context: 218 219 /* Are we prepared to handle this kernel fault? 220 * 221 * (The kernel has valid exception-points in the source 222 * when it accesses user-memory. When it fails in one 223 * of those points, we find it in a table and do a jump 224 * to some fixup code that loads an appropriate error 225 * code) 226 */ 227 228 if (find_fixup_code(regs)) 229 return; 230 231 /* 232 * Oops. The kernel tried to access some bad page. We'll have to 233 * terminate things with extreme prejudice. 234 */ 235 236 if (!oops_in_progress) { 237 oops_in_progress = 1; 238 if ((unsigned long) (address) < PAGE_SIZE) 239 printk(KERN_ALERT "Unable to handle kernel NULL " 240 "pointer dereference"); 241 else 242 printk(KERN_ALERT "Unable to handle kernel access" 243 " at virtual address %08lx\n", address); 244 245 die_if_kernel("Oops", regs, (writeaccess << 1) | protection); 246 oops_in_progress = 0; 247 } 248 249 do_exit(SIGKILL); 250 251 /* 252 * We ran out of memory, or some other thing happened to us that made 253 * us unable to handle the page fault gracefully. 254 */ 255 256 out_of_memory: 257 up_read(&mm->mmap_sem); 258 if (!user_mode(regs)) 259 goto no_context; 260 pagefault_out_of_memory(); 261 return; 262 263 do_sigbus: 264 up_read(&mm->mmap_sem); 265 266 /* 267 * Send a sigbus, regardless of whether we were in kernel 268 * or user mode. 269 */ 270 info.si_signo = SIGBUS; 271 info.si_errno = 0; 272 info.si_code = BUS_ADRERR; 273 info.si_addr = (void *)address; 274 force_sig_info(SIGBUS, &info, tsk); 275 276 /* Kernel mode? Handle exceptions or die */ 277 if (!user_mode(regs)) 278 goto no_context; 279 return; 280 281vmalloc_fault: 282 { 283 /* 284 * Synchronize this task's top level page-table 285 * with the 'reference' page table. 286 * 287 * Use current_pgd instead of tsk->active_mm->pgd 288 * since the latter might be unavailable if this 289 * code is executed in a misfortunately run irq 290 * (like inside schedule() between switch_mm and 291 * switch_to...). 292 */ 293 294 int offset = pgd_index(address); 295 pgd_t *pgd, *pgd_k; 296 pud_t *pud, *pud_k; 297 pmd_t *pmd, *pmd_k; 298 pte_t *pte_k; 299 300 pgd = (pgd_t *)per_cpu(current_pgd, smp_processor_id()) + offset; 301 pgd_k = init_mm.pgd + offset; 302 303 /* Since we're two-level, we don't need to do both 304 * set_pgd and set_pmd (they do the same thing). If 305 * we go three-level at some point, do the right thing 306 * with pgd_present and set_pgd here. 307 * 308 * Also, since the vmalloc area is global, we don't 309 * need to copy individual PTE's, it is enough to 310 * copy the pgd pointer into the pte page of the 311 * root task. If that is there, we'll find our pte if 312 * it exists. 313 */ 314 315 pud = pud_offset(pgd, address); 316 pud_k = pud_offset(pgd_k, address); 317 if (!pud_present(*pud_k)) 318 goto no_context; 319 320 pmd = pmd_offset(pud, address); 321 pmd_k = pmd_offset(pud_k, address); 322 323 if (!pmd_present(*pmd_k)) 324 goto bad_area_nosemaphore; 325 326 set_pmd(pmd, *pmd_k); 327 328 /* Make sure the actual PTE exists as well to 329 * catch kernel vmalloc-area accesses to non-mapped 330 * addresses. If we don't do this, this will just 331 * silently loop forever. 332 */ 333 334 pte_k = pte_offset_kernel(pmd_k, address); 335 if (!pte_present(*pte_k)) 336 goto no_context; 337 338 return; 339 } 340} 341 342/* Find fixup code. */ 343int 344find_fixup_code(struct pt_regs *regs) 345{ 346 const struct exception_table_entry *fixup; 347 /* in case of delay slot fault (v32) */ 348 unsigned long ip = (instruction_pointer(regs) & ~0x1); 349 350 fixup = search_exception_tables(ip); 351 if (fixup != 0) { 352 /* Adjust the instruction pointer in the stackframe. */ 353 instruction_pointer(regs) = fixup->fixup; 354 arch_fixup(regs); 355 return 1; 356 } 357 358 return 0; 359}