Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / arch / m68k / mm / fault.c
blob8dc87ebc1d1e86559a3bb30de18c984d944f4882
1 /*
2 * linux/arch/m68k/mm/fault.c
4 * Copyright (C) 1995 Hamish Macdonald
5 */
7 #include <linux/mman.h>
8 #include <linux/mm.h>
9 #include <linux/kernel.h>
10 #include <linux/ptrace.h>
11 #include <linux/interrupt.h>
13 #include <asm/setup.h>
14 #include <asm/traps.h>
15 #include <asm/system.h>
16 #include <asm/uaccess.h>
17 #include <asm/pgalloc.h>
19 extern void die_if_kernel(char *, struct pt_regs *, long);
20 extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
22 int send_fault_sig(struct pt_regs *regs)
24 siginfo_t siginfo = { 0, 0, 0, };
26 siginfo.si_signo = current->thread.signo;
27 siginfo.si_code = current->thread.code;
28 siginfo.si_addr = (void *)current->thread.faddr;
29 printk("send_fault_sig: %p,%d,%d\n", siginfo.si_addr, siginfo.si_signo, siginfo.si_code);
31 if (user_mode(regs)) {
32 force_sig_info(siginfo.si_signo,
33 &siginfo, current);
34 } else {
35 unsigned long fixup;
37 /* Are we prepared to handle this kernel fault? */
38 if ((fixup = search_exception_table(regs->pc))) {
39 struct pt_regs *tregs;
40 /* Create a new four word stack frame, discarding the old
41 one. */
42 regs->stkadj = frame_extra_sizes[regs->format];
43 tregs = (struct pt_regs *)((ulong)regs + regs->stkadj);
44 tregs->vector = regs->vector;
45 tregs->format = 0;
46 tregs->pc = fixup;
47 tregs->sr = regs->sr;
48 return -1;
51 //if (siginfo.si_signo == SIGBUS)
52 // force_sig_info(siginfo.si_signo,
53 // &siginfo, current);
56 * Oops. The kernel tried to access some bad page. We'll have to
57 * terminate things with extreme prejudice.
59 if ((unsigned long)siginfo.si_addr < PAGE_SIZE)
60 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
61 else
62 printk(KERN_ALERT "Unable to handle kernel access");
63 printk(" at virtual address %p\n", siginfo.si_addr);
64 die_if_kernel("Oops", regs, 0 /*error_code*/);
65 do_exit(SIGKILL);
68 return 1;
72 * This routine handles page faults. It determines the problem, and
73 * then passes it off to one of the appropriate routines.
75 * error_code:
76 * bit 0 == 0 means no page found, 1 means protection fault
77 * bit 1 == 0 means read, 1 means write
79 * If this routine detects a bad access, it returns 1, otherwise it
80 * returns 0.
82 int do_page_fault(struct pt_regs *regs, unsigned long address,
83 unsigned long error_code)
85 struct mm_struct *mm = current->mm;
86 struct vm_area_struct * vma;
87 int write, fault;
89 #ifdef DEBUG
90 printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
91 regs->sr, regs->pc, address, error_code,
92 current->mm->pgd);
93 #endif
96 * If we're in an interrupt or have no user
97 * context, we must not take the fault..
99 if (in_interrupt() || !mm)
100 goto no_context;
102 down(&mm->mmap_sem);
104 vma = find_vma(mm, address);
105 if (!vma)
106 goto map_err;
107 if (vma->vm_flags & VM_IO)
108 goto acc_err;
109 if (vma->vm_start <= address)
110 goto good_area;
111 if (!(vma->vm_flags & VM_GROWSDOWN))
112 goto map_err;
113 if (user_mode(regs)) {
114 /* Accessing the stack below usp is always a bug. The
115 "+ 256" is there due to some instructions doing
116 pre-decrement on the stack and that doesn't show up
117 until later. */
118 if (address + 256 < rdusp())
119 goto map_err;
121 if (expand_stack(vma, address))
122 goto map_err;
125 * Ok, we have a good vm_area for this memory access, so
126 * we can handle it..
128 good_area:
129 #ifdef DEBUG
130 printk("do_page_fault: good_area\n");
131 #endif
132 write = 0;
133 switch (error_code & 3) {
134 default: /* 3: write, present */
135 /* fall through */
136 case 2: /* write, not present */
137 if (!(vma->vm_flags & VM_WRITE))
138 goto acc_err;
139 write++;
140 break;
141 case 1: /* read, present */
142 goto acc_err;
143 case 0: /* read, not present */
144 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
145 goto acc_err;
149 * If for any reason at all we couldn't handle the fault,
150 * make sure we exit gracefully rather than endlessly redo
151 * the fault.
153 fault = handle_mm_fault(mm, vma, address, write);
154 #ifdef DEBUG
155 printk("handle_mm_fault returns %d\n",fault);
156 #endif
157 if (fault < 0)
158 goto out_of_memory;
159 if (!fault)
160 goto bus_err;
162 /* There seems to be a missing invalidate somewhere in do_no_page.
163 * Until I found it, this one cures the problem and makes
164 * 1.2 run on the 68040 (Martin Apel).
166 #warning should be obsolete now...
167 if (CPU_IS_040_OR_060)
168 flush_tlb_page(vma, address);
169 up(&mm->mmap_sem);
170 return 0;
173 * We ran out of memory, or some other thing happened to us that made
174 * us unable to handle the page fault gracefully.
176 out_of_memory:
177 printk("VM: killing process %s\n", current->comm);
178 if (user_mode(regs))
179 do_exit(SIGKILL);
181 no_context:
182 current->thread.signo = SIGBUS;
183 current->thread.faddr = address;
184 return send_fault_sig(regs);
186 bus_err:
187 current->thread.signo = SIGBUS;
188 current->thread.code = BUS_ADRERR;
189 current->thread.faddr = address;
190 goto send_sig;
192 map_err:
193 current->thread.signo = SIGSEGV;
194 current->thread.code = SEGV_MAPERR;
195 current->thread.faddr = address;
196 goto send_sig;
198 acc_err:
199 current->thread.signo = SIGSEGV;
200 current->thread.code = SEGV_ACCERR;
201 current->thread.faddr = address;
203 send_sig:
204 up(&mm->mmap_sem);
205 return send_fault_sig(regs);