diff options
Diffstat (limited to 'arch/arm/mm/pgd.c')
-rw-r--r-- | arch/arm/mm/pgd.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 93292a18cf77..f7fafb1741f4 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | pgd_t *pgd_alloc(struct mm_struct *mm) | 23 | pgd_t *pgd_alloc(struct mm_struct *mm) |
24 | { | 24 | { |
25 | pgd_t *new_pgd, *init_pgd; | 25 | pgd_t *new_pgd, *init_pgd; |
26 | pud_t *new_pud, *init_pud; | ||
26 | pmd_t *new_pmd, *init_pmd; | 27 | pmd_t *new_pmd, *init_pmd; |
27 | pte_t *new_pte, *init_pte; | 28 | pte_t *new_pte, *init_pte; |
28 | 29 | ||
@@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
46 | * On ARM, first page must always be allocated since it | 47 | * On ARM, first page must always be allocated since it |
47 | * contains the machine vectors. | 48 | * contains the machine vectors. |
48 | */ | 49 | */ |
49 | new_pmd = pmd_alloc(mm, new_pgd, 0); | 50 | new_pud = pud_alloc(mm, new_pgd, 0); |
51 | if (!new_pud) | ||
52 | goto no_pud; | ||
53 | |||
54 | new_pmd = pmd_alloc(mm, new_pud, 0); | ||
50 | if (!new_pmd) | 55 | if (!new_pmd) |
51 | goto no_pmd; | 56 | goto no_pmd; |
52 | 57 | ||
@@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
54 | if (!new_pte) | 59 | if (!new_pte) |
55 | goto no_pte; | 60 | goto no_pte; |
56 | 61 | ||
57 | init_pmd = pmd_offset(init_pgd, 0); | 62 | init_pud = pud_offset(init_pgd, 0); |
63 | init_pmd = pmd_offset(init_pud, 0); | ||
58 | init_pte = pte_offset_map(init_pmd, 0); | 64 | init_pte = pte_offset_map(init_pmd, 0); |
59 | set_pte_ext(new_pte, *init_pte, 0); | 65 | set_pte_ext(new_pte, *init_pte, 0); |
60 | pte_unmap(init_pte); | 66 | pte_unmap(init_pte); |
@@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
66 | no_pte: | 72 | no_pte: |
67 | pmd_free(mm, new_pmd); | 73 | pmd_free(mm, new_pmd); |
68 | no_pmd: | 74 | no_pmd: |
75 | pud_free(mm, new_pud); | ||
76 | no_pud: | ||
69 | free_pages((unsigned long)new_pgd, 2); | 77 | free_pages((unsigned long)new_pgd, 2); |
70 | no_pgd: | 78 | no_pgd: |
71 | return NULL; | 79 | return NULL; |
@@ -74,6 +82,7 @@ no_pgd: | |||
74 | void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) | 82 | void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) |
75 | { | 83 | { |
76 | pgd_t *pgd; | 84 | pgd_t *pgd; |
85 | pud_t *pud; | ||
77 | pmd_t *pmd; | 86 | pmd_t *pmd; |
78 | pgtable_t pte; | 87 | pgtable_t pte; |
79 | 88 | ||
@@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) | |||
84 | if (pgd_none_or_clear_bad(pgd)) | 93 | if (pgd_none_or_clear_bad(pgd)) |
85 | goto no_pgd; | 94 | goto no_pgd; |
86 | 95 | ||
87 | pmd = pmd_offset(pgd, 0); | 96 | pud = pud_offset(pgd, 0); |
97 | if (pud_none_or_clear_bad(pud)) | ||
98 | goto no_pud; | ||
99 | |||
100 | pmd = pmd_offset(pud, 0); | ||
88 | if (pmd_none_or_clear_bad(pmd)) | 101 | if (pmd_none_or_clear_bad(pmd)) |
89 | goto no_pmd; | 102 | goto no_pmd; |
90 | 103 | ||
@@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) | |||
92 | pmd_clear(pmd); | 105 | pmd_clear(pmd); |
93 | pte_free(mm, pte); | 106 | pte_free(mm, pte); |
94 | no_pmd: | 107 | no_pmd: |
95 | pgd_clear(pgd); | 108 | pud_clear(pud); |
96 | pmd_free(mm, pmd); | 109 | pmd_free(mm, pmd); |
110 | no_pud: | ||
111 | pgd_clear(pgd); | ||
112 | pud_free(mm, pud); | ||
97 | no_pgd: | 113 | no_pgd: |
98 | free_pages((unsigned long) pgd_base, 2); | 114 | free_pages((unsigned long) pgd_base, 2); |
99 | } | 115 | } |