This source file includes following definitions.
- do_page_fault
1
2
3
4
5
6
7
8 #include <linux/config.h>
9 #include <linux/signal.h>
10 #include <linux/sched.h>
11 #include <linux/head.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/types.h>
16 #include <linux/ptrace.h>
17 #include <linux/mman.h>
18 #include <linux/mm.h>
19
20 #include <asm/system.h>
21 #include <asm/segment.h>
22 #include <asm/mipsconfig.h>
23
24 extern void die_if_kernel(char *, struct pt_regs *, long);
25
26
27
28
29
30
31
32
33
34
35
36
37 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
38 {
39 struct vm_area_struct * vma;
40 unsigned long address;
41 unsigned long page;
42
43
44 __asm__("dmfc0\t%0,$8"
45 : "=r" (address));
46
47 for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
48 if (!vma)
49 goto bad_area;
50 if (vma->vm_end > address)
51 break;
52 }
53 if (vma->vm_start <= address)
54 goto good_area;
55 if (!(vma->vm_flags & VM_GROWSDOWN))
56 goto bad_area;
57 if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
58 goto bad_area;
59 vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
60 vma->vm_start = (address & PAGE_MASK);
61
62
63
64
65 good_area:
66
67
68
69 if (error_code & 2) {
70 if (!(vma->vm_flags & VM_WRITE))
71 goto bad_area;
72 } else {
73
74 if (error_code & 1)
75 goto bad_area;
76 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
77 goto bad_area;
78 }
79 if (error_code & 1) {
80 do_wp_page(vma, address, error_code & 2);
81 return;
82 }
83 do_no_page(vma, address, error_code & 2);
84 return;
85
86
87
88
89
90 bad_area:
91 if (user_mode(regs)) {
92 current->tss.cp0_badvaddr = address;
93 current->tss.error_code = error_code;
94 #if 0
95 current->tss.trap_no = 14;
96 #endif
97 send_sig(SIGSEGV, current, 1);
98 return;
99 }
100
101
102
103
104 if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) {
105 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
106 pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
107 } else
108 printk(KERN_ALERT "Unable to handle kernel paging request");
109 printk(" at virtual address %08lx\n",address);
110 page = current->tss.pg_dir;
111 printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page);
112 page = ((unsigned long *) page)[address >> PGDIR_SHIFT];
113 printk(KERN_ALERT "*pde = %08lx\n", page);
114 if (page & 1) {
115 page &= PAGE_MASK;
116 address &= 0x003ff000;
117 page = ((unsigned long *) page)[address >> PAGE_SHIFT];
118 printk(KERN_ALERT "*pte = %08lx\n", page);
119 }
120 die_if_kernel("Oops", regs, error_code);
121 do_exit(SIGKILL);
122 }