aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu-hash.h37
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h87
-rw-r--r--arch/powerpc/include/asm/mmu.h1
-rw-r--r--arch/powerpc/mm/hash_native_64.c42
-rw-r--r--arch/powerpc/mm/hash_utils_64.c55
5 files changed, 102 insertions, 120 deletions
diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
index 287a656ceb57..e407af2b7333 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
@@ -245,6 +245,43 @@ static inline int segment_shift(int ssize)
245} 245}
246 246
247/* 247/*
248 * This array is indexed by the LP field of the HPTE second dword.
249 * Since this field may contain some RPN bits, some entries are
250 * replicated so that we get the same value irrespective of RPN.
251 * The top 4 bits are the page size index (MMU_PAGE_*) for the
252 * actual page size, the bottom 4 bits are the base page size.
253 */
254extern u8 hpte_page_sizes[1 << LP_BITS];
255
256static inline unsigned long __hpte_page_size(unsigned long h, unsigned long l,
257 bool is_base_size)
258{
259 unsigned int i, lp;
260
261 if (!(h & HPTE_V_LARGE))
262 return 1ul << 12;
263
264 /* Look at the 8 bit LP value */
265 lp = (l >> LP_SHIFT) & ((1 << LP_BITS) - 1);
266 i = hpte_page_sizes[lp];
267 if (!i)
268 return 0;
269 if (!is_base_size)
270 i >>= 4;
271 return 1ul << mmu_psize_defs[i & 0xf].shift;
272}
273
274static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
275{
276 return __hpte_page_size(h, l, 0);
277}
278
279static inline unsigned long hpte_base_page_size(unsigned long h, unsigned long l)
280{
281 return __hpte_page_size(h, l, 1);
282}
283
284/*
248 * The current system page and segment sizes 285 * The current system page and segment sizes
249 */ 286 */
250extern int mmu_kernel_ssize; 287extern int mmu_kernel_ssize;
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index 88d17b4ea9c8..4ffd5a1e788d 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -20,6 +20,8 @@
20#ifndef __ASM_KVM_BOOK3S_64_H__ 20#ifndef __ASM_KVM_BOOK3S_64_H__
21#define __ASM_KVM_BOOK3S_64_H__ 21#define __ASM_KVM_BOOK3S_64_H__
22 22
23#include <asm/book3s/64/mmu-hash.h>
24
23#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE 25#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
24static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu) 26static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu)
25{ 27{
@@ -97,56 +99,20 @@ static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v)
97 hpte[0] = cpu_to_be64(hpte_v); 99 hpte[0] = cpu_to_be64(hpte_v);
98} 100}
99 101
100static inline int __hpte_actual_psize(unsigned int lp, int psize)
101{
102 int i, shift;
103 unsigned int mask;
104
105 /* start from 1 ignoring MMU_PAGE_4K */
106 for (i = 1; i < MMU_PAGE_COUNT; i++) {
107
108 /* invalid penc */
109 if (mmu_psize_defs[psize].penc[i] == -1)
110 continue;
111 /*
112 * encoding bits per actual page size
113 * PTE LP actual page size
114 * rrrr rrrz >=8KB
115 * rrrr rrzz >=16KB
116 * rrrr rzzz >=32KB
117 * rrrr zzzz >=64KB
118 * .......
119 */
120 shift = mmu_psize_defs[i].shift - LP_SHIFT;
121 if (shift > LP_BITS)
122 shift = LP_BITS;
123 mask = (1 << shift) - 1;
124 if ((lp & mask) == mmu_psize_defs[psize].penc[i])
125 return i;
126 }
127 return -1;
128}
129
130static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, 102static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
131 unsigned long pte_index) 103 unsigned long pte_index)
132{ 104{
133 int b_psize = MMU_PAGE_4K, a_psize = MMU_PAGE_4K; 105 int i, b_psize = MMU_PAGE_4K, a_psize = MMU_PAGE_4K;
134 unsigned int penc; 106 unsigned int penc;
135 unsigned long rb = 0, va_low, sllp; 107 unsigned long rb = 0, va_low, sllp;
136 unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1); 108 unsigned int lp = (r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
137 109
138 if (v & HPTE_V_LARGE) { 110 if (v & HPTE_V_LARGE) {
139 for (b_psize = 0; b_psize < MMU_PAGE_COUNT; b_psize++) { 111 i = hpte_page_sizes[lp];
140 112 b_psize = i & 0xf;
141 /* valid entries have a shift value */ 113 a_psize = i >> 4;
142 if (!mmu_psize_defs[b_psize].shift)
143 continue;
144
145 a_psize = __hpte_actual_psize(lp, b_psize);
146 if (a_psize != -1)
147 break;
148 }
149 } 114 }
115
150 /* 116 /*
151 * Ignore the top 14 bits of va 117 * Ignore the top 14 bits of va
152 * v have top two bits covering segment size, hence move 118 * v have top two bits covering segment size, hence move
@@ -215,45 +181,6 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
215 return rb; 181 return rb;
216} 182}
217 183
218static inline unsigned long __hpte_page_size(unsigned long h, unsigned long l,
219 bool is_base_size)
220{
221
222 int size, a_psize;
223 /* Look at the 8 bit LP value */
224 unsigned int lp = (l >> LP_SHIFT) & ((1 << LP_BITS) - 1);
225
226 /* only handle 4k, 64k and 16M pages for now */
227 if (!(h & HPTE_V_LARGE))
228 return 1ul << 12;
229 else {
230 for (size = 0; size < MMU_PAGE_COUNT; size++) {
231 /* valid entries have a shift value */
232 if (!mmu_psize_defs[size].shift)
233 continue;
234
235 a_psize = __hpte_actual_psize(lp, size);
236 if (a_psize != -1) {
237 if (is_base_size)
238 return 1ul << mmu_psize_defs[size].shift;
239 return 1ul << mmu_psize_defs[a_psize].shift;
240 }
241 }
242
243 }
244 return 0;
245}
246
247static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
248{
249 return __hpte_page_size(h, l, 0);
250}
251
252static inline unsigned long hpte_base_page_size(unsigned long h, unsigned long l)
253{
254 return __hpte_page_size(h, l, 1);
255}
256
257static inline unsigned long hpte_rpn(unsigned long ptel, unsigned long psize) 184static inline unsigned long hpte_rpn(unsigned long ptel, unsigned long psize)
258{ 185{
259 return ((ptel & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT; 186 return ((ptel & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT;
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index e2fb408f8398..b78e8d3377f6 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -271,6 +271,7 @@ static inline bool early_radix_enabled(void)
271#define MMU_PAGE_16G 13 271#define MMU_PAGE_16G 13
272#define MMU_PAGE_64G 14 272#define MMU_PAGE_64G 14
273 273
274/* N.B. we need to change the type of hpte_page_sizes if this gets to be > 16 */
274#define MMU_PAGE_COUNT 15 275#define MMU_PAGE_COUNT 15
275 276
276#ifdef CONFIG_PPC_BOOK3S_64 277#ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 0e4e9654bd2c..83ddc0e171b0 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -493,36 +493,6 @@ static void native_hugepage_invalidate(unsigned long vsid,
493} 493}
494#endif 494#endif
495 495
496static inline int __hpte_actual_psize(unsigned int lp, int psize)
497{
498 int i, shift;
499 unsigned int mask;
500
501 /* start from 1 ignoring MMU_PAGE_4K */
502 for (i = 1; i < MMU_PAGE_COUNT; i++) {
503
504 /* invalid penc */
505 if (mmu_psize_defs[psize].penc[i] == -1)
506 continue;
507 /*
508 * encoding bits per actual page size
509 * PTE LP actual page size
510 * rrrr rrrz >=8KB
511 * rrrr rrzz >=16KB
512 * rrrr rzzz >=32KB
513 * rrrr zzzz >=64KB
514 * .......
515 */
516 shift = mmu_psize_defs[i].shift - LP_SHIFT;
517 if (shift > LP_BITS)
518 shift = LP_BITS;
519 mask = (1 << shift) - 1;
520 if ((lp & mask) == mmu_psize_defs[psize].penc[i])
521 return i;
522 }
523 return -1;
524}
525
526static void hpte_decode(struct hash_pte *hpte, unsigned long slot, 496static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
527 int *psize, int *apsize, int *ssize, unsigned long *vpn) 497 int *psize, int *apsize, int *ssize, unsigned long *vpn)
528{ 498{
@@ -538,16 +508,8 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
538 size = MMU_PAGE_4K; 508 size = MMU_PAGE_4K;
539 a_size = MMU_PAGE_4K; 509 a_size = MMU_PAGE_4K;
540 } else { 510 } else {
541 for (size = 0; size < MMU_PAGE_COUNT; size++) { 511 size = hpte_page_sizes[lp] & 0xf;
542 512 a_size = hpte_page_sizes[lp] >> 4;
543 /* valid entries have a shift value */
544 if (!mmu_psize_defs[size].shift)
545 continue;
546
547 a_size = __hpte_actual_psize(lp, size);
548 if (a_size != -1)
549 break;
550 }
551 } 513 }
552 /* This works for all page sizes, and for 256M and 1T segments */ 514 /* This works for all page sizes, and for 256M and 1T segments */
553 if (cpu_has_feature(CPU_FTR_ARCH_300)) 515 if (cpu_has_feature(CPU_FTR_ARCH_300))
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0821556e16f4..ef3ae891a3db 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -93,6 +93,9 @@ static unsigned long _SDR1;
93struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; 93struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
94EXPORT_SYMBOL_GPL(mmu_psize_defs); 94EXPORT_SYMBOL_GPL(mmu_psize_defs);
95 95
96u8 hpte_page_sizes[1 << LP_BITS];
97EXPORT_SYMBOL_GPL(hpte_page_sizes);
98
96struct hash_pte *htab_address; 99struct hash_pte *htab_address;
97unsigned long htab_size_bytes; 100unsigned long htab_size_bytes;
98unsigned long htab_hash_mask; 101unsigned long htab_hash_mask;
@@ -564,8 +567,60 @@ static void __init htab_scan_page_sizes(void)
564#endif /* CONFIG_HUGETLB_PAGE */ 567#endif /* CONFIG_HUGETLB_PAGE */
565} 568}
566 569
570/*
571 * Fill in the hpte_page_sizes[] array.
572 * We go through the mmu_psize_defs[] array looking for all the
573 * supported base/actual page size combinations. Each combination
574 * has a unique pagesize encoding (penc) value in the low bits of
575 * the LP field of the HPTE. For actual page sizes less than 1MB,
576 * some of the upper LP bits are used for RPN bits, meaning that
577 * we need to fill in several entries in hpte_page_sizes[].
578 *
579 * In diagrammatic form, with r = RPN bits and z = page size bits:
580 * PTE LP actual page size
581 * rrrr rrrz >=8KB
582 * rrrr rrzz >=16KB
583 * rrrr rzzz >=32KB
584 * rrrr zzzz >=64KB
585 * ...
586 *
587 * The zzzz bits are implementation-specific but are chosen so that
588 * no encoding for a larger page size uses the same value in its
589 * low-order N bits as the encoding for the 2^(12+N) byte page size
590 * (if it exists).
591 */
592static void init_hpte_page_sizes(void)
593{
594 long int ap, bp;
595 long int shift, penc;
596
597 for (bp = 0; bp < MMU_PAGE_COUNT; ++bp) {
598 if (!mmu_psize_defs[bp].shift)
599 continue; /* not a supported page size */
600 for (ap = bp; ap < MMU_PAGE_COUNT; ++ap) {
601 penc = mmu_psize_defs[bp].penc[ap];
602 if (penc == -1)
603 continue;
604 shift = mmu_psize_defs[ap].shift - LP_SHIFT;
605 if (shift <= 0)
606 continue; /* should never happen */
607 /*
608 * For page sizes less than 1MB, this loop
609 * replicates the entry for all possible values
610 * of the rrrr bits.
611 */
612 while (penc < (1 << LP_BITS)) {
613 hpte_page_sizes[penc] = (ap << 4) | bp;
614 penc += 1 << shift;
615 }
616 }
617 }
618}
619
567static void __init htab_init_page_sizes(void) 620static void __init htab_init_page_sizes(void)
568{ 621{
622 init_hpte_page_sizes();
623
569 if (!debug_pagealloc_enabled()) { 624 if (!debug_pagealloc_enabled()) {
570 /* 625 /*
571 * Pick a size for the linear mapping. Currently, we only 626 * Pick a size for the linear mapping. Currently, we only