blob: c6f5b51ec2c744b7ef941f8eaa2a36a2a673a3c3 [file] [log] [blame]
Paul Mundtc7179942007-08-01 16:19:49 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * arch/sh/mm/fault-nommu.c
3 *
Paul Mundtc7179942007-08-01 16:19:49 +09004 * Copyright (C) 2002 - 2007 Paul Mundt
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Based on linux/arch/sh/mm/fault.c:
7 * Copyright (C) 1999 Niibe Yutaka
8 *
9 * Released under the terms of the GNU GPL v2.0.
10 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/mm.h>
Paul Mundtc7179942007-08-01 16:19:49 +090013#include <linux/hardirq.h>
14#include <linux/kprobes.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <asm/system.h>
Paul Mundtc7179942007-08-01 16:19:49 +090016#include <asm/ptrace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <asm/kgdb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19/*
20 * This routine handles page faults. It determines the address,
21 * and the problem, and then passes it off to one of the appropriate
22 * routines.
23 */
Paul Mundtc7179942007-08-01 16:19:49 +090024asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
25 unsigned long writeaccess,
26 unsigned long address)
Linus Torvalds1da177e2005-04-16 15:20:36 -070027{
Paul Mundtc7179942007-08-01 16:19:49 +090028 trace_hardirqs_on();
29 local_irq_enable();
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#if defined(CONFIG_SH_KGDB)
32 if (kgdb_nofault && kgdb_bus_err_hook)
33 kgdb_bus_err_hook();
34#endif
35
36 /*
37 * Oops. The kernel tried to access some bad page. We'll have to
38 * terminate things with extreme prejudice.
39 *
40 */
41 if (address < PAGE_SIZE) {
42 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
43 } else {
44 printk(KERN_ALERT "Unable to handle kernel paging request");
45 }
46
47 printk(" at virtual address %08lx\n", address);
48 printk(KERN_ALERT "pc = %08lx\n", regs->pc);
49
50 die("Oops", regs, writeaccess);
51 do_exit(SIGKILL);
52}
53
Paul Mundtc7179942007-08-01 16:19:49 +090054asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
55 unsigned long writeaccess,
56 unsigned long address)
Linus Torvalds1da177e2005-04-16 15:20:36 -070057{
58#if defined(CONFIG_SH_KGDB)
59 if (kgdb_nofault && kgdb_bus_err_hook)
60 kgdb_bus_err_hook();
61#endif
62
Paul Mundtc7179942007-08-01 16:19:49 +090063 return (address >= TASK_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064}