aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/pgalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include/asm/pgalloc.h')
-rw-r--r--arch/arm/include/asm/pgalloc.h39
1 files changed, 17 insertions, 22 deletions
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 1f1064b519c0..9763be04f77e 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -35,6 +35,11 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
35 35
36#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO) 36#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
37 37
38static inline void clean_pte_table(pte_t *pte)
39{
40 clean_dcache_area(pte + PTE_HWTABLE_PTRS, PTE_HWTABLE_SIZE);
41}
42
38/* 43/*
39 * Allocate one PTE table. 44 * Allocate one PTE table.
40 * 45 *
@@ -42,14 +47,14 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
42 * into one table thus: 47 * into one table thus:
43 * 48 *
44 * +------------+ 49 * +------------+
45 * | h/w pt 0 |
46 * +------------+
47 * | h/w pt 1 |
48 * +------------+
49 * | Linux pt 0 | 50 * | Linux pt 0 |
50 * +------------+ 51 * +------------+
51 * | Linux pt 1 | 52 * | Linux pt 1 |
52 * +------------+ 53 * +------------+
54 * | h/w pt 0 |
55 * +------------+
56 * | h/w pt 1 |
57 * +------------+
53 */ 58 */
54static inline pte_t * 59static inline pte_t *
55pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) 60pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
@@ -57,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
57 pte_t *pte; 62 pte_t *pte;
58 63
59 pte = (pte_t *)__get_free_page(PGALLOC_GFP); 64 pte = (pte_t *)__get_free_page(PGALLOC_GFP);
60 if (pte) { 65 if (pte)
61 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); 66 clean_pte_table(pte);
62 pte += PTRS_PER_PTE;
63 }
64 67
65 return pte; 68 return pte;
66} 69}
@@ -76,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
76 pte = alloc_pages(PGALLOC_GFP, 0); 79 pte = alloc_pages(PGALLOC_GFP, 0);
77#endif 80#endif
78 if (pte) { 81 if (pte) {
79 if (!PageHighMem(pte)) { 82 if (!PageHighMem(pte))
80 void *page = page_address(pte); 83 clean_pte_table(page_address(pte));
81 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
82 }
83 pgtable_page_ctor(pte); 84 pgtable_page_ctor(pte);
84 } 85 }
85 86
@@ -91,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
91 */ 92 */
92static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 93static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
93{ 94{
94 if (pte) { 95 if (pte)
95 pte -= PTRS_PER_PTE;
96 free_page((unsigned long)pte); 96 free_page((unsigned long)pte);
97 }
98} 97}
99 98
100static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 99static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
@@ -106,7 +105,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
106static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, 105static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
107 unsigned long prot) 106 unsigned long prot)
108{ 107{
109 unsigned long pmdval = pte | prot; 108 unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
110 pmdp[0] = __pmd(pmdval); 109 pmdp[0] = __pmd(pmdval);
111 pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); 110 pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
112 flush_pmd_entry(pmdp); 111 flush_pmd_entry(pmdp);
@@ -121,14 +120,10 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
121static inline void 120static inline void
122pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) 121pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
123{ 122{
124 unsigned long pte_ptr = (unsigned long)ptep;
125
126 /* 123 /*
127 * The pmd must be loaded with the physical 124 * The pmd must be loaded with the physical address of the PTE table
128 * address of the PTE table
129 */ 125 */
130 pte_ptr -= PTRS_PER_PTE * sizeof(void *); 126 __pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);
131 __pmd_populate(pmdp, __pa(pte_ptr), _PAGE_KERNEL_TABLE);
132} 127}
133 128
134static inline void 129static inline void