PUD index size was changed to 9 from 7 since kernel v3.7, but it was
not updated here. Also, currently L4_MASK is set to 0xfff for kernel
v3.10 and above irrespective of page size but it should be 0x1ff for
4K page size and 0xfff for 64K page size. This patch fixes them.
Signed-off-by: Hari Bathini <hbathini(a)linux.vnet.ibm.com>
---
defs.h | 7 ++++++-
ppc64.c | 10 +++++++---
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index adf6156..ea77823 100644
--- a/defs.h
+++ b/defs.h
@@ -3809,6 +3809,7 @@ struct efi_memory_desc_t {
#define PMD_INDEX_SIZE_L4_4K 7
#define PUD_INDEX_SIZE_L4_4K 7
#define PGD_INDEX_SIZE_L4_4K 9
+#define PUD_INDEX_SIZE_L4_4K_3_7 9
#define PTE_SHIFT_L4_4K 17
#define PMD_MASKED_BITS_4K 0
@@ -3829,7 +3830,10 @@ struct efi_memory_desc_t {
#define PD_HUGE 0x8000000000000000
#define HUGE_PTE_MASK 0x03
#define HUGEPD_SHIFT_MASK 0x3f
-#define L4_MASK (THIS_KERNEL_VERSION >= LINUX(3,10,0) ? 0xfff : 0x1ff)
+
+#define L4_MASK \
+ (THIS_KERNEL_VERSION >= LINUX(3,10,0) ? (machdep->ptrs_per_pgd - 1) : 0x1ff)
+
#define L4_OFFSET(vaddr) ((vaddr >> (machdep->machspec->l4_shift)) &
L4_MASK)
#define PGD_OFFSET_L4(vaddr) \
@@ -5674,6 +5678,7 @@ struct machine_specific {
uint l2_index_size;
uint l1_index_size;
+ uint ptrs_per_l4;
uint ptrs_per_l3;
uint ptrs_per_l2;
uint ptrs_per_l1;
diff --git a/ppc64.c b/ppc64.c
index 07508f7..bf0cd82 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -299,7 +299,10 @@ ppc64_init(int when)
/* 4K pagesize */
m->l1_index_size = PTE_INDEX_SIZE_L4_4K;
m->l2_index_size = PMD_INDEX_SIZE_L4_4K;
- m->l3_index_size = PUD_INDEX_SIZE_L4_4K;
+ if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
+ m->l3_index_size = PUD_INDEX_SIZE_L4_4K_3_7;
+ else
+ m->l3_index_size = PUD_INDEX_SIZE_L4_4K;
m->l4_index_size = PGD_INDEX_SIZE_L4_4K;
m->pte_shift = (machdep->flags & BOOK3E) ?
PTE_SHIFT_L4_BOOK3E_4K : PTE_SHIFT_L4_4K;
@@ -311,8 +314,8 @@ ppc64_init(int when)
m->ptrs_per_l1 = (1 << m->l1_index_size);
m->ptrs_per_l2 = (1 << m->l2_index_size);
m->ptrs_per_l3 = (1 << m->l3_index_size);
-
- machdep->ptrs_per_pgd = m->ptrs_per_l3;
+ m->ptrs_per_l4 = (1 << m->l4_index_size);
+ machdep->ptrs_per_pgd = m->ptrs_per_l4;
/* Compute shifts */
m->l2_shift = m->l1_shift + m->l1_index_size;
@@ -564,6 +567,7 @@ ppc64_dump_machdep_table(ulong arg)
fprintf(fp, " l3_index_size: %d\n",
machdep->machspec->l3_index_size);
fprintf(fp, " l2_index_size: %d\n",
machdep->machspec->l2_index_size);
fprintf(fp, " l1_index_size: %d\n",
machdep->machspec->l1_index_size);
+ fprintf(fp, " ptrs_per_l4: %d\n",
machdep->machspec->ptrs_per_l4);
fprintf(fp, " ptrs_per_l3: %d\n",
machdep->machspec->ptrs_per_l3);
fprintf(fp, " ptrs_per_l2: %d\n",
machdep->machspec->ptrs_per_l2);
fprintf(fp, " ptrs_per_l1: %d\n",
machdep->machspec->ptrs_per_l1);