diff options
author | Steve Capper <steve.capper@linaro.org> | 2013-04-19 11:23:57 -0400 |
---|---|---|
committer | Steve Capper <steve.capper@linaro.org> | 2013-06-14 04:52:41 -0400 |
commit | af07484863e0c20796081e57093886c22dc16705 (patch) | |
tree | c9891c1048f860413c7cfd79e2b7a686c8be0263 | |
parent | d03bb1455f3a2804539ed27047fd3b073fdeb3e0 (diff) |
ARM64: mm: THP support.
Bring Transparent HugePage support to ARM. The size of a
transparent huge page depends on the normal page size. A
transparent huge page is always represented as a pmd.
If PAGE_SIZE is 4KB, THPs are 2MB.
If PAGE_SIZE is 64KB, THPs are 512MB.
Signed-off-by: Steve Capper <steve.capper@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable-hwdef.h | 4 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable.h | 55 | ||||
-rw-r--r-- | arch/arm64/include/asm/tlb.h | 6 | ||||
-rw-r--r-- | arch/arm64/include/asm/tlbflush.h | 2 |
5 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 10607d63b945..308a55636f76 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -189,6 +189,9 @@ config ARCH_WANT_GENERAL_HUGETLB | |||
189 | config ARCH_WANT_HUGE_PMD_SHARE | 189 | config ARCH_WANT_HUGE_PMD_SHARE |
190 | def_bool y if !ARM64_64K_PAGES | 190 | def_bool y if !ARM64_64K_PAGES |
191 | 191 | ||
192 | config HAVE_ARCH_TRANSPARENT_HUGEPAGE | ||
193 | def_bool y | ||
194 | |||
192 | source "mm/Kconfig" | 195 | source "mm/Kconfig" |
193 | 196 | ||
194 | config FORCE_MAX_ZONEORDER | 197 | config FORCE_MAX_ZONEORDER |
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index e6e0a0d4cf9a..63c9d0de05bb 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h | |||
@@ -42,6 +42,10 @@ | |||
42 | /* | 42 | /* |
43 | * Section | 43 | * Section |
44 | */ | 44 | */ |
45 | #define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0) | ||
46 | #define PMD_SECT_PROT_NONE (_AT(pmdval_t, 1) << 2) | ||
47 | #define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */ | ||
48 | #define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */ | ||
45 | #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) | 49 | #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) |
46 | #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) | 50 | #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) |
47 | #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) | 51 | #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 21771330f809..720fc4a2be49 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -188,6 +188,61 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
188 | #define __HAVE_ARCH_PTE_SPECIAL | 188 | #define __HAVE_ARCH_PTE_SPECIAL |
189 | 189 | ||
190 | /* | 190 | /* |
191 | * Software PMD bits for THP | ||
192 | */ | ||
193 | |||
194 | #define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55) | ||
195 | #define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57) | ||
196 | |||
197 | /* | ||
198 | * THP definitions. | ||
199 | */ | ||
200 | #define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF) | ||
201 | |||
202 | #define __HAVE_ARCH_PMD_WRITE | ||
203 | #define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY)) | ||
204 | |||
205 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
206 | #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) | ||
207 | #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING) | ||
208 | #endif | ||
209 | |||
210 | #define PMD_BIT_FUNC(fn,op) \ | ||
211 | static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; } | ||
212 | |||
213 | PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY); | ||
214 | PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF); | ||
215 | PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING); | ||
216 | PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY); | ||
217 | PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY); | ||
218 | PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF); | ||
219 | PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK); | ||
220 | |||
221 | #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT)) | ||
222 | |||
223 | #define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT) | ||
224 | #define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) | ||
225 | #define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) | ||
226 | |||
227 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) | ||
228 | |||
229 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | ||
230 | { | ||
231 | const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN | | ||
232 | PMD_SECT_RDONLY | PMD_SECT_PROT_NONE | | ||
233 | PMD_SECT_VALID; | ||
234 | pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask); | ||
235 | return pmd; | ||
236 | } | ||
237 | |||
238 | #define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd) | ||
239 | |||
240 | static inline int has_transparent_hugepage(void) | ||
241 | { | ||
242 | return 1; | ||
243 | } | ||
244 | |||
245 | /* | ||
191 | * Mark the prot value as uncacheable and unbufferable. | 246 | * Mark the prot value as uncacheable and unbufferable. |
192 | */ | 247 | */ |
193 | #define pgprot_noncached(prot) \ | 248 | #define pgprot_noncached(prot) \ |
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 654f0968030b..46b3beb4b773 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h | |||
@@ -187,4 +187,10 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | |||
187 | 187 | ||
188 | #define tlb_migrate_finish(mm) do { } while (0) | 188 | #define tlb_migrate_finish(mm) do { } while (0) |
189 | 189 | ||
190 | static inline void | ||
191 | tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr) | ||
192 | { | ||
193 | tlb_add_flush(tlb, addr); | ||
194 | } | ||
195 | |||
190 | #endif | 196 | #endif |
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index 122d6320f745..8b482035cfc2 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h | |||
@@ -117,6 +117,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
117 | dsb(); | 117 | dsb(); |
118 | } | 118 | } |
119 | 119 | ||
120 | #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0) | ||
121 | |||
120 | #endif | 122 | #endif |
121 | 123 | ||
122 | #endif | 124 | #endif |