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