This source file includes following definitions.
- oom
- free_one_table
- clear_page_tables
- free_page_tables
- clone_page_tables
- copy_page_tables
- unmap_page_range
- zeromap_page_range
- remap_page_range
- put_page
- put_dirty_page
- __do_wp_page
- do_wp_page
- __verify_write
- verify_area
- get_empty_page
- try_to_share
- share_page
- get_empty_pgtable
- do_no_page
- do_page_fault
- __bad_pagetable
- __bad_page
- __zero_page
- show_mem
- paging_init
- mem_init
- si_meminfo
- file_mmap_nopage
- file_mmap_free
- file_mmap_share
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <asm/system.h>
37 #include <linux/config.h>
38
39 #include <linux/signal.h>
40 #include <linux/sched.h>
41 #include <linux/head.h>
42 #include <linux/kernel.h>
43 #include <linux/errno.h>
44 #include <linux/string.h>
45 #include <linux/types.h>
46 #include <linux/ptrace.h>
47 #include <linux/mman.h>
48
49
50
51
52
53
54 #undef CONFIG_TEST_VERIFY_AREA
55
56 unsigned long high_memory = 0;
57
58 extern unsigned long pg0[1024];
59
60 extern void sound_mem_init(void);
61 extern void die_if_kernel(char *,struct pt_regs *,long);
62 extern void show_net_buffers(void);
63
64
65
66
67
68 int nr_swap_pages = 0;
69 int nr_free_pages = 0;
70 struct mem_list free_area_list[NR_MEM_LISTS];
71 unsigned char * free_area_map[NR_MEM_LISTS];
72
73 #define copy_page(from,to) \
74 __asm__("cld ; rep ; movsl": :"S" (from),"D" (to),"c" (1024):"cx","di","si")
75
76 unsigned short * mem_map = NULL;
77
78 #define CODE_SPACE(addr,p) ((addr) < (p)->end_code)
79
80
81
82
83
84 void oom(struct task_struct * task)
85 {
86 printk("\nOut of memory.\n");
87 task->sigaction[SIGKILL-1].sa_handler = NULL;
88 task->blocked &= ~(1<<(SIGKILL-1));
89 send_sig(SIGKILL,task,1);
90 }
91
92 static void free_one_table(unsigned long * page_dir)
93 {
94 int j;
95 unsigned long pg_table = *page_dir;
96 unsigned long * page_table;
97
98 if (!pg_table)
99 return;
100 *page_dir = 0;
101 if (pg_table >= high_memory || !(pg_table & PAGE_PRESENT)) {
102 printk("Bad page table: [%p]=%08lx\n",page_dir,pg_table);
103 return;
104 }
105 if (mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)
106 return;
107 page_table = (unsigned long *) (pg_table & PAGE_MASK);
108 for (j = 0 ; j < PTRS_PER_PAGE ; j++,page_table++) {
109 unsigned long pg = *page_table;
110
111 if (!pg)
112 continue;
113 *page_table = 0;
114 if (pg & PAGE_PRESENT)
115 free_page(PAGE_MASK & pg);
116 else
117 swap_free(pg);
118 }
119 free_page(PAGE_MASK & pg_table);
120 }
121
122
123
124
125
126
127
128
129 void clear_page_tables(struct task_struct * tsk)
130 {
131 int i;
132 unsigned long pg_dir;
133 unsigned long * page_dir;
134
135 if (!tsk)
136 return;
137 if (tsk == task[0])
138 panic("task[0] (swapper) doesn't support exec()\n");
139 pg_dir = tsk->tss.cr3;
140 page_dir = (unsigned long *) pg_dir;
141 if (!page_dir || page_dir == swapper_pg_dir) {
142 printk("Trying to clear kernel page-directory: not good\n");
143 return;
144 }
145 if (mem_map[MAP_NR(pg_dir)] > 1) {
146 unsigned long * new_pg;
147
148 if (!(new_pg = (unsigned long*) get_free_page(GFP_KERNEL))) {
149 oom(tsk);
150 return;
151 }
152 for (i = 768 ; i < 1024 ; i++)
153 new_pg[i] = page_dir[i];
154 free_page(pg_dir);
155 tsk->tss.cr3 = (unsigned long) new_pg;
156 return;
157 }
158 for (i = 0 ; i < 768 ; i++,page_dir++)
159 free_one_table(page_dir);
160 invalidate();
161 return;
162 }
163
164
165
166
167 void free_page_tables(struct task_struct * tsk)
168 {
169 int i;
170 unsigned long pg_dir;
171 unsigned long * page_dir;
172
173 if (!tsk)
174 return;
175 if (tsk == task[0]) {
176 printk("task[0] (swapper) killed: unable to recover\n");
177 panic("Trying to free up swapper memory space");
178 }
179 pg_dir = tsk->tss.cr3;
180 if (!pg_dir || pg_dir == (unsigned long) swapper_pg_dir) {
181 printk("Trying to free kernel page-directory: not good\n");
182 return;
183 }
184 tsk->tss.cr3 = (unsigned long) swapper_pg_dir;
185 if (tsk == current)
186 __asm__ __volatile__("movl %0,%%cr3": :"a" (tsk->tss.cr3));
187 if (mem_map[MAP_NR(pg_dir)] > 1) {
188 free_page(pg_dir);
189 return;
190 }
191 page_dir = (unsigned long *) pg_dir;
192 for (i = 0 ; i < PTRS_PER_PAGE ; i++,page_dir++)
193 free_one_table(page_dir);
194 free_page(pg_dir);
195 invalidate();
196 }
197
198
199
200
201
202
203
204 int clone_page_tables(struct task_struct * tsk)
205 {
206 unsigned long pg_dir;
207
208 pg_dir = current->tss.cr3;
209 mem_map[MAP_NR(pg_dir)]++;
210 tsk->tss.cr3 = pg_dir;
211 return 0;
212 }
213
214
215
216
217
218
219 int copy_page_tables(struct task_struct * tsk)
220 {
221 int i;
222 unsigned long old_pg_dir, *old_page_dir;
223 unsigned long new_pg_dir, *new_page_dir;
224
225 if (!(new_pg_dir = get_free_page(GFP_KERNEL)))
226 return -ENOMEM;
227 old_pg_dir = current->tss.cr3;
228 tsk->tss.cr3 = new_pg_dir;
229 old_page_dir = (unsigned long *) old_pg_dir;
230 new_page_dir = (unsigned long *) new_pg_dir;
231 for (i = 0 ; i < PTRS_PER_PAGE ; i++,old_page_dir++,new_page_dir++) {
232 int j;
233 unsigned long old_pg_table, *old_page_table;
234 unsigned long new_pg_table, *new_page_table;
235
236 old_pg_table = *old_page_dir;
237 if (!old_pg_table)
238 continue;
239 if (old_pg_table >= high_memory || !(old_pg_table & PAGE_PRESENT)) {
240 printk("copy_page_tables: bad page table: "
241 "probable memory corruption");
242 *old_page_dir = 0;
243 continue;
244 }
245 if (mem_map[MAP_NR(old_pg_table)] & MAP_PAGE_RESERVED) {
246 *new_page_dir = old_pg_table;
247 continue;
248 }
249 if (!(new_pg_table = get_free_page(GFP_KERNEL))) {
250 free_page_tables(tsk);
251 return -ENOMEM;
252 }
253 old_page_table = (unsigned long *) (PAGE_MASK & old_pg_table);
254 new_page_table = (unsigned long *) (PAGE_MASK & new_pg_table);
255 for (j = 0 ; j < PTRS_PER_PAGE ; j++,old_page_table++,new_page_table++) {
256 unsigned long pg;
257 pg = *old_page_table;
258 if (!pg)
259 continue;
260 if (!(pg & PAGE_PRESENT)) {
261 *new_page_table = swap_duplicate(pg);
262 continue;
263 }
264 if ((pg & (PAGE_RW | PAGE_COW)) == (PAGE_RW | PAGE_COW))
265 pg &= ~PAGE_RW;
266 *new_page_table = pg;
267 if (mem_map[MAP_NR(pg)] & MAP_PAGE_RESERVED)
268 continue;
269 *old_page_table = pg;
270 mem_map[MAP_NR(pg)]++;
271 }
272 *new_page_dir = new_pg_table | PAGE_TABLE;
273 }
274 invalidate();
275 return 0;
276 }
277
278
279
280
281
282 int unmap_page_range(unsigned long from, unsigned long size)
283 {
284 unsigned long page, page_dir;
285 unsigned long *page_table, *dir;
286 unsigned long poff, pcnt, pc;
287
288 if (from & ~PAGE_MASK) {
289 printk("unmap_page_range called with wrong alignment\n");
290 return -EINVAL;
291 }
292 size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
293 dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
294 poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
295 if ((pcnt = PTRS_PER_PAGE - poff) > size)
296 pcnt = size;
297
298 for ( ; size > 0; ++dir, size -= pcnt,
299 pcnt = (size > PTRS_PER_PAGE ? PTRS_PER_PAGE : size)) {
300 if (!(page_dir = *dir)) {
301 poff = 0;
302 continue;
303 }
304 if (!(page_dir & PAGE_PRESENT)) {
305 printk("unmap_page_range: bad page directory.");
306 continue;
307 }
308 page_table = (unsigned long *)(PAGE_MASK & page_dir);
309 if (poff) {
310 page_table += poff;
311 poff = 0;
312 }
313 for (pc = pcnt; pc--; page_table++) {
314 if ((page = *page_table) != 0) {
315 *page_table = 0;
316 if (1 & page) {
317 if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
318 if (current->mm->rss > 0)
319 --current->mm->rss;
320 free_page(PAGE_MASK & page);
321 } else
322 swap_free(page);
323 }
324 }
325 if (pcnt == PTRS_PER_PAGE) {
326 *dir = 0;
327 free_page(PAGE_MASK & page_dir);
328 }
329 }
330 invalidate();
331 return 0;
332 }
333
334 int zeromap_page_range(unsigned long from, unsigned long size, int mask)
335 {
336 unsigned long *page_table, *dir;
337 unsigned long poff, pcnt;
338 unsigned long page;
339
340 if (mask) {
341 if ((mask & (PAGE_MASK|PAGE_PRESENT)) != PAGE_PRESENT) {
342 printk("zeromap_page_range: mask = %08x\n",mask);
343 return -EINVAL;
344 }
345 mask |= ZERO_PAGE;
346 }
347 if (from & ~PAGE_MASK) {
348 printk("zeromap_page_range: from = %08lx\n",from);
349 return -EINVAL;
350 }
351 dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
352 size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
353 poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
354 if ((pcnt = PTRS_PER_PAGE - poff) > size)
355 pcnt = size;
356
357 while (size > 0) {
358 if (!(PAGE_PRESENT & *dir)) {
359
360 if (!(page_table = (unsigned long*) get_free_page(GFP_KERNEL))) {
361 invalidate();
362 return -ENOMEM;
363 }
364 if (PAGE_PRESENT & *dir) {
365 free_page((unsigned long) page_table);
366 page_table = (unsigned long *)(PAGE_MASK & *dir++);
367 } else
368 *dir++ = ((unsigned long) page_table) | PAGE_TABLE;
369 } else
370 page_table = (unsigned long *)(PAGE_MASK & *dir++);
371 page_table += poff;
372 poff = 0;
373 for (size -= pcnt; pcnt-- ;) {
374 if ((page = *page_table) != 0) {
375 *page_table = 0;
376 if (page & PAGE_PRESENT) {
377 if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
378 if (current->mm->rss > 0)
379 --current->mm->rss;
380 free_page(PAGE_MASK & page);
381 } else
382 swap_free(page);
383 }
384 *page_table++ = mask;
385 }
386 pcnt = (size > PTRS_PER_PAGE ? PTRS_PER_PAGE : size);
387 }
388 invalidate();
389 return 0;
390 }
391
392
393
394
395
396
397 int remap_page_range(unsigned long from, unsigned long to, unsigned long size, int mask)
398 {
399 unsigned long *page_table, *dir;
400 unsigned long poff, pcnt;
401 unsigned long page;
402
403 if (mask) {
404 if ((mask & (PAGE_MASK|PAGE_PRESENT)) != PAGE_PRESENT) {
405 printk("remap_page_range: mask = %08x\n",mask);
406 return -EINVAL;
407 }
408 }
409 if ((from & ~PAGE_MASK) || (to & ~PAGE_MASK)) {
410 printk("remap_page_range: from = %08lx, to=%08lx\n",from,to);
411 return -EINVAL;
412 }
413 dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
414 size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
415 poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
416 if ((pcnt = PTRS_PER_PAGE - poff) > size)
417 pcnt = size;
418
419 while (size > 0) {
420 if (!(PAGE_PRESENT & *dir)) {
421
422 if (!(page_table = (unsigned long*) get_free_page(GFP_KERNEL))) {
423 invalidate();
424 return -1;
425 }
426 *dir++ = ((unsigned long) page_table) | PAGE_TABLE;
427 }
428 else
429 page_table = (unsigned long *)(PAGE_MASK & *dir++);
430 if (poff) {
431 page_table += poff;
432 poff = 0;
433 }
434
435 for (size -= pcnt; pcnt-- ;) {
436 if ((page = *page_table) != 0) {
437 *page_table = 0;
438 if (PAGE_PRESENT & page) {
439 if (!(mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED))
440 if (current->mm->rss > 0)
441 --current->mm->rss;
442 free_page(PAGE_MASK & page);
443 } else
444 swap_free(page);
445 }
446
447
448
449
450
451
452
453 if (!mask)
454 *page_table++ = 0;
455 else if (to >= high_memory)
456 *page_table++ = (to | mask);
457 else if (!mem_map[MAP_NR(to)])
458 *page_table++ = 0;
459 else {
460 *page_table++ = (to | mask);
461 if (!(mem_map[MAP_NR(to)] & MAP_PAGE_RESERVED)) {
462 ++current->mm->rss;
463 mem_map[MAP_NR(to)]++;
464 }
465 }
466 to += PAGE_SIZE;
467 }
468 pcnt = (size > PTRS_PER_PAGE ? PTRS_PER_PAGE : size);
469 }
470 invalidate();
471 return 0;
472 }
473
474
475
476
477
478
479
480 unsigned long put_page(struct task_struct * tsk,unsigned long page,
481 unsigned long address,int prot)
482 {
483 unsigned long *page_table;
484
485 if ((prot & (PAGE_MASK|PAGE_PRESENT)) != PAGE_PRESENT)
486 printk("put_page: prot = %08x\n",prot);
487 if (page >= high_memory) {
488 printk("put_page: trying to put page %08lx at %08lx\n",page,address);
489 return 0;
490 }
491 page_table = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
492 if ((*page_table) & PAGE_PRESENT)
493 page_table = (unsigned long *) (PAGE_MASK & *page_table);
494 else {
495 printk("put_page: bad page directory entry\n");
496 oom(tsk);
497 *page_table = BAD_PAGETABLE | PAGE_TABLE;
498 return 0;
499 }
500 page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
501 if (*page_table) {
502 printk("put_page: page already exists\n");
503 *page_table = 0;
504 invalidate();
505 }
506 *page_table = page | prot;
507
508 return page;
509 }
510
511
512
513
514
515
516
517 unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsigned long address)
518 {
519 unsigned long tmp, *page_table;
520
521 if (page >= high_memory)
522 printk("put_dirty_page: trying to put page %08lx at %08lx\n",page,address);
523 if (mem_map[MAP_NR(page)] != 1)
524 printk("mem_map disagrees with %08lx at %08lx\n",page,address);
525 page_table = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
526 if (PAGE_PRESENT & *page_table)
527 page_table = (unsigned long *) (PAGE_MASK & *page_table);
528 else {
529 if (!(tmp = get_free_page(GFP_KERNEL)))
530 return 0;
531 if (PAGE_PRESENT & *page_table) {
532 free_page(tmp);
533 page_table = (unsigned long *) (PAGE_MASK & *page_table);
534 } else {
535 *page_table = tmp | PAGE_TABLE;
536 page_table = (unsigned long *) tmp;
537 }
538 }
539 page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
540 if (*page_table) {
541 printk("put_dirty_page: page already exists\n");
542 *page_table = 0;
543 invalidate();
544 }
545 *page_table = page | (PAGE_DIRTY | PAGE_PRIVATE);
546
547 return page;
548 }
549
550
551
552
553
554
555
556
557
558
559
560
561 static void __do_wp_page(unsigned long error_code, unsigned long address,
562 struct task_struct * tsk, unsigned long user_esp)
563 {
564 unsigned long *pde, pte, old_page, prot;
565 unsigned long new_page;
566
567 new_page = __get_free_page(GFP_KERNEL);
568 pde = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
569 pte = *pde;
570 if (!(pte & PAGE_PRESENT))
571 goto end_wp_page;
572 if ((pte & PAGE_TABLE) != PAGE_TABLE || pte >= high_memory)
573 goto bad_wp_pagetable;
574 pte &= PAGE_MASK;
575 pte += PAGE_PTR(address);
576 old_page = *(unsigned long *) pte;
577 if (!(old_page & PAGE_PRESENT))
578 goto end_wp_page;
579 if (old_page >= high_memory)
580 goto bad_wp_page;
581 if (old_page & PAGE_RW)
582 goto end_wp_page;
583 tsk->mm->min_flt++;
584 prot = (old_page & ~PAGE_MASK) | PAGE_RW;
585 old_page &= PAGE_MASK;
586 if (mem_map[MAP_NR(old_page)] != 1) {
587 if (new_page) {
588 if (mem_map[MAP_NR(old_page)] & MAP_PAGE_RESERVED)
589 ++tsk->mm->rss;
590 copy_page(old_page,new_page);
591 *(unsigned long *) pte = new_page | prot;
592 free_page(old_page);
593 invalidate();
594 return;
595 }
596 free_page(old_page);
597 oom(tsk);
598 *(unsigned long *) pte = BAD_PAGE | prot;
599 invalidate();
600 return;
601 }
602 *(unsigned long *) pte |= PAGE_RW;
603 invalidate();
604 if (new_page)
605 free_page(new_page);
606 return;
607 bad_wp_page:
608 printk("do_wp_page: bogus page at address %08lx (%08lx)\n",address,old_page);
609 *(unsigned long *) pte = BAD_PAGE | PAGE_SHARED;
610 send_sig(SIGKILL, tsk, 1);
611 goto end_wp_page;
612 bad_wp_pagetable:
613 printk("do_wp_page: bogus page-table at address %08lx (%08lx)\n",address,pte);
614 *pde = BAD_PAGETABLE | PAGE_TABLE;
615 send_sig(SIGKILL, tsk, 1);
616 end_wp_page:
617 if (new_page)
618 free_page(new_page);
619 return;
620 }
621
622
623
624
625
626 void do_wp_page(unsigned long error_code, unsigned long address,
627 struct task_struct * tsk, unsigned long user_esp)
628 {
629 unsigned long page;
630 unsigned long * pg_table;
631
632 pg_table = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
633 page = *pg_table;
634 if (!page)
635 return;
636 if ((page & PAGE_PRESENT) && page < high_memory) {
637 pg_table = (unsigned long *) ((page & PAGE_MASK) + PAGE_PTR(address));
638 page = *pg_table;
639 if (!(page & PAGE_PRESENT))
640 return;
641 if (page & PAGE_RW)
642 return;
643 if (!(page & PAGE_COW)) {
644 if (user_esp && tsk == current) {
645 current->tss.cr2 = address;
646 current->tss.error_code = error_code;
647 current->tss.trap_no = 14;
648 send_sig(SIGSEGV, tsk, 1);
649 return;
650 }
651 }
652 if (mem_map[MAP_NR(page)] == 1) {
653 *pg_table |= PAGE_RW | PAGE_DIRTY;
654 invalidate();
655 return;
656 }
657 __do_wp_page(error_code, address, tsk, user_esp);
658 return;
659 }
660 printk("bad page directory entry %08lx\n",page);
661 *pg_table = 0;
662 }
663
664 static int __verify_write(unsigned long start, unsigned long size)
665 {
666 size--;
667 size += start & ~PAGE_MASK;
668 size >>= PAGE_SHIFT;
669 start &= PAGE_MASK;
670 do {
671 do_wp_page(1,start,current,0);
672 start += PAGE_SIZE;
673 } while (size--);
674 return 0;
675 }
676
677 int verify_area(int type, const void * addr, unsigned long size)
678 {
679 struct vm_area_struct * vma;
680
681 for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
682 if (!vma)
683 goto bad_area;
684 if (vma->vm_end > (unsigned long) addr)
685 break;
686 }
687 if (vma->vm_start <= (unsigned long) addr)
688 goto good_area;
689 if (!(vma->vm_flags & VM_GROWSDOWN))
690 goto bad_area;
691 if (vma->vm_end - (unsigned long) addr > current->rlim[RLIMIT_STACK].rlim_cur)
692 goto bad_area;
693 good_area:
694 while (vma->vm_end - (unsigned long) addr < size) {
695 struct vm_area_struct * next = vma->vm_next;
696 if (!next)
697 goto bad_area;
698 if (vma->vm_end != next->vm_start)
699 goto bad_area;
700 vma = next;
701 }
702 if (wp_works_ok || type == VERIFY_READ || !size)
703 return 0;
704 return __verify_write((unsigned long) addr,size);
705 bad_area:
706 return -EFAULT;
707 }
708
709 static inline void get_empty_page(struct task_struct * tsk, unsigned long address)
710 {
711 unsigned long tmp;
712
713 if (!(tmp = get_free_page(GFP_KERNEL))) {
714 oom(tsk);
715 tmp = BAD_PAGE;
716 }
717 if (!put_page(tsk,tmp,address,PAGE_PRIVATE))
718 free_page(tmp);
719 }
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735 static int try_to_share(unsigned long address, struct task_struct * tsk,
736 struct task_struct * p, unsigned long error_code, unsigned long newpage)
737 {
738 unsigned long from;
739 unsigned long to;
740 unsigned long from_page;
741 unsigned long to_page;
742
743 from_page = (unsigned long)PAGE_DIR_OFFSET(p->tss.cr3,address);
744 to_page = (unsigned long)PAGE_DIR_OFFSET(tsk->tss.cr3,address);
745
746 from = *(unsigned long *) from_page;
747 if (!(from & PAGE_PRESENT))
748 return 0;
749 from &= PAGE_MASK;
750 from_page = from + PAGE_PTR(address);
751 from = *(unsigned long *) from_page;
752
753 if ((from & (PAGE_PRESENT | PAGE_DIRTY)) != PAGE_PRESENT)
754 return 0;
755 if (from >= high_memory)
756 return 0;
757 if (mem_map[MAP_NR(from)] & MAP_PAGE_RESERVED)
758 return 0;
759
760 to = *(unsigned long *) to_page;
761 if (!(to & PAGE_PRESENT))
762 return 0;
763 to &= PAGE_MASK;
764 to_page = to + PAGE_PTR(address);
765 if (*(unsigned long *) to_page)
766 return 0;
767
768 if (error_code & PAGE_RW) {
769 if(!newpage)
770 return 0;
771 copy_page((from & PAGE_MASK),newpage);
772 to = newpage | PAGE_PRIVATE;
773 } else {
774 mem_map[MAP_NR(from)]++;
775 from &= ~PAGE_RW;
776 to = from;
777 if(newpage)
778 free_page(newpage);
779 }
780 *(unsigned long *) from_page = from;
781 *(unsigned long *) to_page = to;
782 invalidate();
783 return 1;
784 }
785
786
787
788
789
790
791
792
793
794 int share_page(struct vm_area_struct * area, struct task_struct * tsk,
795 struct inode * inode,
796 unsigned long address, unsigned long error_code, unsigned long newpage)
797 {
798 struct task_struct ** p;
799
800 if (!inode || inode->i_count < 2 || !area->vm_ops)
801 return 0;
802 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
803 if (!*p)
804 continue;
805 if (tsk == *p)
806 continue;
807 if (inode != (*p)->executable) {
808 if(!area) continue;
809
810
811 if(area){
812 struct vm_area_struct * mpnt;
813 for (mpnt = (*p)->mm->mmap; mpnt; mpnt = mpnt->vm_next) {
814 if (mpnt->vm_ops == area->vm_ops &&
815 mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
816 mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
817 if (mpnt->vm_ops->share(mpnt, area, address))
818 break;
819 };
820 };
821 if (!mpnt) continue;
822 };
823 }
824 if (try_to_share(address,tsk,*p,error_code,newpage))
825 return 1;
826 }
827 return 0;
828 }
829
830
831
832
833 static inline unsigned long get_empty_pgtable(struct task_struct * tsk,unsigned long address)
834 {
835 unsigned long page;
836 unsigned long *p;
837
838 p = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
839 if (PAGE_PRESENT & *p)
840 return *p;
841 if (*p) {
842 printk("get_empty_pgtable: bad page-directory entry \n");
843 *p = 0;
844 }
845 page = get_free_page(GFP_KERNEL);
846 p = PAGE_DIR_OFFSET(tsk->tss.cr3,address);
847 if (PAGE_PRESENT & *p) {
848 free_page(page);
849 return *p;
850 }
851 if (*p) {
852 printk("get_empty_pgtable: bad page-directory entry \n");
853 *p = 0;
854 }
855 if (page) {
856 *p = page | PAGE_TABLE;
857 return *p;
858 }
859 oom(current);
860 *p = BAD_PAGETABLE | PAGE_TABLE;
861 return 0;
862 }
863
864 void do_no_page(unsigned long error_code, unsigned long address,
865 struct task_struct *tsk, unsigned long user_esp)
866 {
867 unsigned long tmp;
868 unsigned long page;
869 struct vm_area_struct * mpnt;
870
871 page = get_empty_pgtable(tsk,address);
872 if (!page)
873 return;
874 page &= PAGE_MASK;
875 page += PAGE_PTR(address);
876 tmp = *(unsigned long *) page;
877 if (tmp & PAGE_PRESENT)
878 return;
879 if (tmp) {
880 ++tsk->mm->rss;
881 ++tsk->mm->maj_flt;
882 swap_in((unsigned long *) page);
883 return;
884 }
885 address &= 0xfffff000;
886 tmp = 0;
887 for (mpnt = tsk->mm->mmap; mpnt != NULL; mpnt = mpnt->vm_next) {
888 if (address < mpnt->vm_start)
889 break;
890 if (address >= mpnt->vm_end) {
891 tmp = mpnt->vm_end;
892 continue;
893 }
894 if (!mpnt->vm_ops || !mpnt->vm_ops->nopage) {
895 ++tsk->mm->rss;
896 ++tsk->mm->min_flt;
897 get_empty_page(tsk,address);
898 return;
899 }
900 ++tsk->mm->rss;
901 mpnt->vm_ops->nopage(error_code, mpnt, address);
902 return;
903 }
904 if (tsk != current)
905 goto ok_no_page;
906 if (address >= tsk->mm->end_data && address < tsk->mm->brk)
907 goto ok_no_page;
908 if (mpnt && (mpnt->vm_flags & VM_GROWSDOWN) &&
909 address - tmp > mpnt->vm_start - address &&
910 tsk->rlim[RLIMIT_STACK].rlim_cur > mpnt->vm_end - address) {
911 mpnt->vm_start = address;
912 goto ok_no_page;
913 }
914 tsk->tss.cr2 = address;
915 current->tss.error_code = error_code;
916 current->tss.trap_no = 14;
917 send_sig(SIGSEGV,tsk,1);
918 if (error_code & 4)
919 return;
920 ok_no_page:
921 ++tsk->mm->rss;
922 ++tsk->mm->min_flt;
923 get_empty_page(tsk,address);
924 }
925
926
927
928
929
930
931 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
932 {
933 unsigned long address;
934 unsigned long user_esp = 0;
935 unsigned int bit;
936
937
938 __asm__("movl %%cr2,%0":"=r" (address));
939 if (address < TASK_SIZE) {
940 if (error_code & 4) {
941 if (regs->eflags & VM_MASK) {
942 bit = (address - 0xA0000) >> PAGE_SHIFT;
943 if (bit < 32)
944 current->screen_bitmap |= 1 << bit;
945 } else
946 user_esp = regs->esp;
947 }
948 if (error_code & PAGE_PRESENT) {
949 #ifdef CONFIG_TEST_VERIFY_AREA
950 if (regs->cs == KERNEL_CS)
951 printk("WP fault at %08x\n", regs->eip);
952 #endif
953 do_wp_page(error_code, address, current, user_esp);
954 } else {
955 do_no_page(error_code, address, current, user_esp);
956 }
957 return;
958 }
959 address -= TASK_SIZE;
960 if (wp_works_ok < 0 && address == 0 && (error_code & PAGE_PRESENT)) {
961 wp_works_ok = 1;
962 pg0[0] = PAGE_SHARED;
963 printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
964 return;
965 }
966 if (address < PAGE_SIZE) {
967 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
968 pg0[0] = PAGE_SHARED;
969 } else
970 printk(KERN_ALERT "Unable to handle kernel paging request");
971 printk(" at kernel address %08lx\n",address);
972 address += TASK_SIZE;
973 __asm__("movl %%cr3,%0" : "=r" (user_esp));
974 printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n",
975 current->tss.cr3, user_esp);
976 user_esp = ((unsigned long *) user_esp)[address >> 22];
977 printk(KERN_ALERT "*pde = %08lx\n", user_esp);
978 if (user_esp & PAGE_PRESENT) {
979 user_esp &= PAGE_MASK;
980 address &= 0x003ff000;
981 user_esp = ((unsigned long *) user_esp)[address >> PAGE_SHIFT];
982 printk(KERN_ALERT "*pte = %08lx\n", user_esp);
983 }
984 die_if_kernel("Oops", regs, error_code);
985 do_exit(SIGKILL);
986 }
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001 unsigned long __bad_pagetable(void)
1002 {
1003 extern char empty_bad_page_table[PAGE_SIZE];
1004
1005 __asm__ __volatile__("cld ; rep ; stosl":
1006 :"a" (BAD_PAGE + PAGE_TABLE),
1007 "D" ((long) empty_bad_page_table),
1008 "c" (PTRS_PER_PAGE)
1009 :"di","cx");
1010 return (unsigned long) empty_bad_page_table;
1011 }
1012
1013 unsigned long __bad_page(void)
1014 {
1015 extern char empty_bad_page[PAGE_SIZE];
1016
1017 __asm__ __volatile__("cld ; rep ; stosl":
1018 :"a" (0),
1019 "D" ((long) empty_bad_page),
1020 "c" (PTRS_PER_PAGE)
1021 :"di","cx");
1022 return (unsigned long) empty_bad_page;
1023 }
1024
1025 unsigned long __zero_page(void)
1026 {
1027 extern char empty_zero_page[PAGE_SIZE];
1028
1029 __asm__ __volatile__("cld ; rep ; stosl":
1030 :"a" (0),
1031 "D" ((long) empty_zero_page),
1032 "c" (PTRS_PER_PAGE)
1033 :"di","cx");
1034 return (unsigned long) empty_zero_page;
1035 }
1036
1037 void show_mem(void)
1038 {
1039 int i,free = 0,total = 0,reserved = 0;
1040 int shared = 0;
1041
1042 printk("Mem-info:\n");
1043 show_free_areas();
1044 printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
1045 i = high_memory >> PAGE_SHIFT;
1046 while (i-- > 0) {
1047 total++;
1048 if (mem_map[i] & MAP_PAGE_RESERVED)
1049 reserved++;
1050 else if (!mem_map[i])
1051 free++;
1052 else
1053 shared += mem_map[i]-1;
1054 }
1055 printk("%d pages of RAM\n",total);
1056 printk("%d free pages\n",free);
1057 printk("%d reserved pages\n",reserved);
1058 printk("%d pages shared\n",shared);
1059 show_buffers();
1060 show_net_buffers();
1061 }
1062
1063 extern unsigned long free_area_init(unsigned long, unsigned long);
1064
1065
1066
1067
1068
1069
1070
1071
1072 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
1073 {
1074 unsigned long * pg_dir;
1075 unsigned long * pg_table;
1076 unsigned long tmp;
1077 unsigned long address;
1078
1079
1080
1081
1082
1083
1084
1085 #if 0
1086 memset((void *) 0, 0, PAGE_SIZE);
1087 #endif
1088 start_mem = PAGE_ALIGN(start_mem);
1089 address = 0;
1090 pg_dir = swapper_pg_dir;
1091 while (address < end_mem) {
1092 tmp = *(pg_dir + 768);
1093 if (!tmp) {
1094 tmp = start_mem | PAGE_TABLE;
1095 *(pg_dir + 768) = tmp;
1096 start_mem += PAGE_SIZE;
1097 }
1098 *pg_dir = tmp;
1099 pg_dir++;
1100 pg_table = (unsigned long *) (tmp & PAGE_MASK);
1101 for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
1102 if (address < end_mem)
1103 *pg_table = address | PAGE_SHARED;
1104 else
1105 *pg_table = 0;
1106 address += PAGE_SIZE;
1107 }
1108 }
1109 invalidate();
1110 return free_area_init(start_mem, end_mem);
1111 }
1112
1113 void mem_init(unsigned long start_low_mem,
1114 unsigned long start_mem, unsigned long end_mem)
1115 {
1116 int codepages = 0;
1117 int reservedpages = 0;
1118 int datapages = 0;
1119 unsigned long tmp;
1120 extern int etext;
1121
1122 cli();
1123 end_mem &= PAGE_MASK;
1124 high_memory = end_mem;
1125
1126
1127 start_low_mem = PAGE_ALIGN(start_low_mem);
1128 start_mem = PAGE_ALIGN(start_mem);
1129
1130
1131
1132
1133
1134
1135 while (start_low_mem < 0x9f000) {
1136 mem_map[MAP_NR(start_low_mem)] = 0;
1137 start_low_mem += PAGE_SIZE;
1138 }
1139
1140 while (start_mem < high_memory) {
1141 mem_map[MAP_NR(start_mem)] = 0;
1142 start_mem += PAGE_SIZE;
1143 }
1144 #ifdef CONFIG_SOUND
1145 sound_mem_init();
1146 #endif
1147 for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
1148 if (mem_map[MAP_NR(tmp)]) {
1149 if (tmp >= 0xA0000 && tmp < 0x100000)
1150 reservedpages++;
1151 else if (tmp < (unsigned long) &etext)
1152 codepages++;
1153 else
1154 datapages++;
1155 continue;
1156 }
1157 mem_map[MAP_NR(tmp)] = 1;
1158 free_page(tmp);
1159 }
1160 tmp = nr_free_pages << PAGE_SHIFT;
1161 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
1162 tmp >> 10,
1163 high_memory >> 10,
1164 codepages << (PAGE_SHIFT-10),
1165 reservedpages << (PAGE_SHIFT-10),
1166 datapages << (PAGE_SHIFT-10));
1167
1168 wp_works_ok = -1;
1169 pg0[0] = PAGE_READONLY;
1170 invalidate();
1171 __asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
1172 pg0[0] = 0;
1173 invalidate();
1174 if (wp_works_ok < 0)
1175 wp_works_ok = 0;
1176 #ifdef CONFIG_TEST_VERIFY_AREA
1177 wp_works_ok = 0;
1178 #endif
1179 return;
1180 }
1181
1182 void si_meminfo(struct sysinfo *val)
1183 {
1184 int i;
1185
1186 i = high_memory >> PAGE_SHIFT;
1187 val->totalram = 0;
1188 val->sharedram = 0;
1189 val->freeram = nr_free_pages << PAGE_SHIFT;
1190 val->bufferram = buffermem;
1191 while (i-- > 0) {
1192 if (mem_map[i] & MAP_PAGE_RESERVED)
1193 continue;
1194 val->totalram++;
1195 if (!mem_map[i])
1196 continue;
1197 val->sharedram += mem_map[i]-1;
1198 }
1199 val->totalram <<= PAGE_SHIFT;
1200 val->sharedram <<= PAGE_SHIFT;
1201 return;
1202 }
1203
1204
1205
1206 void file_mmap_nopage(int error_code, struct vm_area_struct * area, unsigned long address)
1207 {
1208 struct inode * inode = area->vm_inode;
1209 unsigned int block;
1210 unsigned long page;
1211 int nr[8];
1212 int i, j;
1213 int prot = area->vm_page_prot;
1214
1215 address &= PAGE_MASK;
1216 block = address - area->vm_start + area->vm_offset;
1217 block >>= inode->i_sb->s_blocksize_bits;
1218
1219 page = get_free_page(GFP_KERNEL);
1220 if (share_page(area, area->vm_task, inode, address, error_code, page)) {
1221 ++area->vm_task->mm->min_flt;
1222 return;
1223 }
1224
1225 ++area->vm_task->mm->maj_flt;
1226 if (!page) {
1227 oom(current);
1228 put_page(area->vm_task, BAD_PAGE, address, PAGE_PRIVATE);
1229 return;
1230 }
1231 for (i=0, j=0; i< PAGE_SIZE ; j++, block++, i += inode->i_sb->s_blocksize)
1232 nr[j] = bmap(inode,block);
1233 if (error_code & PAGE_RW)
1234 prot |= PAGE_RW | PAGE_DIRTY;
1235 page = bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, prot);
1236
1237 if (!(prot & PAGE_RW)) {
1238 if (share_page(area, area->vm_task, inode, address, error_code, page))
1239 return;
1240 }
1241 if (put_page(area->vm_task,page,address,prot))
1242 return;
1243 free_page(page);
1244 oom(current);
1245 }
1246
1247 void file_mmap_free(struct vm_area_struct * area)
1248 {
1249 if (area->vm_inode)
1250 iput(area->vm_inode);
1251 #if 0
1252 if (area->vm_inode)
1253 printk("Free inode %x:%d (%d)\n",area->vm_inode->i_dev,
1254 area->vm_inode->i_ino, area->vm_inode->i_count);
1255 #endif
1256 }
1257
1258
1259
1260
1261
1262 int file_mmap_share(struct vm_area_struct * area1,
1263 struct vm_area_struct * area2,
1264 unsigned long address)
1265 {
1266 if (area1->vm_inode != area2->vm_inode)
1267 return 0;
1268 if (area1->vm_start != area2->vm_start)
1269 return 0;
1270 if (area1->vm_end != area2->vm_end)
1271 return 0;
1272 if (area1->vm_offset != area2->vm_offset)
1273 return 0;
1274 if (area1->vm_page_prot != area2->vm_page_prot)
1275 return 0;
1276 return 1;
1277 }
1278
1279 struct vm_operations_struct file_mmap = {
1280 NULL,
1281 file_mmap_free,
1282 file_mmap_nopage,
1283 NULL,
1284 file_mmap_share,
1285 NULL,
1286 };