fault.c revision c421b08ef52f38049c6f591c5d260a97af7b0000
1/* MN10300 MMU Fault handler 2 * 3 * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. 4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 5 * Modified by David Howells (dhowells@redhat.com) 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public Licence 9 * as published by the Free Software Foundation; either version 10 * 2 of the Licence, or (at your option) any later version. 11 */ 12 13#include <linux/signal.h> 14#include <linux/sched.h> 15#include <linux/kernel.h> 16#include <linux/errno.h> 17#include <linux/string.h> 18#include <linux/types.h> 19#include <linux/ptrace.h> 20#include <linux/mman.h> 21#include <linux/mm.h> 22#include <linux/smp.h> 23#include <linux/interrupt.h> 24#include <linux/init.h> 25#include <linux/vt_kern.h> /* For unblank_screen() */ 26 27#include <asm/system.h> 28#include <asm/uaccess.h> 29#include <asm/pgalloc.h> 30#include <asm/hardirq.h> 31#include <asm/gdb-stub.h> 32#include <asm/cpu-regs.h> 33 34/* 35 * Unlock any spinlocks which will prevent us from getting the 36 * message out 37 */ 38void bust_spinlocks(int yes) 39{ 40 if (yes) { 41 oops_in_progress = 1; 42#ifdef CONFIG_SMP 43 /* Many serial drivers do __global_cli() */ 44 global_irq_lock = 0; 45#endif 46 } else { 47 int loglevel_save = console_loglevel; 48#ifdef CONFIG_VT 49 unblank_screen(); 50#endif 51 oops_in_progress = 0; 52 /* 53 * OK, the message is on the console. Now we call printk() 54 * without oops_in_progress set so that printk will give klogd 55 * a poke. Hold onto your hats... 56 */ 57 console_loglevel = 15; /* NMI oopser may have shut the console 58 * up */ 59 printk(" "); 60 console_loglevel = loglevel_save; 61 } 62} 63 64void do_BUG(const char *file, int line) 65{ 66 bust_spinlocks(1); 67 printk(KERN_EMERG "------------[ cut here ]------------\n"); 68 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); 69} 70 71#if 0 72static void print_pagetable_entries(pgd_t *pgdir, unsigned long address) 73{ 74 pgd_t *pgd; 75 pmd_t *pmd; 76 pte_t *pte; 77 78 pgd = pgdir + __pgd_offset(address); 79 printk(KERN_DEBUG "pgd entry %p: %016Lx\n", 80 pgd, (long long) pgd_val(*pgd)); 81 82 if (!pgd_present(*pgd)) { 83 printk(KERN_DEBUG "... pgd not present!\n"); 84 return; 85 } 86 pmd = pmd_offset(pgd, address); 87 printk(KERN_DEBUG "pmd entry %p: %016Lx\n", 88 pmd, (long long)pmd_val(*pmd)); 89 90 if (!pmd_present(*pmd)) { 91 printk(KERN_DEBUG "... pmd not present!\n"); 92 return; 93 } 94 pte = pte_offset(pmd, address); 95 printk(KERN_DEBUG "pte entry %p: %016Lx\n", 96 pte, (long long) pte_val(*pte)); 97 98 if (!pte_present(*pte)) 99 printk(KERN_DEBUG "... pte not present!\n"); 100} 101#endif 102 103asmlinkage void monitor_signal(struct pt_regs *); 104 105/* 106 * This routine handles page faults. It determines the address, 107 * and the problem, and then passes it off to one of the appropriate 108 * routines. 109 * 110 * fault_code: 111 * - LSW: either MMUFCR_IFC or MMUFCR_DFC as appropriate 112 * - MSW: 0 if data access, 1 if instruction access 113 * - bit 0: TLB miss flag 114 * - bit 1: initial write 115 * - bit 2: page invalid 116 * - bit 3: protection violation 117 * - bit 4: accessor (0=user 1=kernel) 118 * - bit 5: 0=read 1=write 119 * - bit 6-8: page protection spec 120 * - bit 9: illegal address 121 * - bit 16: 0=data 1=ins 122 * 123 */ 124asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code, 125 unsigned long address) 126{ 127 struct vm_area_struct *vma; 128 struct task_struct *tsk; 129 struct mm_struct *mm; 130 unsigned long page; 131 siginfo_t info; 132 int write, fault; 133 134#ifdef CONFIG_GDBSTUB 135 /* handle GDB stub causing a fault */ 136 if (gdbstub_busy) { 137 gdbstub_exception(regs, TBR & TBR_INT_CODE); 138 return; 139 } 140#endif 141 142#if 0 143 printk(KERN_DEBUG "--- do_page_fault(%p,%s:%04lx,%08lx)\n", 144 regs, 145 fault_code & 0x10000 ? "ins" : "data", 146 fault_code & 0xffff, address); 147#endif 148 149 tsk = current; 150 151 /* 152 * We fault-in kernel-space virtual memory on-demand. The 153 * 'reference' page table is init_mm.pgd. 154 * 155 * NOTE! We MUST NOT take any locks for this case. We may 156 * be in an interrupt or a critical region, and should 157 * only copy the information from the master page table, 158 * nothing more. 159 * 160 * This verifies that the fault happens in kernel space 161 * and that the fault was a page not present (invalid) error 162 */ 163 if (address >= VMALLOC_START && address < VMALLOC_END && 164 (fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_SR && 165 (fault_code & MMUFCR_xFC_PGINVAL) == MMUFCR_xFC_PGINVAL 166 ) 167 goto vmalloc_fault; 168 169 mm = tsk->mm; 170 info.si_code = SEGV_MAPERR; 171 172 /* 173 * If we're in an interrupt or have no user 174 * context, we must not take the fault.. 175 */ 176 if (in_atomic() || !mm) 177 goto no_context; 178 179 down_read(&mm->mmap_sem); 180 181 vma = find_vma(mm, address); 182 if (!vma) 183 goto bad_area; 184 if (vma->vm_start <= address) 185 goto good_area; 186 if (!(vma->vm_flags & VM_GROWSDOWN)) 187 goto bad_area; 188 189 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) { 190 /* accessing the stack below the stack pointer is always a 191 * bug */ 192 if ((address & PAGE_MASK) + 2 * PAGE_SIZE < regs->sp) { 193#if 0 194 printk(KERN_WARNING 195 "[%d] ### Access below stack @%lx (sp=%lx)\n", 196 current->pid, address, regs->sp); 197 printk(KERN_WARNING 198 "vma [%08x - %08x]\n", 199 vma->vm_start, vma->vm_end); 200 show_registers(regs); 201 printk(KERN_WARNING 202 "[%d] ### Code: [%08lx]" 203 " %02x %02x %02x %02x %02x %02x %02x %02x\n", 204 current->pid, 205 regs->pc, 206 ((u8 *) regs->pc)[0], 207 ((u8 *) regs->pc)[1], 208 ((u8 *) regs->pc)[2], 209 ((u8 *) regs->pc)[3], 210 ((u8 *) regs->pc)[4], 211 ((u8 *) regs->pc)[5], 212 ((u8 *) regs->pc)[6], 213 ((u8 *) regs->pc)[7] 214 ); 215#endif 216 goto bad_area; 217 } 218 } 219 220 if (expand_stack(vma, address)) 221 goto bad_area; 222 223/* 224 * Ok, we have a good vm_area for this memory access, so 225 * we can handle it.. 226 */ 227good_area: 228 info.si_code = SEGV_ACCERR; 229 write = 0; 230 switch (fault_code & (MMUFCR_xFC_PGINVAL|MMUFCR_xFC_TYPE)) { 231 default: /* 3: write, present */ 232 case MMUFCR_xFC_TYPE_WRITE: 233#ifdef TEST_VERIFY_AREA 234 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_SR) 235 printk(KERN_DEBUG "WP fault at %08lx\n", regs->pc); 236#endif 237 /* write to absent page */ 238 case MMUFCR_xFC_PGINVAL | MMUFCR_xFC_TYPE_WRITE: 239 if (!(vma->vm_flags & VM_WRITE)) 240 goto bad_area; 241 write++; 242 break; 243 244 /* read from protected page */ 245 case MMUFCR_xFC_TYPE_READ: 246 goto bad_area; 247 248 /* read from absent page present */ 249 case MMUFCR_xFC_PGINVAL | MMUFCR_xFC_TYPE_READ: 250 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 251 goto bad_area; 252 break; 253 } 254 255 /* 256 * If for any reason at all we couldn't handle the fault, 257 * make sure we exit gracefully rather than endlessly redo 258 * the fault. 259 */ 260 fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); 261 if (unlikely(fault & VM_FAULT_ERROR)) { 262 if (fault & VM_FAULT_OOM) 263 goto out_of_memory; 264 else if (fault & VM_FAULT_SIGBUS) 265 goto do_sigbus; 266 BUG(); 267 } 268 if (fault & VM_FAULT_MAJOR) 269 current->maj_flt++; 270 else 271 current->min_flt++; 272 273 up_read(&mm->mmap_sem); 274 return; 275 276/* 277 * Something tried to access memory that isn't in our memory map.. 278 * Fix it, but check if it's kernel or user first.. 279 */ 280bad_area: 281 up_read(&mm->mmap_sem); 282 monitor_signal(regs); 283 284 /* User mode accesses just cause a SIGSEGV */ 285 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) { 286 info.si_signo = SIGSEGV; 287 info.si_errno = 0; 288 /* info.si_code has been set above */ 289 info.si_addr = (void *)address; 290 force_sig_info(SIGSEGV, &info, tsk); 291 return; 292 } 293 294no_context: 295 monitor_signal(regs); 296 /* Are we prepared to handle this kernel fault? */ 297 if (fixup_exception(regs)) 298 return; 299 300/* 301 * Oops. The kernel tried to access some bad page. We'll have to 302 * terminate things with extreme prejudice. 303 */ 304 305 bust_spinlocks(1); 306 307 if (address < PAGE_SIZE) 308 printk(KERN_ALERT 309 "Unable to handle kernel NULL pointer dereference"); 310 else 311 printk(KERN_ALERT 312 "Unable to handle kernel paging request"); 313 printk(" at virtual address %08lx\n", address); 314 printk(" printing pc:\n"); 315 printk(KERN_ALERT "%08lx\n", regs->pc); 316 317#ifdef CONFIG_GDBSTUB 318 gdbstub_intercept( 319 regs, fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR); 320#endif 321 322 page = PTBR; 323 page = ((unsigned long *) __va(page))[address >> 22]; 324 printk(KERN_ALERT "*pde = %08lx\n", page); 325 if (page & 1) { 326 page &= PAGE_MASK; 327 address &= 0x003ff000; 328 page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; 329 printk(KERN_ALERT "*pte = %08lx\n", page); 330 } 331 332 die("Oops", regs, fault_code); 333 do_exit(SIGKILL); 334 335/* 336 * We ran out of memory, or some other thing happened to us that made 337 * us unable to handle the page fault gracefully. 338 */ 339out_of_memory: 340 up_read(&mm->mmap_sem); 341 if ((fault_code & MMUFCR_xFC_ACCESS) != MMUFCR_xFC_ACCESS_USR) 342 goto no_context; 343 pagefault_out_of_memory(); 344 return; 345 346do_sigbus: 347 up_read(&mm->mmap_sem); 348 monitor_signal(regs); 349 350 /* 351 * Send a sigbus, regardless of whether we were in kernel 352 * or user mode. 353 */ 354 info.si_signo = SIGBUS; 355 info.si_errno = 0; 356 info.si_code = BUS_ADRERR; 357 info.si_addr = (void *)address; 358 force_sig_info(SIGBUS, &info, tsk); 359 360 /* Kernel mode? Handle exceptions or die */ 361 if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_SR) 362 goto no_context; 363 return; 364 365vmalloc_fault: 366 { 367 /* 368 * Synchronize this task's top level page-table 369 * with the 'reference' page table. 370 * 371 * Do _not_ use "tsk" here. We might be inside 372 * an interrupt in the middle of a task switch.. 373 */ 374 int index = pgd_index(address); 375 pgd_t *pgd, *pgd_k; 376 pud_t *pud, *pud_k; 377 pmd_t *pmd, *pmd_k; 378 pte_t *pte_k; 379 380 pgd_k = init_mm.pgd + index; 381 382 if (!pgd_present(*pgd_k)) 383 goto no_context; 384 385 pud_k = pud_offset(pgd_k, address); 386 if (!pud_present(*pud_k)) 387 goto no_context; 388 389 pmd_k = pmd_offset(pud_k, address); 390 if (!pmd_present(*pmd_k)) 391 goto no_context; 392 393 pgd = (pgd_t *) PTBR + index; 394 pud = pud_offset(pgd, address); 395 pmd = pmd_offset(pud, address); 396 set_pmd(pmd, *pmd_k); 397 398 pte_k = pte_offset_kernel(pmd_k, address); 399 if (!pte_present(*pte_k)) 400 goto no_context; 401 return; 402 } 403} 404