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