1/* $Id: fault.c,v 1.1.1.1 2007/08/03 18:52:18 Exp $ 2 * fault.c: Page fault handlers for the Sparc. 3 * 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 6 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 7 */ 8 9#include <asm/head.h> 10 11#include <linux/string.h> 12#include <linux/types.h> 13#include <linux/sched.h> 14#include <linux/ptrace.h> 15#include <linux/mman.h> 16#include <linux/threads.h> 17#include <linux/kernel.h> 18#include <linux/signal.h> 19#include <linux/mm.h> 20#include <linux/smp.h> 21#include <linux/interrupt.h> 22#include <linux/module.h> 23#include <linux/kdebug.h> 24 25#include <asm/system.h> 26#include <asm/page.h> 27#include <asm/pgtable.h> 28#include <asm/memreg.h> 29#include <asm/openprom.h> 30#include <asm/oplib.h> 31#include <asm/smp.h> 32#include <asm/traps.h> 33#include <asm/uaccess.h> 34 35extern int prom_node_root; 36 37/* At boot time we determine these two values necessary for setting 38 * up the segment maps and page table entries (pte's). 39 */ 40 41int num_segmaps, num_contexts; 42int invalid_segment; 43 44/* various Virtual Address Cache parameters we find at boot time... */ 45 46int vac_size, vac_linesize, vac_do_hw_vac_flushes; 47int vac_entries_per_context, vac_entries_per_segment; 48int vac_entries_per_page; 49 50/* Nice, simple, prom library does all the sweating for us. ;) */ 51int prom_probe_memory (void) 52{ 53 register struct linux_mlist_v0 *mlist; 54 register unsigned long bytes, base_paddr, tally; 55 register int i; 56 57 i = 0; 58 mlist= *prom_meminfo()->v0_available; 59 bytes = tally = mlist->num_bytes; 60 base_paddr = (unsigned long) mlist->start_adr; 61 62 sp_banks[0].base_addr = base_paddr; 63 sp_banks[0].num_bytes = bytes; 64 65 while (mlist->theres_more != (void *) 0){ 66 i++; 67 mlist = mlist->theres_more; 68 bytes = mlist->num_bytes; 69 tally += bytes; 70 if (i > SPARC_PHYS_BANKS-1) { 71 printk ("The machine has more banks than " 72 "this kernel can support\n" 73 "Increase the SPARC_PHYS_BANKS " 74 "setting (currently %d)\n", 75 SPARC_PHYS_BANKS); 76 i = SPARC_PHYS_BANKS-1; 77 break; 78 } 79 80 sp_banks[i].base_addr = (unsigned long) mlist->start_adr; 81 sp_banks[i].num_bytes = mlist->num_bytes; 82 } 83 84 i++; 85 sp_banks[i].base_addr = 0xdeadbeef; 86 sp_banks[i].num_bytes = 0; 87 88 /* Now mask all bank sizes on a page boundary, it is all we can 89 * use anyways. 90 */ 91 for(i=0; sp_banks[i].num_bytes != 0; i++) 92 sp_banks[i].num_bytes &= PAGE_MASK; 93 94 return tally; 95} 96 97/* Traverse the memory lists in the prom to see how much physical we 98 * have. 99 */ 100unsigned long 101probe_memory(void) 102{ 103 int total; 104 105 total = prom_probe_memory(); 106 107 /* Oh man, much nicer, keep the dirt in promlib. */ 108 return total; 109} 110 111extern void sun4c_complete_all_stores(void); 112 113/* Whee, a level 15 NMI interrupt memory error. Let's have fun... */ 114asmlinkage void sparc_lvl15_nmi(struct pt_regs *regs, unsigned long serr, 115 unsigned long svaddr, unsigned long aerr, 116 unsigned long avaddr) 117{ 118 sun4c_complete_all_stores(); 119 printk("FAULT: NMI received\n"); 120 printk("SREGS: Synchronous Error %08lx\n", serr); 121 printk(" Synchronous Vaddr %08lx\n", svaddr); 122 printk(" Asynchronous Error %08lx\n", aerr); 123 printk(" Asynchronous Vaddr %08lx\n", avaddr); 124 if (sun4c_memerr_reg) 125 printk(" Memory Parity Error %08lx\n", *sun4c_memerr_reg); 126 printk("REGISTER DUMP:\n"); 127 show_regs(regs); 128 prom_halt(); 129} 130 131static void unhandled_fault(unsigned long, struct task_struct *, 132 struct pt_regs *) __attribute__ ((noreturn)); 133 134static void unhandled_fault(unsigned long address, struct task_struct *tsk, 135 struct pt_regs *regs) 136{ 137 if((unsigned long) address < PAGE_SIZE) { 138 printk(KERN_ALERT 139 "Unable to handle kernel NULL pointer dereference\n"); 140 } else { 141 printk(KERN_ALERT "Unable to handle kernel paging request " 142 "at virtual address %08lx\n", address); 143 } 144 printk(KERN_ALERT "tsk->{mm,active_mm}->context = %08lx\n", 145 (tsk->mm ? tsk->mm->context : tsk->active_mm->context)); 146 printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %08lx\n", 147 (tsk->mm ? (unsigned long) tsk->mm->pgd : 148 (unsigned long) tsk->active_mm->pgd)); 149 die_if_kernel("Oops", regs); 150} 151 152asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, 153 unsigned long address) 154{ 155 struct pt_regs regs; 156 unsigned long g2; 157 unsigned int insn; 158 int i; 159 160 i = search_extables_range(ret_pc, &g2); 161 switch (i) { 162 case 3: 163 /* load & store will be handled by fixup */ 164 return 3; 165 166 case 1: 167 /* store will be handled by fixup, load will bump out */ 168 /* for _to_ macros */ 169 insn = *((unsigned int *) pc); 170 if ((insn >> 21) & 1) 171 return 1; 172 break; 173 174 case 2: 175 /* load will be handled by fixup, store will bump out */ 176 /* for _from_ macros */ 177 insn = *((unsigned int *) pc); 178 if (!((insn >> 21) & 1) || ((insn>>19)&0x3f) == 15) 179 return 2; 180 break; 181 182 default: 183 break; 184 }; 185 186 memset(®s, 0, sizeof (regs)); 187 regs.pc = pc; 188 regs.npc = pc + 4; 189 __asm__ __volatile__( 190 "rd %%psr, %0\n\t" 191 "nop\n\t" 192 "nop\n\t" 193 "nop\n" : "=r" (regs.psr)); 194 unhandled_fault(address, current, ®s); 195 196 /* Not reached */ 197 return 0; 198} 199 200extern unsigned long safe_compute_effective_address(struct pt_regs *, 201 unsigned int); 202 203static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) 204{ 205 unsigned int insn; 206 207 if (text_fault) 208 return regs->pc; 209 210 if (regs->psr & PSR_PS) { 211 insn = *(unsigned int *) regs->pc; 212 } else { 213 __get_user(insn, (unsigned int *) regs->pc); 214 } 215 216 return safe_compute_effective_address(regs, insn); 217} 218 219asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, 220 unsigned long address) 221{ 222 struct vm_area_struct *vma; 223 struct task_struct *tsk = current; 224 struct mm_struct *mm = tsk->mm; 225 unsigned int fixup; 226 unsigned long g2; 227 siginfo_t info; 228 int from_user = !(regs->psr & PSR_PS); 229 230 if(text_fault) 231 address = regs->pc; 232 233 /* 234 * We fault-in kernel-space virtual memory on-demand. The 235 * 'reference' page table is init_mm.pgd. 236 * 237 * NOTE! We MUST NOT take any locks for this case. We may 238 * be in an interrupt or a critical region, and should 239 * only copy the information from the master page table, 240 * nothing more. 241 */ 242 if (!ARCH_SUN4C_SUN4 && address >= TASK_SIZE) 243 goto vmalloc_fault; 244 245 info.si_code = SEGV_MAPERR; 246 247 /* 248 * If we're in an interrupt or have no user 249 * context, we must not take the fault.. 250 */ 251 if (in_atomic() || !mm) 252 goto no_context; 253 254 down_read(&mm->mmap_sem); 255 256 /* 257 * The kernel referencing a bad kernel pointer can lock up 258 * a sun4c machine completely, so we must attempt recovery. 259 */ 260 if(!from_user && address >= PAGE_OFFSET) 261 goto bad_area; 262 263 vma = find_vma(mm, address); 264 if(!vma) 265 goto bad_area; 266 if(vma->vm_start <= address) 267 goto good_area; 268 if(!(vma->vm_flags & VM_GROWSDOWN)) 269 goto bad_area; 270 if(expand_stack(vma, address)) 271 goto bad_area; 272 /* 273 * Ok, we have a good vm_area for this memory access, so 274 * we can handle it.. 275 */ 276good_area: 277 info.si_code = SEGV_ACCERR; 278 if(write) { 279 if(!(vma->vm_flags & VM_WRITE)) 280 goto bad_area; 281 } else { 282 /* Allow reads even for write-only mappings */ 283 if(!(vma->vm_flags & (VM_READ | VM_EXEC))) 284 goto bad_area; 285 } 286 287 /* 288 * If for any reason at all we couldn't handle the fault, 289 * make sure we exit gracefully rather than endlessly redo 290 * the fault. 291 */ 292 switch (handle_mm_fault(mm, vma, address, write)) { 293 case VM_FAULT_SIGBUS: 294 goto do_sigbus; 295 case VM_FAULT_OOM: 296 goto out_of_memory; 297 case VM_FAULT_MAJOR: 298 current->maj_flt++; 299 break; 300 case VM_FAULT_MINOR: 301 default: 302 current->min_flt++; 303 break; 304 } 305 up_read(&mm->mmap_sem); 306 return; 307 308 /* 309 * Something tried to access memory that isn't in our memory map.. 310 * Fix it, but check if it's kernel or user first.. 311 */ 312bad_area: 313 up_read(&mm->mmap_sem); 314 315bad_area_nosemaphore: 316 /* User mode accesses just cause a SIGSEGV */ 317 if(from_user) { 318 info.si_signo = SIGSEGV; 319 info.si_errno = 0; 320 /* info.si_code set above to make clear whether 321 this was a SEGV_MAPERR or SEGV_ACCERR fault. */ 322 info.si_addr = (void __user *)compute_si_addr(regs, text_fault); 323 info.si_trapno = 0; 324 force_sig_info (SIGSEGV, &info, tsk); 325 return; 326 } 327 328 /* Is this in ex_table? */ 329no_context: 330 g2 = regs->u_regs[UREG_G2]; 331 if (!from_user && (fixup = search_extables_range(regs->pc, &g2))) { 332 if (fixup > 10) { /* Values below are reserved for other things */ 333 extern const unsigned __memset_start[]; 334 extern const unsigned __memset_end[]; 335 extern const unsigned __csum_partial_copy_start[]; 336 extern const unsigned __csum_partial_copy_end[]; 337 338#ifdef DEBUG_EXCEPTIONS 339 printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address); 340 printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n", 341 regs->pc, fixup, g2); 342#endif 343 if ((regs->pc >= (unsigned long)__memset_start && 344 regs->pc < (unsigned long)__memset_end) || 345 (regs->pc >= (unsigned long)__csum_partial_copy_start && 346 regs->pc < (unsigned long)__csum_partial_copy_end)) { 347 regs->u_regs[UREG_I4] = address; 348 regs->u_regs[UREG_I5] = regs->pc; 349 } 350 regs->u_regs[UREG_G2] = g2; 351 regs->pc = fixup; 352 regs->npc = regs->pc + 4; 353 return; 354 } 355 } 356 357 unhandled_fault (address, tsk, regs); 358 do_exit(SIGKILL); 359 360/* 361 * We ran out of memory, or some other thing happened to us that made 362 * us unable to handle the page fault gracefully. 363 */ 364out_of_memory: 365 up_read(&mm->mmap_sem); 366 printk("VM: killing process %s\n", tsk->comm); 367 if (from_user) 368 do_exit(SIGKILL); 369 goto no_context; 370 371do_sigbus: 372 up_read(&mm->mmap_sem); 373 info.si_signo = SIGBUS; 374 info.si_errno = 0; 375 info.si_code = BUS_ADRERR; 376 info.si_addr = (void __user *) compute_si_addr(regs, text_fault); 377 info.si_trapno = 0; 378 force_sig_info (SIGBUS, &info, tsk); 379 if (!from_user) 380 goto no_context; 381 382vmalloc_fault: 383 { 384 /* 385 * Synchronize this task's top level page-table 386 * with the 'reference' page table. 387 */ 388 int offset = pgd_index(address); 389 pgd_t *pgd, *pgd_k; 390 pmd_t *pmd, *pmd_k; 391 392 pgd = tsk->active_mm->pgd + offset; 393 pgd_k = init_mm.pgd + offset; 394 395 if (!pgd_present(*pgd)) { 396 if (!pgd_present(*pgd_k)) 397 goto bad_area_nosemaphore; 398 pgd_val(*pgd) = pgd_val(*pgd_k); 399 return; 400 } 401 402 pmd = pmd_offset(pgd, address); 403 pmd_k = pmd_offset(pgd_k, address); 404 405 if (pmd_present(*pmd) || !pmd_present(*pmd_k)) 406 goto bad_area_nosemaphore; 407 *pmd = *pmd_k; 408 return; 409 } 410} 411 412asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, 413 unsigned long address) 414{ 415 extern void sun4c_update_mmu_cache(struct vm_area_struct *, 416 unsigned long,pte_t); 417 extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long); 418 struct task_struct *tsk = current; 419 struct mm_struct *mm = tsk->mm; 420 pgd_t *pgdp; 421 pte_t *ptep; 422 423 if (text_fault) { 424 address = regs->pc; 425 } else if (!write && 426 !(regs->psr & PSR_PS)) { 427 unsigned int insn, __user *ip; 428 429 ip = (unsigned int __user *)regs->pc; 430 if (!get_user(insn, ip)) { 431 if ((insn & 0xc1680000) == 0xc0680000) 432 write = 1; 433 } 434 } 435 436 if (!mm) { 437 /* We are oopsing. */ 438 do_sparc_fault(regs, text_fault, write, address); 439 BUG(); /* P3 Oops already, you bitch */ 440 } 441 442 pgdp = pgd_offset(mm, address); 443 ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address); 444 445 if (pgd_val(*pgdp)) { 446 if (write) { 447 if ((pte_val(*ptep) & (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) 448 == (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_PRESENT)) { 449 unsigned long flags; 450 451 *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | 452 _SUN4C_PAGE_MODIFIED | 453 _SUN4C_PAGE_VALID | 454 _SUN4C_PAGE_DIRTY); 455 456 local_irq_save(flags); 457 if (sun4c_get_segmap(address) != invalid_segment) { 458 sun4c_put_pte(address, pte_val(*ptep)); 459 local_irq_restore(flags); 460 return; 461 } 462 local_irq_restore(flags); 463 } 464 } else { 465 if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) 466 == (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) { 467 unsigned long flags; 468 469 *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | 470 _SUN4C_PAGE_VALID); 471 472 local_irq_save(flags); 473 if (sun4c_get_segmap(address) != invalid_segment) { 474 sun4c_put_pte(address, pte_val(*ptep)); 475 local_irq_restore(flags); 476 return; 477 } 478 local_irq_restore(flags); 479 } 480 } 481 } 482 483 /* This conditional is 'interesting'. */ 484 if (pgd_val(*pgdp) && !(write && !(pte_val(*ptep) & _SUN4C_PAGE_WRITE)) 485 && (pte_val(*ptep) & _SUN4C_PAGE_VALID)) 486 /* Note: It is safe to not grab the MMAP semaphore here because 487 * we know that update_mmu_cache() will not sleep for 488 * any reason (at least not in the current implementation) 489 * and therefore there is no danger of another thread getting 490 * on the CPU and doing a shrink_mmap() on this vma. 491 */ 492 sun4c_update_mmu_cache (find_vma(current->mm, address), address, 493 *ptep); 494 else 495 do_sparc_fault(regs, text_fault, write, address); 496} 497 498/* This always deals with user addresses. */ 499inline void force_user_fault(unsigned long address, int write) 500{ 501 struct vm_area_struct *vma; 502 struct task_struct *tsk = current; 503 struct mm_struct *mm = tsk->mm; 504 siginfo_t info; 505 506 info.si_code = SEGV_MAPERR; 507 508 down_read(&mm->mmap_sem); 509 vma = find_vma(mm, address); 510 if(!vma) 511 goto bad_area; 512 if(vma->vm_start <= address) 513 goto good_area; 514 if(!(vma->vm_flags & VM_GROWSDOWN)) 515 goto bad_area; 516 if(expand_stack(vma, address)) 517 goto bad_area; 518good_area: 519 info.si_code = SEGV_ACCERR; 520 if(write) { 521 if(!(vma->vm_flags & VM_WRITE)) 522 goto bad_area; 523 } else { 524 if(!(vma->vm_flags & (VM_READ | VM_EXEC))) 525 goto bad_area; 526 } 527 switch (handle_mm_fault(mm, vma, address, write)) { 528 case VM_FAULT_SIGBUS: 529 case VM_FAULT_OOM: 530 goto do_sigbus; 531 } 532 up_read(&mm->mmap_sem); 533 return; 534bad_area: 535 up_read(&mm->mmap_sem); 536 info.si_signo = SIGSEGV; 537 info.si_errno = 0; 538 /* info.si_code set above to make clear whether 539 this was a SEGV_MAPERR or SEGV_ACCERR fault. */ 540 info.si_addr = (void __user *) address; 541 info.si_trapno = 0; 542 force_sig_info (SIGSEGV, &info, tsk); 543 return; 544 545do_sigbus: 546 up_read(&mm->mmap_sem); 547 info.si_signo = SIGBUS; 548 info.si_errno = 0; 549 info.si_code = BUS_ADRERR; 550 info.si_addr = (void __user *) address; 551 info.si_trapno = 0; 552 force_sig_info (SIGBUS, &info, tsk); 553} 554 555void window_overflow_fault(void) 556{ 557 unsigned long sp; 558 559 sp = current_thread_info()->rwbuf_stkptrs[0]; 560 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 561 force_user_fault(sp + 0x38, 1); 562 force_user_fault(sp, 1); 563} 564 565void window_underflow_fault(unsigned long sp) 566{ 567 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 568 force_user_fault(sp + 0x38, 0); 569 force_user_fault(sp, 0); 570} 571 572void window_ret_fault(struct pt_regs *regs) 573{ 574 unsigned long sp; 575 576 sp = regs->u_regs[UREG_FP]; 577 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) 578 force_user_fault(sp + 0x38, 0); 579 force_user_fault(sp, 0); 580} 581