This source file includes following definitions.
- pgd_alloc
- pgd_free
- setup_mm_for_reboot
1
2
3
4 #include <linux/init_task.h>
5 #include <asm/pgalloc.h>
6
7 #define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD)
8
9
10
11
12
13 pgd_t *pgd_alloc(struct mm_struct *mm)
14 {
15 pgd_t *new_pgd, *init_pgd;
16 int i;
17
18 new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0);
19 if (!new_pgd)
20 return NULL;
21 for (i = 0; i < PTRS_PER_PGD; i++) {
22 (*new_pgd) = 1;
23 new_pgd++;
24 }
25 new_pgd -= PTRS_PER_PGD;
26
27 init_pgd = pgd_offset_k(0);
28
29 memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
30 (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
31
32 cpu_dcache_wb_range((unsigned long)new_pgd,
33 (unsigned long)new_pgd +
34 PTRS_PER_PGD * sizeof(pgd_t));
35 inc_zone_page_state(virt_to_page((unsigned long *)new_pgd),
36 NR_PAGETABLE);
37
38 return new_pgd;
39 }
40
41 void pgd_free(struct mm_struct *mm, pgd_t * pgd)
42 {
43 pmd_t *pmd;
44 struct page *pte;
45
46 if (!pgd)
47 return;
48
49 pmd = (pmd_t *) pgd;
50 if (pmd_none(*pmd))
51 goto free;
52 if (pmd_bad(*pmd)) {
53 pmd_ERROR(*pmd);
54 pmd_clear(pmd);
55 goto free;
56 }
57
58 pte = pmd_page(*pmd);
59 pmd_clear(pmd);
60 dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
61 pte_free(mm, pte);
62 mm_dec_nr_ptes(mm);
63 pmd_free(mm, pmd);
64 free:
65 free_pages((unsigned long)pgd, 0);
66 }
67
68
69
70
71
72
73 void setup_mm_for_reboot(char mode)
74 {
75 unsigned long pmdval;
76 pgd_t *pgd;
77 pmd_t *pmd;
78 int i;
79
80 if (current->mm && current->mm->pgd)
81 pgd = current->mm->pgd;
82 else
83 pgd = init_mm.pgd;
84
85 for (i = 0; i < USER_PTRS_PER_PGD; i++) {
86 pmdval = (i << PGDIR_SHIFT);
87 pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
88 set_pmd(pmd, __pmd(pmdval));
89 }
90 }