patch-2.1.12 linux/arch/m68k/mm/fault.c
Next file: linux/arch/m68k/mm/init.c
Previous file: linux/arch/m68k/mm/extable.c
Back to the patch index
Back to the overall index
- Lines: 113
- Date:
Fri Nov 22 15:56:35 1996
- Orig file:
v2.1.11/linux/arch/m68k/mm/fault.c
- Orig date:
Wed Sep 25 10:47:40 1996
diff -u --recursive --new-file v2.1.11/linux/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c
@@ -9,10 +9,14 @@
#include <linux/kernel.h>
#include <linux/ptrace.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
#include <asm/system.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
extern void die_if_kernel(char *, struct pt_regs *, long);
+extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
/*
* This routine handles page faults. It determines the problem, and
@@ -28,14 +32,20 @@
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
- struct vm_area_struct * vma;
+ void (*handler)(struct task_struct *,
+ struct vm_area_struct *,
+ unsigned long,
+ int);
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
+ struct vm_area_struct * vma;
+ unsigned long fixup, fault_pc;
+ int write;
#ifdef DEBUG
printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
regs->sr, regs->pc, address, error_code,
- tsk->tss.pagedir_v);
+ tsk->mm->pgd);
#endif
down(&mm->mmap_sem);
@@ -62,25 +72,24 @@
* we can handle it..
*/
good_area:
- /*
- * was it a write?
- */
- if (error_code & 2) {
- if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
- } else {
- /* read with protection fault? */
- if (error_code & 1)
- goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto bad_area;
- }
- if (error_code & 1) {
- do_wp_page(tsk, vma, address, error_code & 2);
- up(&mm->mmap_sem);
- return 0;
+ write = 0;
+ handler = do_no_page;
+ switch (error_code & 3) {
+ default: /* 3: write, present */
+ handler = do_wp_page;
+ /* fall through */
+ case 2: /* write, not present */
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ write++;
+ break;
+ case 1: /* read, present */
+ goto bad_area;
+ case 0: /* read, not present */
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto bad_area;
}
- do_no_page(tsk, vma, address, error_code & 2);
+ handler(tsk, vma, address, write);
up(&mm->mmap_sem);
/* There seems to be a missing invalidate somewhere in do_no_page.
@@ -96,6 +105,26 @@
*/
bad_area:
up(&mm->mmap_sem);
+
+ /* Are we prepared to handle this fault? */
+ if (CPU_IS_060 && regs->format == 4)
+ fault_pc = ((struct frame *)regs)->un.fmt4.pc;
+ else
+ fault_pc = regs->pc;
+ if ((fixup = search_exception_table(fault_pc)) != 0) {
+ struct pt_regs *tregs;
+ printk("Exception at %lx (%lx)\n", fault_pc, fixup);
+ /* Create a new four word stack frame, discarding the old
+ one. */
+ regs->stkadj = frame_extra_sizes[regs->format];
+ tregs = (struct pt_regs *)((ulong)regs + regs->stkadj);
+ tregs->vector = regs->vector;
+ tregs->format = 0;
+ tregs->pc = fixup;
+ tregs->sr = regs->sr;
+ return -1;
+ }
+
if (user_mode(regs)) {
/* User memory access */
force_sig (SIGSEGV, tsk);
@@ -116,4 +145,3 @@
return 1;
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov