diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2017-03-09 09:24:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-09 14:48:47 -0500 |
commit | 048456dcf2c56ad6f6248e2899dda92fb6a613f6 (patch) | |
tree | 5a36b42c6ec1d44ce29becbf7ace2b8c4bebd61f | |
parent | 9849a5697d3defb2087cb6b9be5573a142697889 (diff) |
asm-generic: introduce <asm-generic/pgtable-nop4d.h>
Like with pgtable-nopud.h for 4-level paging, this new header is base
for converting an architectures to properly folded p4d_t level.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/asm-generic/pgtable-nop4d.h | 56 | ||||
-rw-r--r-- | include/asm-generic/pgtable-nopud.h | 43 | ||||
-rw-r--r-- | include/asm-generic/tlb.h | 14 |
3 files changed, 89 insertions, 24 deletions
diff --git a/include/asm-generic/pgtable-nop4d.h b/include/asm-generic/pgtable-nop4d.h new file mode 100644 index 000000000000..de364ecb8df6 --- /dev/null +++ b/include/asm-generic/pgtable-nop4d.h | |||
@@ -0,0 +1,56 @@ | |||
1 | #ifndef _PGTABLE_NOP4D_H | ||
2 | #define _PGTABLE_NOP4D_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | |||
6 | #define __PAGETABLE_P4D_FOLDED | ||
7 | |||
8 | typedef struct { pgd_t pgd; } p4d_t; | ||
9 | |||
10 | #define P4D_SHIFT PGDIR_SHIFT | ||
11 | #define PTRS_PER_P4D 1 | ||
12 | #define P4D_SIZE (1UL << P4D_SHIFT) | ||
13 | #define P4D_MASK (~(P4D_SIZE-1)) | ||
14 | |||
15 | /* | ||
16 | * The "pgd_xxx()" functions here are trivial for a folded two-level | ||
17 | * setup: the p4d is never bad, and a p4d always exists (as it's folded | ||
18 | * into the pgd entry) | ||
19 | */ | ||
20 | static inline int pgd_none(pgd_t pgd) { return 0; } | ||
21 | static inline int pgd_bad(pgd_t pgd) { return 0; } | ||
22 | static inline int pgd_present(pgd_t pgd) { return 1; } | ||
23 | static inline void pgd_clear(pgd_t *pgd) { } | ||
24 | #define p4d_ERROR(p4d) (pgd_ERROR((p4d).pgd)) | ||
25 | |||
26 | #define pgd_populate(mm, pgd, p4d) do { } while (0) | ||
27 | /* | ||
28 | * (p4ds are folded into pgds so this doesn't get actually called, | ||
29 | * but the define is needed for a generic inline function.) | ||
30 | */ | ||
31 | #define set_pgd(pgdptr, pgdval) set_p4d((p4d_t *)(pgdptr), (p4d_t) { pgdval }) | ||
32 | |||
33 | static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) | ||
34 | { | ||
35 | return (p4d_t *)pgd; | ||
36 | } | ||
37 | |||
38 | #define p4d_val(x) (pgd_val((x).pgd)) | ||
39 | #define __p4d(x) ((p4d_t) { __pgd(x) }) | ||
40 | |||
41 | #define pgd_page(pgd) (p4d_page((p4d_t){ pgd })) | ||
42 | #define pgd_page_vaddr(pgd) (p4d_page_vaddr((p4d_t){ pgd })) | ||
43 | |||
44 | /* | ||
45 | * allocating and freeing a p4d is trivial: the 1-entry p4d is | ||
46 | * inside the pgd, so has no extra memory associated with it. | ||
47 | */ | ||
48 | #define p4d_alloc_one(mm, address) NULL | ||
49 | #define p4d_free(mm, x) do { } while (0) | ||
50 | #define __p4d_free_tlb(tlb, x, a) do { } while (0) | ||
51 | |||
52 | #undef p4d_addr_end | ||
53 | #define p4d_addr_end(addr, end) (end) | ||
54 | |||
55 | #endif /* __ASSEMBLY__ */ | ||
56 | #endif /* _PGTABLE_NOP4D_H */ | ||
diff --git a/include/asm-generic/pgtable-nopud.h b/include/asm-generic/pgtable-nopud.h index 5e49430a30a4..c2b9b96d6268 100644 --- a/include/asm-generic/pgtable-nopud.h +++ b/include/asm-generic/pgtable-nopud.h | |||
@@ -6,53 +6,54 @@ | |||
6 | #ifdef __ARCH_USE_5LEVEL_HACK | 6 | #ifdef __ARCH_USE_5LEVEL_HACK |
7 | #include <asm-generic/pgtable-nop4d-hack.h> | 7 | #include <asm-generic/pgtable-nop4d-hack.h> |
8 | #else | 8 | #else |
9 | #include <asm-generic/pgtable-nop4d.h> | ||
9 | 10 | ||
10 | #define __PAGETABLE_PUD_FOLDED | 11 | #define __PAGETABLE_PUD_FOLDED |
11 | 12 | ||
12 | /* | 13 | /* |
13 | * Having the pud type consist of a pgd gets the size right, and allows | 14 | * Having the pud type consist of a p4d gets the size right, and allows |
14 | * us to conceptually access the pgd entry that this pud is folded into | 15 | * us to conceptually access the p4d entry that this pud is folded into |
15 | * without casting. | 16 | * without casting. |
16 | */ | 17 | */ |
17 | typedef struct { pgd_t pgd; } pud_t; | 18 | typedef struct { p4d_t p4d; } pud_t; |
18 | 19 | ||
19 | #define PUD_SHIFT PGDIR_SHIFT | 20 | #define PUD_SHIFT P4D_SHIFT |
20 | #define PTRS_PER_PUD 1 | 21 | #define PTRS_PER_PUD 1 |
21 | #define PUD_SIZE (1UL << PUD_SHIFT) | 22 | #define PUD_SIZE (1UL << PUD_SHIFT) |
22 | #define PUD_MASK (~(PUD_SIZE-1)) | 23 | #define PUD_MASK (~(PUD_SIZE-1)) |
23 | 24 | ||
24 | /* | 25 | /* |
25 | * The "pgd_xxx()" functions here are trivial for a folded two-level | 26 | * The "p4d_xxx()" functions here are trivial for a folded two-level |
26 | * setup: the pud is never bad, and a pud always exists (as it's folded | 27 | * setup: the pud is never bad, and a pud always exists (as it's folded |
27 | * into the pgd entry) | 28 | * into the p4d entry) |
28 | */ | 29 | */ |
29 | static inline int pgd_none(pgd_t pgd) { return 0; } | 30 | static inline int p4d_none(p4d_t p4d) { return 0; } |
30 | static inline int pgd_bad(pgd_t pgd) { return 0; } | 31 | static inline int p4d_bad(p4d_t p4d) { return 0; } |
31 | static inline int pgd_present(pgd_t pgd) { return 1; } | 32 | static inline int p4d_present(p4d_t p4d) { return 1; } |
32 | static inline void pgd_clear(pgd_t *pgd) { } | 33 | static inline void p4d_clear(p4d_t *p4d) { } |
33 | #define pud_ERROR(pud) (pgd_ERROR((pud).pgd)) | 34 | #define pud_ERROR(pud) (p4d_ERROR((pud).p4d)) |
34 | 35 | ||
35 | #define pgd_populate(mm, pgd, pud) do { } while (0) | 36 | #define p4d_populate(mm, p4d, pud) do { } while (0) |
36 | /* | 37 | /* |
37 | * (puds are folded into pgds so this doesn't get actually called, | 38 | * (puds are folded into p4ds so this doesn't get actually called, |
38 | * but the define is needed for a generic inline function.) | 39 | * but the define is needed for a generic inline function.) |
39 | */ | 40 | */ |
40 | #define set_pgd(pgdptr, pgdval) set_pud((pud_t *)(pgdptr), (pud_t) { pgdval }) | 41 | #define set_p4d(p4dptr, p4dval) set_pud((pud_t *)(p4dptr), (pud_t) { p4dval }) |
41 | 42 | ||
42 | static inline pud_t * pud_offset(pgd_t * pgd, unsigned long address) | 43 | static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) |
43 | { | 44 | { |
44 | return (pud_t *)pgd; | 45 | return (pud_t *)p4d; |
45 | } | 46 | } |
46 | 47 | ||
47 | #define pud_val(x) (pgd_val((x).pgd)) | 48 | #define pud_val(x) (p4d_val((x).p4d)) |
48 | #define __pud(x) ((pud_t) { __pgd(x) } ) | 49 | #define __pud(x) ((pud_t) { __p4d(x) }) |
49 | 50 | ||
50 | #define pgd_page(pgd) (pud_page((pud_t){ pgd })) | 51 | #define p4d_page(p4d) (pud_page((pud_t){ p4d })) |
51 | #define pgd_page_vaddr(pgd) (pud_page_vaddr((pud_t){ pgd })) | 52 | #define p4d_page_vaddr(p4d) (pud_page_vaddr((pud_t){ p4d })) |
52 | 53 | ||
53 | /* | 54 | /* |
54 | * allocating and freeing a pud is trivial: the 1-entry pud is | 55 | * allocating and freeing a pud is trivial: the 1-entry pud is |
55 | * inside the pgd, so has no extra memory associated with it. | 56 | * inside the p4d, so has no extra memory associated with it. |
56 | */ | 57 | */ |
57 | #define pud_alloc_one(mm, address) NULL | 58 | #define pud_alloc_one(mm, address) NULL |
58 | #define pud_free(mm, x) do { } while (0) | 59 | #define pud_free(mm, x) do { } while (0) |
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index 4329bc6ef04b..8afa4335e5b2 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h | |||
@@ -270,6 +270,12 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb, | |||
270 | __pte_free_tlb(tlb, ptep, address); \ | 270 | __pte_free_tlb(tlb, ptep, address); \ |
271 | } while (0) | 271 | } while (0) |
272 | 272 | ||
273 | #define pmd_free_tlb(tlb, pmdp, address) \ | ||
274 | do { \ | ||
275 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | ||
276 | __pmd_free_tlb(tlb, pmdp, address); \ | ||
277 | } while (0) | ||
278 | |||
273 | #ifndef __ARCH_HAS_4LEVEL_HACK | 279 | #ifndef __ARCH_HAS_4LEVEL_HACK |
274 | #define pud_free_tlb(tlb, pudp, address) \ | 280 | #define pud_free_tlb(tlb, pudp, address) \ |
275 | do { \ | 281 | do { \ |
@@ -278,11 +284,13 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb, | |||
278 | } while (0) | 284 | } while (0) |
279 | #endif | 285 | #endif |
280 | 286 | ||
281 | #define pmd_free_tlb(tlb, pmdp, address) \ | 287 | #ifndef __ARCH_HAS_5LEVEL_HACK |
288 | #define p4d_free_tlb(tlb, pudp, address) \ | ||
282 | do { \ | 289 | do { \ |
283 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | 290 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ |
284 | __pmd_free_tlb(tlb, pmdp, address); \ | 291 | __p4d_free_tlb(tlb, pudp, address); \ |
285 | } while (0) | 292 | } while (0) |
293 | #endif | ||
286 | 294 | ||
287 | #define tlb_migrate_finish(mm) do {} while (0) | 295 | #define tlb_migrate_finish(mm) do {} while (0) |
288 | 296 | ||