15f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen/* 25f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Copyright (C) 2004-2006 Atmel Corporation 35f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * 45f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Based on linux/arch/sh/mm/fault.c: 55f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Copyright (C) 1999 Niibe Yutaka 65f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * 75f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * This program is free software; you can redistribute it and/or modify 85f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * it under the terms of the GNU General Public License version 2 as 95f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * published by the Free Software Foundation. 105f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 115f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 125f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <linux/mm.h> 135f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <linux/module.h> 145f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <linux/pagemap.h> 151eeb66a1bb973534dc3d064920a5ca683823372eChristoph Hellwig#include <linux/kdebug.h> 169caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig#include <linux/kprobes.h> 179caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig 185f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <asm/mmu_context.h> 195f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <asm/sysreg.h> 205f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#include <asm/tlb.h> 21623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen#include <asm/uaccess.h> 225f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 235f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#ifdef CONFIG_KPROBES 249caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwigstatic inline int notify_page_fault(struct pt_regs *regs, int trap) 255f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 269caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig int ret = 0; 275f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 289caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig if (!user_mode(regs)) { 299caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig if (kprobe_running() && kprobe_fault_handler(regs, trap)) 309caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig ret = 1; 319caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig } 325f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 339caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig return ret; 345f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 355f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#else 369caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwigstatic inline int notify_page_fault(struct pt_regs *regs, int trap) 375f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 389caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig return 0; 395f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 405f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#endif 415f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 42623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoenint exception_trace = 1; 43623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 445f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen/* 455f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * This routine handles page faults. It determines the address and the 465f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * problem, and then passes it off to one of the appropriate routines. 475f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * 485f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * ecr is the Exception Cause Register. Possible values are: 495f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * 6: Protection fault (instruction access) 50623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen * 15: Protection fault (read access) 51623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen * 16: Protection fault (write access) 52623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen * 20: Page not found (instruction access) 53623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen * 24: Page not found (read access) 54623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen * 28: Page not found (write access) 555f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 565f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenasmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) 575f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 585f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen struct task_struct *tsk; 595f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen struct mm_struct *mm; 605f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen struct vm_area_struct *vma; 615f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen const struct exception_table_entry *fixup; 625f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen unsigned long address; 635f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen unsigned long page; 64623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen long signr; 65623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen int code; 6683c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin int fault; 67bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; 685f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 699caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig if (notify_page_fault(regs, ecr)) 705f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 715f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 725f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen address = sysreg_read(TLBEAR); 735f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 745f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen tsk = current; 755f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen mm = tsk->mm; 765f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 77623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen signr = SIGSEGV; 78623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = SEGV_MAPERR; 79623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 805f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 815f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * If we're in an interrupt or have no user context, we must 825f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * not take the fault... 835f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 845f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM)) 855f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto no_context; 865f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 875f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen local_irq_enable(); 885f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 89759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner if (user_mode(regs)) 90759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner flags |= FAULT_FLAG_USER; 91bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consulretry: 925f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen down_read(&mm->mmap_sem); 935f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 945f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen vma = find_vma(mm, address); 955f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!vma) 965f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 975f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (vma->vm_start <= address) 985f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto good_area; 995f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_GROWSDOWN)) 1005f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1015f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (expand_stack(vma, address)) 1025f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1035f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1045f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1055f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Ok, we have a good vm_area for this memory access, so we 1065f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * can handle it... 1075f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1085f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoengood_area: 109623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = SEGV_ACCERR; 110623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 1115f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen switch (ecr) { 1125f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_X: 1135f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_X: 1145f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_EXEC)) 1155f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1165f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1175f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_R: 1185f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_R: 1195f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) 1205f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1215f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1225f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_W: 1235f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_W: 1245f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_WRITE)) 1255f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 126bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul flags |= FAULT_FLAG_WRITE; 1275f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1285f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen default: 1295f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen panic("Unhandled case %lu in do_page_fault!", ecr); 1305f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1315f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1325f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1335f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * If for any reason at all we couldn't handle the fault, make 1345f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * sure we exit gracefully rather than endlessly redo the 1355f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * fault. 1365f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 137bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul fault = handle_mm_fault(mm, vma, address, flags); 138bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul 139bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) 140bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul return; 141bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul 14283c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin if (unlikely(fault & VM_FAULT_ERROR)) { 14383c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin if (fault & VM_FAULT_OOM) 14483c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin goto out_of_memory; 14583c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin else if (fault & VM_FAULT_SIGBUS) 14683c54070ee1a2d05c89793884bea1a03f2851ed4Nick Piggin goto do_sigbus; 1475f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen BUG(); 1485f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 149bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul 150bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul if (flags & FAULT_FLAG_ALLOW_RETRY) { 151bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul if (fault & VM_FAULT_MAJOR) 152bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul tsk->maj_flt++; 153bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul else 154bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul tsk->min_flt++; 155bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul if (fault & VM_FAULT_RETRY) { 156bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul flags &= ~FAULT_FLAG_ALLOW_RETRY; 15745cac65b0fcd287ebb877b141d40ba9bbe8e5da7Shaohua Li flags |= FAULT_FLAG_TRIED; 158bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul 159bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul /* 160bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul * No need to up_read(&mm->mmap_sem) as we would have 161bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul * already released it in __lock_page_or_retry() in 162bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul * mm/filemap.c. 163bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul */ 164bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul goto retry; 165bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul } 166bf7c27e9887af48952743753916f9cfbe900d0e9Kautuk Consul } 1675f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1685f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 1695f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1705f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1715f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1725f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Something tried to access memory that isn't in our memory 1735f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * map. Fix it, but check if it's kernel or user first... 1745f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1755f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenbad_area: 1765f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 1775f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1785f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (user_mode(regs)) { 179126187f1e00048abec4d4a2eb3eeae396fbaa944Andrea Righi if (exception_trace && printk_ratelimit()) 180623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("%s%s[%d]: segfault at %08lx pc %08lx " 181623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen "sp %08lx ecr %lu\n", 182b460cbc581a53cc088ceba80608021dd49c63c43Serge E. Hallyn is_global_init(tsk) ? KERN_EMERG : KERN_INFO, 183623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen tsk->comm, tsk->pid, address, regs->pc, 184623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen regs->sp, ecr); 185623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen _exception(SIGSEGV, regs, code, address); 1865f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1875f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1885f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1895f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenno_context: 1905f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* Are we prepared to handle this kernel fault? */ 1915f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen fixup = search_exception_tables(regs->pc); 1925f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (fixup) { 1935f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen regs->pc = fixup->fixup; 1945f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1955f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1965f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1975f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1985f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Oops. The kernel tried to access some bad page. We'll have 1995f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * to terminate things with extreme prejudice. 2005f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 2015f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (address < PAGE_SIZE) 2025f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 2035f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Unable to handle kernel NULL pointer dereference"); 2045f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen else 2055f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 2065f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Unable to handle kernel paging request"); 2075f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(" at virtual address %08lx\n", address); 2085f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2095f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = sysreg_read(PTBR); 2105f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT "ptbr = %08lx", page); 21132019828d9012e584017a824f84798248c0060ddHaavard Skinnemoen if (address >= TASK_SIZE) 21232019828d9012e584017a824f84798248c0060ddHaavard Skinnemoen page = (unsigned long)swapper_pg_dir; 2135f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (page) { 2145f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = ((unsigned long *)page)[address >> 22]; 2155f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(" pgd = %08lx", page); 2165f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (page & _PAGE_PRESENT) { 2175f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page &= PAGE_MASK; 2185f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen address &= 0x003ff000; 2195f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT]; 220623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk(" pte = %08lx", page); 2215f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 2225f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 223623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("\n"); 224623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen die("Kernel access of bad area", regs, signr); 225623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen return; 2265f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2275f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 2285f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * We ran out of memory, or some other thing happened to us 2295f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * that made us unable to handle the page fault gracefully. 2305f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 2315f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenout_of_memory: 2325f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 23367a8a20fe1eec43ebfa7f2b83e988dbdb4c16271Nick Piggin if (!user_mode(regs)) 23467a8a20fe1eec43ebfa7f2b83e988dbdb4c16271Nick Piggin goto no_context; 235871341023c771ad233620b7a1fb3d9c7031c4e5cJohannes Weiner pagefault_out_of_memory(); 23667a8a20fe1eec43ebfa7f2b83e988dbdb4c16271Nick Piggin return; 2375f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2385f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoendo_sigbus: 2395f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 2405f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2415f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* Kernel mode? Handle exceptions or die */ 242623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen signr = SIGBUS; 243623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = BUS_ADRERR; 2445f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!user_mode(regs)) 2455f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto no_context; 246623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 247623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen if (exception_trace) 248623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("%s%s[%d]: bus error at %08lx pc %08lx " 249623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen "sp %08lx ecr %lu\n", 250b460cbc581a53cc088ceba80608021dd49c63c43Serge E. Hallyn is_global_init(tsk) ? KERN_EMERG : KERN_INFO, 251623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen tsk->comm, tsk->pid, address, regs->pc, 252623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen regs->sp, ecr); 253623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 254623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen _exception(SIGBUS, regs, BUS_ADRERR, address); 2555f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 2565f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2575f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenasmlinkage void do_bus_error(unsigned long addr, int write_access, 2585f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen struct pt_regs *regs) 2595f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 2605f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 2615f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Bus error at physical address 0x%08lx (%s access)\n", 2625f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen addr, write_access ? "write" : "read"); 2635f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_INFO "DTLB dump:\n"); 2645f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen dump_dtlb(); 265623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen die("Bus Error", regs, SIGKILL); 2665f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 267