fault.c revision 126187f1e00048abec4d4a2eb3eeae396fbaa944
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 int writeaccess; 65623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen long signr; 66623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen int code; 675f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 689caebec7b8093574fca5a334a1939530872d75e3Christoph Hellwig if (notify_page_fault(regs, ecr)) 695f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 705f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 715f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen address = sysreg_read(TLBEAR); 725f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 735f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen tsk = current; 745f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen mm = tsk->mm; 755f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 76623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen signr = SIGSEGV; 77623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = SEGV_MAPERR; 78623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 795f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 805f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * If we're in an interrupt or have no user context, we must 815f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * not take the fault... 825f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 835f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM)) 845f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto no_context; 855f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 865f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen local_irq_enable(); 875f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 885f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen down_read(&mm->mmap_sem); 895f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 905f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen vma = find_vma(mm, address); 915f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!vma) 925f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 935f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (vma->vm_start <= address) 945f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto good_area; 955f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_GROWSDOWN)) 965f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 975f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (expand_stack(vma, address)) 985f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 995f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1005f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1015f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Ok, we have a good vm_area for this memory access, so we 1025f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * can handle it... 1035f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1045f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoengood_area: 105623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = SEGV_ACCERR; 106623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen writeaccess = 0; 107623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 1085f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen switch (ecr) { 1095f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_X: 1105f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_X: 1115f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_EXEC)) 1125f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1135f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1145f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_R: 1155f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_R: 1165f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) 1175f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1185f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1195f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_PROTECTION_W: 1205f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case ECR_TLB_MISS_W: 1215f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!(vma->vm_flags & VM_WRITE)) 1225f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto bad_area; 1235f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen writeaccess = 1; 1245f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1255f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen default: 1265f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen panic("Unhandled case %lu in do_page_fault!", ecr); 1275f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1285f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1295f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1305f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * If for any reason at all we couldn't handle the fault, make 1315f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * sure we exit gracefully rather than endlessly redo the 1325f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * fault. 1335f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1345f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoensurvive: 1355f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen switch (handle_mm_fault(mm, vma, address, writeaccess)) { 1365f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case VM_FAULT_MINOR: 1375f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen tsk->min_flt++; 1385f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1395f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case VM_FAULT_MAJOR: 1405f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen tsk->maj_flt++; 1415f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen break; 1425f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case VM_FAULT_SIGBUS: 1435f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto do_sigbus; 1445f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen case VM_FAULT_OOM: 1455f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto out_of_memory; 1465f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen default: 1475f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen BUG(); 1485f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1495f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1505f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 1515f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1525f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1535f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1545f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Something tried to access memory that isn't in our memory 1555f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * map. Fix it, but check if it's kernel or user first... 1565f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1575f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenbad_area: 1585f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 1595f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1605f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (user_mode(regs)) { 161126187f1e00048abec4d4a2eb3eeae396fbaa944Andrea Righi if (exception_trace && printk_ratelimit()) 162623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("%s%s[%d]: segfault at %08lx pc %08lx " 163623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen "sp %08lx ecr %lu\n", 164623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen is_init(tsk) ? KERN_EMERG : KERN_INFO, 165623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen tsk->comm, tsk->pid, address, regs->pc, 166623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen regs->sp, ecr); 167623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen _exception(SIGSEGV, regs, code, address); 1685f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1695f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1705f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1715f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenno_context: 1725f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* Are we prepared to handle this kernel fault? */ 1735f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen fixup = search_exception_tables(regs->pc); 1745f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (fixup) { 1755f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen regs->pc = fixup->fixup; 1765f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen return; 1775f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 1785f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1795f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 1805f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * Oops. The kernel tried to access some bad page. We'll have 1815f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * to terminate things with extreme prejudice. 1825f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 1835f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (address < PAGE_SIZE) 1845f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 1855f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Unable to handle kernel NULL pointer dereference"); 1865f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen else 1875f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 1885f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Unable to handle kernel paging request"); 1895f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(" at virtual address %08lx\n", address); 1905f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 1915f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = sysreg_read(PTBR); 1925f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT "ptbr = %08lx", page); 1935f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (page) { 1945f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = ((unsigned long *)page)[address >> 22]; 1955f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(" pgd = %08lx", page); 1965f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (page & _PAGE_PRESENT) { 1975f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page &= PAGE_MASK; 1985f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen address &= 0x003ff000; 1995f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT]; 200623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk(" pte = %08lx", page); 2015f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 2025f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 203623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("\n"); 204623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen die("Kernel access of bad area", regs, signr); 205623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen return; 2065f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2075f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* 2085f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * We ran out of memory, or some other thing happened to us 2095f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * that made us unable to handle the page fault gracefully. 2105f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 2115f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenout_of_memory: 2125f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 213623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen if (is_init(current)) { 2145f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen yield(); 2155f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen down_read(&mm->mmap_sem); 2165f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto survive; 2175f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen } 2185f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk("VM: Killing process %s\n", tsk->comm); 2195f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (user_mode(regs)) 2205f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen do_exit(SIGKILL); 2215f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto no_context; 2225f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2235f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoendo_sigbus: 2245f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen up_read(&mm->mmap_sem); 2255f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2265f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen /* Kernel mode? Handle exceptions or die */ 227623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen signr = SIGBUS; 228623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen code = BUS_ADRERR; 2295f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen if (!user_mode(regs)) 2305f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen goto no_context; 231623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 232623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen if (exception_trace) 233623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen printk("%s%s[%d]: bus error at %08lx pc %08lx " 234623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen "sp %08lx ecr %lu\n", 235623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen is_init(tsk) ? KERN_EMERG : KERN_INFO, 236623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen tsk->comm, tsk->pid, address, regs->pc, 237623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen regs->sp, ecr); 238623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen 239623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen _exception(SIGBUS, regs, BUS_ADRERR, address); 2405f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 2415f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2425f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenasmlinkage void do_bus_error(unsigned long addr, int write_access, 2435f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen struct pt_regs *regs) 2445f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 2455f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_ALERT 2465f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen "Bus error at physical address 0x%08lx (%s access)\n", 2475f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen addr, write_access ? "write" : "read"); 2485f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen printk(KERN_INFO "DTLB dump:\n"); 2495f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen dump_dtlb(); 250623b0355d5b1f9c6d05005b649a2f3a7b9fd7816Haavard Skinnemoen die("Bus Error", regs, SIGKILL); 2515f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 2525f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2535f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen/* 2545f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * This functionality is currently not possible to implement because 2555f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * we're using segmentation to ensure a fixed mapping of the kernel 2565f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * virtual address space. 2575f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * 2585f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * It would be possible to implement this, but it would require us to 2595f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * disable segmentation at startup and load the kernel mappings into 2605f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * the TLB like any other pages. There will be lots of trickery to 2615f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen * avoid recursive invocation of the TLB miss handler, though... 2625f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen */ 2635f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#ifdef CONFIG_DEBUG_PAGEALLOC 2645f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoenvoid kernel_map_pages(struct page *page, int numpages, int enable) 2655f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen{ 2665f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen 2675f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen} 2685f97f7f9400de47ae837170bb274e90ad3934386Haavard SkinnemoenEXPORT_SYMBOL(kernel_map_pages); 2695f97f7f9400de47ae837170bb274e90ad3934386Haavard Skinnemoen#endif 270