File: /usr/src/linux/arch/arm/mm/fault-armo.c

1     /*
2      *  linux/arch/arm/mm/fault-armo.c
3      *
4      *  Copyright (C) 1995  Linus Torvalds
5      *  Modifications for ARM processor (c) 1995-1999 Russell King
6      *
7      * This program is free software; you can redistribute it and/or modify
8      * it under the terms of the GNU General Public License version 2 as
9      * published by the Free Software Foundation.
10      */
11     #include <linux/signal.h>
12     #include <linux/sched.h>
13     #include <linux/kernel.h>
14     #include <linux/errno.h>
15     #include <linux/string.h>
16     #include <linux/types.h>
17     #include <linux/ptrace.h>
18     #include <linux/mman.h>
19     #include <linux/mm.h>
20     #include <linux/interrupt.h>
21     
22     #include <asm/system.h>
23     #include <asm/uaccess.h>
24     #include <asm/pgtable.h>
25     
26     #define FAULT_CODE_LDRSTRPOST	0x80
27     #define FAULT_CODE_LDRSTRPRE	0x40
28     #define FAULT_CODE_LDRSTRREG	0x20
29     #define FAULT_CODE_LDMSTM	0x10
30     #define FAULT_CODE_LDCSTC	0x08
31     #define FAULT_CODE_PREFETCH	0x04
32     #define FAULT_CODE_WRITE	0x02
33     #define FAULT_CODE_FORCECOW	0x01
34     
35     #define DO_COW(m)		((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
36     #define READ_FAULT(m)		(!((m) & FAULT_CODE_WRITE))
37     
38     extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs);
39     extern void show_pte(struct mm_struct *mm, unsigned long addr);
40     
41     /*
42      * Handle a data abort.  Note that we have to handle a range of addresses
43      * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
44      * a copy-on-write.  However, on the second page, we always force COW.
45      */
46     asmlinkage void
47     do_DataAbort(unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
48     {
49     	do_page_fault(min_addr, mode, regs);
50     
51     	if ((min_addr ^ max_addr) >> PAGE_SHIFT)
52     		do_page_fault(max_addr, mode | FAULT_CODE_FORCECOW, regs);
53     }
54     
55     asmlinkage int
56     do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
57     {
58     #if 0
59     	if (the memc mapping for this page exists) {
60     		printk ("Page in, but got abort (undefined instruction?)\n");
61     		return 0;
62     	}
63     #endif
64     	do_page_fault(addr, FAULT_CODE_PREFETCH, regs);
65     	return 1;
66     }
67