diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-powerpc/mmu-hash64.h | 3 | ||||
-rw-r--r-- | include/asm-powerpc/pgalloc-64.h | 5 | ||||
-rw-r--r-- | include/asm-powerpc/pgtable-64k.h | 39 | ||||
-rw-r--r-- | include/asm-powerpc/systbl.h | 1 | ||||
-rw-r--r-- | include/asm-powerpc/unistd.h | 3 |
5 files changed, 48 insertions, 3 deletions
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 2a1b4040e20d..2864fa3989ea 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h | |||
@@ -265,7 +265,7 @@ static inline unsigned long hpt_hash(unsigned long va, unsigned int shift, | |||
265 | 265 | ||
266 | extern int __hash_page_4K(unsigned long ea, unsigned long access, | 266 | extern int __hash_page_4K(unsigned long ea, unsigned long access, |
267 | unsigned long vsid, pte_t *ptep, unsigned long trap, | 267 | unsigned long vsid, pte_t *ptep, unsigned long trap, |
268 | unsigned int local, int ssize); | 268 | unsigned int local, int ssize, int subpage_prot); |
269 | extern int __hash_page_64K(unsigned long ea, unsigned long access, | 269 | extern int __hash_page_64K(unsigned long ea, unsigned long access, |
270 | unsigned long vsid, pte_t *ptep, unsigned long trap, | 270 | unsigned long vsid, pte_t *ptep, unsigned long trap, |
271 | unsigned int local, int ssize); | 271 | unsigned int local, int ssize); |
@@ -279,6 +279,7 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
279 | unsigned long pstart, unsigned long mode, | 279 | unsigned long pstart, unsigned long mode, |
280 | int psize, int ssize); | 280 | int psize, int ssize); |
281 | extern void set_huge_psize(int psize); | 281 | extern void set_huge_psize(int psize); |
282 | extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); | ||
282 | 283 | ||
283 | extern void htab_initialize(void); | 284 | extern void htab_initialize(void); |
284 | extern void htab_initialize_secondary(void); | 285 | extern void htab_initialize_secondary(void); |
diff --git a/include/asm-powerpc/pgalloc-64.h b/include/asm-powerpc/pgalloc-64.h index 94d0294341d6..43214c8085b7 100644 --- a/include/asm-powerpc/pgalloc-64.h +++ b/include/asm-powerpc/pgalloc-64.h | |||
@@ -12,6 +12,10 @@ | |||
12 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
13 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
14 | 14 | ||
15 | #ifndef CONFIG_PPC_SUBPAGE_PROT | ||
16 | static inline void subpage_prot_free(pgd_t *pgd) {} | ||
17 | #endif | ||
18 | |||
15 | extern struct kmem_cache *pgtable_cache[]; | 19 | extern struct kmem_cache *pgtable_cache[]; |
16 | 20 | ||
17 | #define PGD_CACHE_NUM 0 | 21 | #define PGD_CACHE_NUM 0 |
@@ -27,6 +31,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) | |||
27 | 31 | ||
28 | static inline void pgd_free(pgd_t *pgd) | 32 | static inline void pgd_free(pgd_t *pgd) |
29 | { | 33 | { |
34 | subpage_prot_free(pgd); | ||
30 | kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); | 35 | kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); |
31 | } | 36 | } |
32 | 37 | ||
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h index bd54b772fbc6..1cbd6b377eea 100644 --- a/include/asm-powerpc/pgtable-64k.h +++ b/include/asm-powerpc/pgtable-64k.h | |||
@@ -13,12 +13,49 @@ | |||
13 | #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) | 13 | #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) |
14 | #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) | 14 | #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) |
15 | #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) | 15 | #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) |
16 | #endif /* __ASSEMBLY__ */ | ||
17 | 16 | ||
18 | #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) | 17 | #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) |
19 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) | 18 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) |
20 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) | 19 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) |
21 | 20 | ||
21 | #ifdef CONFIG_PPC_SUBPAGE_PROT | ||
22 | /* | ||
23 | * For the sub-page protection option, we extend the PGD with one of | ||
24 | * these. Basically we have a 3-level tree, with the top level being | ||
25 | * the protptrs array. To optimize speed and memory consumption when | ||
26 | * only addresses < 4GB are being protected, pointers to the first | ||
27 | * four pages of sub-page protection words are stored in the low_prot | ||
28 | * array. | ||
29 | * Each page of sub-page protection words protects 1GB (4 bytes | ||
30 | * protects 64k). For the 3-level tree, each page of pointers then | ||
31 | * protects 8TB. | ||
32 | */ | ||
33 | struct subpage_prot_table { | ||
34 | unsigned long maxaddr; /* only addresses < this are protected */ | ||
35 | unsigned int **protptrs[2]; | ||
36 | unsigned int *low_prot[4]; | ||
37 | }; | ||
38 | |||
39 | #undef PGD_TABLE_SIZE | ||
40 | #define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \ | ||
41 | sizeof(struct subpage_prot_table)) | ||
42 | |||
43 | #define SBP_L1_BITS (PAGE_SHIFT - 2) | ||
44 | #define SBP_L2_BITS (PAGE_SHIFT - 3) | ||
45 | #define SBP_L1_COUNT (1 << SBP_L1_BITS) | ||
46 | #define SBP_L2_COUNT (1 << SBP_L2_BITS) | ||
47 | #define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS) | ||
48 | #define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS) | ||
49 | |||
50 | extern void subpage_prot_free(pgd_t *pgd); | ||
51 | |||
52 | static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd) | ||
53 | { | ||
54 | return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD); | ||
55 | } | ||
56 | #endif /* CONFIG_PPC_SUBPAGE_PROT */ | ||
57 | #endif /* __ASSEMBLY__ */ | ||
58 | |||
22 | /* With 4k base page size, hugepage PTEs go at the PMD level */ | 59 | /* With 4k base page size, hugepage PTEs go at the PMD level */ |
23 | #define MIN_HUGEPTE_SHIFT PAGE_SHIFT | 60 | #define MIN_HUGEPTE_SHIFT PAGE_SHIFT |
24 | 61 | ||
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h index 11d5383b2f09..0c8b0d679139 100644 --- a/include/asm-powerpc/systbl.h +++ b/include/asm-powerpc/systbl.h | |||
@@ -313,3 +313,4 @@ COMPAT_SYS_SPU(timerfd) | |||
313 | SYSCALL_SPU(eventfd) | 313 | SYSCALL_SPU(eventfd) |
314 | COMPAT_SYS_SPU(sync_file_range2) | 314 | COMPAT_SYS_SPU(sync_file_range2) |
315 | COMPAT_SYS(fallocate) | 315 | COMPAT_SYS(fallocate) |
316 | SYSCALL(subpage_prot) | ||
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 97d82b6a9406..fedc4b8e49e2 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h | |||
@@ -332,10 +332,11 @@ | |||
332 | #define __NR_eventfd 307 | 332 | #define __NR_eventfd 307 |
333 | #define __NR_sync_file_range2 308 | 333 | #define __NR_sync_file_range2 308 |
334 | #define __NR_fallocate 309 | 334 | #define __NR_fallocate 309 |
335 | #define __NR_subpage_prot 310 | ||
335 | 336 | ||
336 | #ifdef __KERNEL__ | 337 | #ifdef __KERNEL__ |
337 | 338 | ||
338 | #define __NR_syscalls 310 | 339 | #define __NR_syscalls 311 |
339 | 340 | ||
340 | #define __NR__exit __NR_exit | 341 | #define __NR__exit __NR_exit |
341 | #define NR_syscalls __NR_syscalls | 342 | #define NR_syscalls __NR_syscalls |