1 /*
2 * linux/arch/m68k/mm/fault.c
3 *
4 * Copyright (C) 1995 Hamish Macdonald
5 */
6
7 #include <linux/mman.h>
8 #include <linux/mm.h>
9 #include <linux/kernel.h>
10 #include <linux/ptrace.h>
11
12 #include <asm/system.h>
13 #include <asm/pgtable.h>
14
15 extern void die_if_kernel(char *, struct pt_regs *, long);
16
17 /*
18 * This routine handles page faults. It determines the problem, and
19 * then passes it off to one of the appropriate routines.
20 *
21 * error_code:
22 * bit 0 == 0 means no page found, 1 means protection fault
23 * bit 1 == 0 means read, 1 means write
24 *
25 * If this routine detects a bad access, it returns 1, otherwise it
26 * returns 0.
27 */
28 asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
29 unsigned long error_code)
30 {
31 struct vm_area_struct * vma;
32
33 #ifdef DEBUG
34 printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
35 regs->sr, regs->pc, address, error_code,
36 current->tss.pagedir_v);
37 #endif
38
39 vma = find_vma(current, address);
40 if (!vma)
41 goto bad_area;
42 if (vma->vm_start <= address)
43 goto good_area;
44 if (!(vma->vm_flags & VM_GROWSDOWN))
45 goto bad_area;
46 if (user_mode(regs)) {
47 /* Accessing the stack below usp is always a bug. The
48 "+ 256" is there due to some instructions doing
49 pre-decrement on the stack and that doesn't show up
50 until later. */
51 if (address + 256 < rdusp())
52 goto bad_area;
53 }
54 if (expand_stack(vma, address))
55 goto bad_area;
56
57 /*
58 * Ok, we have a good vm_area for this memory access, so
59 * we can handle it..
60 */
61 good_area:
62 /*
63 * was it a write?
64 */
65 if (error_code & 2) {
66 if (!(vma->vm_flags & VM_WRITE))
67 goto bad_area;
68 } else {
69 /* read with protection fault? */
70 if (error_code & 1)
71 goto bad_area;
72 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
73 goto bad_area;
74 }
75 if (error_code & 1) {
76 do_wp_page(current, vma, address, error_code & 2);
77 return 0;
78 }
79 do_no_page(current, vma, address, error_code & 2);
80
81 /* There seems to be a missing invalidate somewhere in do_no_page.
82 * Until I found it, this one cures the problem and makes
83 * 1.2 run on the 68040 (Martin Apel).
84 */
85 flush_tlb_all();
86
87 return 0;
88
89 /*
90 * Something tried to access memory that isn't in our memory map..
91 * Fix it, but check if it's kernel or user first..
92 */
93 bad_area:
94 if (user_mode(regs)) {
95 /* User memory access */
96 force_sig (SIGSEGV, current);
97 return 1;
98 }
99
100 /*
101 * Oops. The kernel tried to access some bad page. We'll have to
102 * terminate things with extreme prejudice.
103 */
104 if ((unsigned long) address < PAGE_SIZE) {
105 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
106 } else
107 printk(KERN_ALERT "Unable to handle kernel access");
108 printk(" at virtual address %08lx\n",address);
109 die_if_kernel("Oops", regs, error_code);
110 do_exit(SIGKILL);
111
112 return 1;
113 }