diff options
Diffstat (limited to 'arch/arm/include/asm/pgalloc.h')
-rw-r--r-- | arch/arm/include/asm/pgalloc.h | 39 |
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 | ||
38 | static 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 | */ |
54 | static inline pte_t * | 59 | static inline pte_t * |
55 | pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) | 60 | pte_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 | */ |
92 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | 93 | static 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 | ||
100 | static inline void pte_free(struct mm_struct *mm, pgtable_t pte) | 99 | static 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) | |||
106 | static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, | 105 | static 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, | |||
121 | static inline void | 120 | static inline void |
122 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) | 121 | pmd_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 | ||
134 | static inline void | 129 | static inline void |