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