aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/pgd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/pgd.c')
-rw-r--r--arch/arm/mm/pgd.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index e3eda56f4788..d15785eb73a7 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -73,28 +73,29 @@ no_pgd:
73 return NULL; 73 return NULL;
74} 74}
75 75
76void pgd_free(struct mm_struct *mm, pgd_t *pgd) 76void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
77{ 77{
78 pgd_t *pgd;
78 pmd_t *pmd; 79 pmd_t *pmd;
79 pgtable_t pte; 80 pgtable_t pte;
80 81
81 if (!pgd) 82 if (!pgd_base)
82 return; 83 return;
83 84
84 /* pgd is always present and good */ 85 pgd = pgd_base + pgd_index(0);
85 pmd = pmd_off(pgd, 0); 86 if (pgd_none_or_clear_bad(pgd))
86 if (pmd_none(*pmd)) 87 goto no_pgd;
87 goto free; 88
88 if (pmd_bad(*pmd)) { 89 pmd = pmd_offset(pgd, 0);
89 pmd_ERROR(*pmd); 90 if (pmd_none_or_clear_bad(pmd))
90 pmd_clear(pmd); 91 goto no_pmd;
91 goto free;
92 }
93 92
94 pte = pmd_pgtable(*pmd); 93 pte = pmd_pgtable(*pmd);
95 pmd_clear(pmd); 94 pmd_clear(pmd);
96 pte_free(mm, pte); 95 pte_free(mm, pte);
96no_pmd:
97 pgd_clear(pgd);
97 pmd_free(mm, pmd); 98 pmd_free(mm, pmd);
98free: 99no_pgd:
99 free_pages((unsigned long) pgd, 2); 100 free_pages((unsigned long) pgd_base, 2);
100} 101}