Excerpts from Fabiano Rosas's message of November 10, 2021 7:19 am: > Nicholas Piggin <npig...@gmail.com> writes: > >> Allow the LPID bit width and partition table size to be set at runtime >> from the device tree. >> >> Move the PID bit width detection into the same place. >> >> KVM does not support using the extra bits yet, this is mainly required >> to get the PTCR register values correct. >> >> Signed-off-by: Nicholas Piggin <npig...@gmail.com> >> --- >> arch/powerpc/include/asm/book3s/64/mmu.h | 9 ++--- >> arch/powerpc/include/asm/kvm_book3s_asm.h | 6 +++- >> arch/powerpc/include/asm/reg.h | 2 -- >> arch/powerpc/mm/book3s64/pgtable.c | 5 --- >> arch/powerpc/mm/book3s64/radix_pgtable.c | 13 +------ >> arch/powerpc/mm/init_64.c | 44 +++++++++++++++++++++++ >> 6 files changed, 55 insertions(+), 24 deletions(-) >> >> diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h >> b/arch/powerpc/include/asm/book3s/64/mmu.h >> index c02f42d1031e..8c500dd6fee4 100644 >> --- a/arch/powerpc/include/asm/book3s/64/mmu.h >> +++ b/arch/powerpc/include/asm/book3s/64/mmu.h >> @@ -62,6 +62,9 @@ extern struct patb_entry *partition_tb; >> #define PRTS_MASK 0x1f /* process table size field */ >> #define PRTB_MASK 0x0ffffffffffff000UL >> >> +/* Number of supported LPID bits */ >> +extern unsigned int mmu_lpid_bits; >> + >> /* Number of supported PID bits */ >> extern unsigned int mmu_pid_bits; >> >> @@ -76,10 +79,8 @@ extern unsigned long __ro_after_init radix_mem_block_size; >> #define PRTB_SIZE_SHIFT (mmu_pid_bits + 4) >> #define PRTB_ENTRIES (1ul << mmu_pid_bits) >> >> -/* >> - * Power9 currently only support 64K partition table size. >> - */ >> -#define PATB_SIZE_SHIFT 16 >> +#define PATB_SIZE_SHIFT (mmu_lpid_bits + 4) >> +#define PATB_ENTRIES (1ul << mmu_lpid_bits) >> >> typedef unsigned long mm_context_id_t; >> struct spinlock; >> diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h >> b/arch/powerpc/include/asm/kvm_book3s_asm.h >> index b6d31bff5209..4d93e09a1ab9 100644 >> --- a/arch/powerpc/include/asm/kvm_book3s_asm.h >> +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h >> @@ -15,7 +15,11 @@ >> #define XICS_IPI 2 /* interrupt source # for IPIs */ >> >> /* LPIDs we support with this build -- runtime limit may be lower */ >> -#define KVMPPC_NR_LPIDS (LPID_RSVD + 1) >> +#define KVMPPC_NR_LPIDS (1ul << 12) >> + >> +/* Reserved LPID for partn switching */ >> +#define LPID_RSVD_POWER7 ((1ul << 10) - 1) >> +#define LPID_RSVD (KVMPPC_NR_LPIDS - 1) >> >> /* Maximum number of threads per physical core */ >> #define MAX_SMT_THREADS 8 >> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h >> index e9d27265253b..30983f2fd6a4 100644 >> --- a/arch/powerpc/include/asm/reg.h >> +++ b/arch/powerpc/include/asm/reg.h >> @@ -474,8 +474,6 @@ >> #ifndef SPRN_LPID >> #define SPRN_LPID 0x13F /* Logical Partition Identifier */ >> #endif >> -#define LPID_RSVD_POWER7 0x3ff /* Reserved LPID for partn switching */ >> -#define LPID_RSVD 0xfff /* Reserved LPID for partn switching */ >> #define SPRN_HMER 0x150 /* Hypervisor maintenance exception reg >> */ >> #define HMER_DEBUG_TRIG (1ul << (63 - 17)) /* Debug trigger */ >> #define SPRN_HMEER 0x151 /* Hyp maintenance exception enable reg >> */ >> diff --git a/arch/powerpc/mm/book3s64/pgtable.c >> b/arch/powerpc/mm/book3s64/pgtable.c >> index 9e16c7b1a6c5..13d1fbddecb9 100644 >> --- a/arch/powerpc/mm/book3s64/pgtable.c >> +++ b/arch/powerpc/mm/book3s64/pgtable.c >> @@ -207,17 +207,12 @@ void __init mmu_partition_table_init(void) >> unsigned long patb_size = 1UL << PATB_SIZE_SHIFT; >> unsigned long ptcr; >> >> - BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too >> large."); >> /* Initialize the Partition Table with no entries */ >> partition_tb = memblock_alloc(patb_size, patb_size); >> if (!partition_tb) >> panic("%s: Failed to allocate %lu bytes align=0x%lx\n", >> __func__, patb_size, patb_size); >> >> - /* >> - * update partition table control register, >> - * 64 K size. >> - */ >> ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12); >> set_ptcr_when_no_uv(ptcr); >> powernv_set_nmmu_ptcr(ptcr); >> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c >> b/arch/powerpc/mm/book3s64/radix_pgtable.c >> index ae20add7954a..1c855434f8dc 100644 >> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c >> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c >> @@ -33,7 +33,6 @@ >> >> #include <trace/events/thp.h> >> >> -unsigned int mmu_pid_bits; >> unsigned int mmu_base_pid; >> unsigned long radix_mem_block_size __ro_after_init; >> >> @@ -357,18 +356,13 @@ static void __init radix_init_pgtable(void) >> -1, PAGE_KERNEL)); >> } >> >> - /* Find out how many PID bits are supported */ >> if (!cpu_has_feature(CPU_FTR_HVMODE) && >> cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) { >> /* >> * Older versions of KVM on these machines perfer if the >> * guest only uses the low 19 PID bits. >> */ >> - if (!mmu_pid_bits) >> - mmu_pid_bits = 19; >> - } else { >> - if (!mmu_pid_bits) >> - mmu_pid_bits = 20; >> + mmu_pid_bits = 19; >> } >> mmu_base_pid = 1; >> >> @@ -449,11 +443,6 @@ static int __init radix_dt_scan_page_sizes(unsigned >> long node, >> if (type == NULL || strcmp(type, "cpu") != 0) >> return 0; >> >> - /* Find MMU PID size */ >> - prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size); >> - if (prop && size == 4) >> - mmu_pid_bits = be32_to_cpup(prop); >> - >> /* Grab page size encodings */ >> prop = of_get_flat_dt_prop(node, "ibm,processor-radix-AP-encodings", >> &size); >> if (!prop) >> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c >> index 386be136026e..7d5a6cb7c76d 100644 >> --- a/arch/powerpc/mm/init_64.c >> +++ b/arch/powerpc/mm/init_64.c >> @@ -370,6 +370,9 @@ void register_page_bootmem_memmap(unsigned long >> section_nr, >> #endif /* CONFIG_SPARSEMEM_VMEMMAP */ >> >> #ifdef CONFIG_PPC_BOOK3S_64 >> +unsigned int mmu_lpid_bits; >> +unsigned int mmu_pid_bits; >> + >> static bool disable_radix = !IS_ENABLED(CONFIG_PPC_RADIX_MMU_DEFAULT); >> >> static int __init parse_disable_radix(char *p) >> @@ -437,12 +440,53 @@ static void __init early_check_vec5(void) >> } >> } >> >> +static int __init dt_scan_mmu_pid_width(unsigned long node, >> + const char *uname, int depth, >> + void *data) >> +{ >> + int size = 0; >> + const __be32 *prop; >> + const char *type = of_get_flat_dt_prop(node, "device_type", NULL); >> + >> + /* We are scanning "cpu" nodes only */ >> + if (type == NULL || strcmp(type, "cpu") != 0) >> + return 0; >> + >> + /* Find MMU LPID, PID register size */ >> + prop = of_get_flat_dt_prop(node, "ibm,mmu-lpid-bits", &size); >> + if (prop && size == 4) >> + mmu_lpid_bits = be32_to_cpup(prop); >> + >> + prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size); >> + if (prop && size == 4) >> + mmu_pid_bits = be32_to_cpup(prop); >> + >> + if (!mmu_pid_bits && !mmu_lpid_bits) >> + return 0; > > What if only one of the properties is present?
Ah that may be a problem because the below fallback would not set the other one that was not found (e.g., some firmware might only give us ibm,mmu-pid-bits because that was defined earlier). I will respin. Thanks, Nick