Re: [PATCH v2 2/4] powerpc: Add Power12 raw mode
Amit Machhiwal <[email protected]> Tue, 4 Aug 2026 00:40:10 +0530
| Newsgroups | org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <[email protected]> |
On 2026/08/03 09:27 PM, Mahesh Salgaonkar wrote: > From: Nicholas Piggin <[email protected]> > > Add CPU table entries for raw mode. > > Signed-off-by: Nicholas Piggin <[email protected]> > Signed-off-by: Ritesh Harjani (IBM) <[email protected]> > Signed-off-by: Mahesh Salgaonkar <[email protected]> > Tested-by: Praveen K Pandey <[email protected]> > Reviewed-by: Nikhil Kumar Singh <[email protected]> > --- > Change in v2: > - Added Reviewed-by from Nikhil > --- > arch/powerpc/include/asm/cpu_setup.h | 2 ++ > arch/powerpc/include/asm/cputable.h | 17 +++++++-- > arch/powerpc/include/asm/mmu.h | 1 + > arch/powerpc/include/asm/reg.h | 5 ++- > arch/powerpc/include/asm/synch.h | 6 +++- > arch/powerpc/include/uapi/asm/cputable.h | 1 + > arch/powerpc/kernel/cpu_setup_power.c | 43 +++++++++++++++++++++++ > arch/powerpc/kernel/cpu_specs_book3s_64.h | 22 ++++++++++++ > arch/powerpc/kernel/dt_cpu_ftrs.c | 37 +++++++++++++++++++ > arch/powerpc/kernel/setup-common.c | 1 + > arch/powerpc/kvm/book3s_hv.c | 9 +++-- > arch/powerpc/mm/book3s64/hash_native.c | 22 ++++++++---- > arch/powerpc/mm/init_64.c | 4 ++- > 13 files changed, 157 insertions(+), 13 deletions(-) > > diff --git a/arch/powerpc/include/asm/cpu_setup.h b/arch/powerpc/include/asm/cpu_setup.h > index 30e2fe3895024..26d2c0e2c99c6 100644 > --- a/arch/powerpc/include/asm/cpu_setup.h > +++ b/arch/powerpc/include/asm/cpu_setup.h > @@ -9,10 +9,12 @@ void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec); > void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec); > void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec); > void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec); > +void __setup_cpu_power12(unsigned long offset, struct cpu_spec *spec); > void __restore_cpu_power7(void); > void __restore_cpu_power8(void); > void __restore_cpu_power9(void); > void __restore_cpu_power10(void); > +void __restore_cpu_power12(void); > > void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec *spec); > void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec *spec); > diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h > index ec16c12296da8..a3be81c47df3a 100644 > --- a/arch/powerpc/include/asm/cputable.h > +++ b/arch/powerpc/include/asm/cputable.h > @@ -194,6 +194,7 @@ static inline void cpu_feature_keys_init(void) { } > #define CPU_FTR_DAWR1 LONG_ASM_CONST(0x0008000000000000) > #define CPU_FTR_DEXCR_NPHIE LONG_ASM_CONST(0x0010000000000000) > #define CPU_FTR_P11_PVR LONG_ASM_CONST(0x0020000000000000) > +#define CPU_FTR_ARCH_32 LONG_ASM_CONST(0x0040000000000000) > > #ifndef __ASSEMBLER__ > > @@ -457,6 +458,18 @@ static inline void cpu_feature_keys_init(void) { } > > #define CPU_FTRS_POWER11 (CPU_FTRS_POWER10 | CPU_FTR_P11_PVR) > > +#define CPU_FTRS_POWER12 (CPU_FTR_LWSYNC | \ > + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ > + CPU_FTR_MMCRA | CPU_FTR_SMT | \ > + CPU_FTR_COHERENT_ICACHE | \ > + CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ > + CPU_FTR_DSCR | \ > + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ > + CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ > + CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ > + CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | CPU_FTR_ARCH_32 | \ > + CPU_FTR_DAWR | CPU_FTR_DAWR1) > + > #define CPU_FTRS_CELL (CPU_FTR_LWSYNC | \ > CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ > CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ > @@ -476,7 +489,7 @@ static inline void cpu_feature_keys_init(void) { } > (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \ > CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \ > CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \ > - CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11) > + CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12) Line exceeds 80 columns. Please wrap CPU_FTRS_POWER12 onto its own line. Same applies to the #else variant below. > #else > #define CPU_FTRS_POSSIBLE \ > (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ > @@ -484,7 +497,7 @@ static inline void cpu_feature_keys_init(void) { } > CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \ > CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \ > CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \ > - CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11) > + CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12) > #endif /* CONFIG_CPU_LITTLE_ENDIAN */ > #endif > #else > diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h > index 5f9c5d436e171..4fd7f81a29304 100644 > --- a/arch/powerpc/include/asm/mmu.h > +++ b/arch/powerpc/include/asm/mmu.h > @@ -133,6 +133,7 @@ > #define MMU_FTRS_POWER9 MMU_FTRS_POWER6 > #define MMU_FTRS_POWER10 MMU_FTRS_POWER6 > #define MMU_FTRS_POWER11 MMU_FTRS_POWER6 > +#define MMU_FTRS_POWER12 MMU_FTRS_POWER6 > #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ > MMU_FTR_CI_LARGE_PAGE > #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ > diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h > index 3449dd2b577d4..4460b666c603e 100644 > --- a/arch/powerpc/include/asm/reg.h > +++ b/arch/powerpc/include/asm/reg.h > @@ -492,11 +492,12 @@ > * determine both the compatibility level which we want to emulate and the > * compatibility level which the host is capable of emulating. > */ > +#define PCR_ARCH_31 0x20 /* Architecture 3.1 */ > #define PCR_ARCH_300 0x10 /* Architecture 3.00 */ > #define PCR_ARCH_207 0x8 /* Architecture 2.07 */ > #define PCR_ARCH_206 0x4 /* Architecture 2.06 */ > #define PCR_ARCH_205 0x2 /* Architecture 2.05 */ > -#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300) > +#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300 | PCR_ARCH_31) > #define PCR_MASK ~(PCR_HIGH_BITS | PCR_LOW_BITS) /* PCR Reserved Bits */ > #define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */ > #define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */ > @@ -1344,6 +1345,7 @@ > #define PVR_POWER9 0x004E > #define PVR_POWER10 0x0080 > #define PVR_POWER11 0x0082 > +#define PVR_POWER12 0x0083 > #define PVR_BE 0x0070 > #define PVR_PA6T 0x0090 > > @@ -1356,6 +1358,7 @@ > #define PVR_ARCH_300 0x0f000005 > #define PVR_ARCH_31 0x0f000006 > #define PVR_ARCH_31_P11 0x0f000007 > +#define PVR_ARCH_32 0x0f000008 > > /* Macros for setting and retrieving special purpose registers */ > #ifndef __ASSEMBLER__ > diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h > index 0d3ccb34adfb2..d0e9765dee287 100644 > --- a/arch/powerpc/include/asm/synch.h > +++ b/arch/powerpc/include/asm/synch.h > @@ -37,8 +37,12 @@ static inline void ppc_after_tlbiel_barrier(void) > * accelerators mapped will use tlbie (which does invalidate the copy) > * to invalidate translations. It's not possible to limit POWER10 this > * way due to local copy-paste. > + * > + * POWER12 does not need it. > */ > - asm volatile(ASM_FTR_IFSET(PPC_CP_ABORT, "", %0) : : "i" (CPU_FTR_ARCH_31) : "memory"); > + asm volatile(ASM_FTR_IF(PPC_CP_ABORT, "", %0, %1) : > + : "i" (CPU_FTR_ARCH_31|CPU_FTR_ARCH_32), "i" (CPU_FTR_ARCH_31) > + : "memory"); > } > #endif /* __ASSEMBLER__ */ > > diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h > index 731b97dc2d150..bc9bd225f5876 100644 > --- a/arch/powerpc/include/uapi/asm/cputable.h > +++ b/arch/powerpc/include/uapi/asm/cputable.h > @@ -52,6 +52,7 @@ > #define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 /* TM w/out suspended state */ > #define PPC_FEATURE2_ARCH_3_1 0x00040000 /* ISA 3.1 */ > #define PPC_FEATURE2_MMA 0x00020000 /* Matrix Multiply Assist */ > +#define PPC_FEATURE2_ARCH_3_2 0x00010000 /* ISA 3.2 */ > > /* > * IMPORTANT! > diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c > index 98bd4e6c17705..5de704ac031d8 100644 > --- a/arch/powerpc/kernel/cpu_setup_power.c > +++ b/arch/powerpc/kernel/cpu_setup_power.c > @@ -286,3 +286,46 @@ void __restore_cpu_power10(void) > init_HFSCR(); > init_PMU_HV(); > } > + > +void __setup_cpu_power12(unsigned long offset, struct cpu_spec *t) > +{ > + init_FSCR_power10(); > + init_PMU(); > + init_PMU_ISA31(); > + > + if (!init_hvmode_206(t)) > + return; > + > + mtspr(SPRN_PSSCR, 0); > + mtspr(SPRN_LPID, 0); > + mtspr(SPRN_PID, 0); > + mtspr(SPRN_AMOR, ~0); > + mtspr(SPRN_PCR, PCR_MASK); > + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ The '\' continuation is unnecessary inside a function body — the enclosing parentheses are sufficient for the compiler. While this pattern exists in the upstream __setup_cpu_power10 and __restore_cpu_power10 functions, please consider not perpetuating it in the new Power12 functions. Simply drop the '\'. checkpatch.pl does report this: WARNING: Avoid unnecessary line continuations #201: FILE: arch/powerpc/kernel/cpu_setup_power.c:304: + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ WARNING: Avoid unnecessary line continuations #224: FILE: arch/powerpc/kernel/cpu_setup_power.c:327: + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ Thanks, Amit > + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); > + init_HFSCR(); > + init_PMU_HV(); > +} > + > +void __restore_cpu_power12(void) > +{ > + u64 msr; > + > + init_FSCR_power10(); > + init_PMU(); > + init_PMU_ISA31(); > + > + msr = mfmsr(); > + if (!(msr & MSR_HV)) > + return; > + > + mtspr(SPRN_PSSCR, 0); > + mtspr(SPRN_LPID, 0); > + mtspr(SPRN_PID, 0); > + mtspr(SPRN_AMOR, ~0); > + mtspr(SPRN_PCR, PCR_MASK); > + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ Ditto. > + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); > + init_HFSCR(); > + init_PMU_HV(); > +} > diff --git a/arch/powerpc/kernel/cpu_specs_book3s_64.h b/arch/powerpc/kernel/cpu_specs_book3s_64.h > index 98d4274a1b6bf..7619dd157646f 100644 > --- a/arch/powerpc/kernel/cpu_specs_book3s_64.h > +++ b/arch/powerpc/kernel/cpu_specs_book3s_64.h > @@ -63,6 +63,11 @@ > #define COMMON_USER_POWER11 COMMON_USER_POWER10 > #define COMMON_USER2_POWER11 COMMON_USER2_POWER10 > > +#define COMMON_USER_POWER12 COMMON_USER_POWER10 > +#define COMMON_USER2_POWER12 (COMMON_USER2_POWER10 | \ > + PPC_FEATURE2_ARCH_3_2) > + > + > static struct cpu_spec cpu_specs[] __initdata = { > { /* PPC970 */ > .pvr_mask = 0xffff0000, > @@ -485,6 +490,23 @@ static struct cpu_spec cpu_specs[] __initdata = { > .machine_check_early = __machine_check_early_realmode_p10, > .platform = "power11", > }, > + { /* Power12 */ > + .pvr_mask = 0xffff0000, > + .pvr_value = 0x00830000, > + .cpu_name = "Power12 (raw)", > + .cpu_features = CPU_FTRS_POWER12, > + .cpu_user_features = COMMON_USER_POWER12, > + .cpu_user_features2 = COMMON_USER2_POWER12, > + .mmu_features = MMU_FTRS_POWER12, > + .icache_bsize = 128, > + .dcache_bsize = 128, > + .num_pmcs = 6, > + .pmc_type = PPC_PMC_IBM, > + .cpu_setup = __setup_cpu_power12, > + .cpu_restore = __restore_cpu_power12, > + .machine_check_early = __machine_check_early_realmode_p10, > + .platform = "power12", > + }, > { /* Cell Broadband Engine */ > .pvr_mask = 0xffff0000, > .pvr_value = 0x00700000, > diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c > index e5853daa6a486..b369e8cda12ee 100644 > --- a/arch/powerpc/kernel/dt_cpu_ftrs.c > +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c > @@ -26,6 +26,7 @@ > /* Device-tree visible constants follow */ > #define ISA_V3_0B 3000 > #define ISA_V3_1 3100 > +#define ISA_V3_2 3200 > > #define USABLE_PR (1U << 0) > #define USABLE_OS (1U << 1) > @@ -466,6 +467,35 @@ static int __init feat_enable_mce_power11(struct dt_cpu_feature *f) > return 1; > } > > +static void init_pmu_power12(void) > +{ > + init_pmu_power10(); > +} > + > +static int __init feat_enable_pmu_power12(struct dt_cpu_feature *f) > +{ > + hfscr_pmu_enable(); > + > + init_pmu_power12(); > + init_pmu_registers = init_pmu_power12; > + > + cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA; > + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT; > + > + cur_cpu_spec->num_pmcs = 6; > + cur_cpu_spec->pmc_type = PPC_PMC_IBM; > + > + return 1; > +} > + > +static int __init feat_enable_mce_power12(struct dt_cpu_feature *f) > +{ > + cur_cpu_spec->platform = "power12"; > + cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10; > + > + return 1; > +} > + > static int __init feat_enable_tm(struct dt_cpu_feature *f) > { > #ifdef CONFIG_PPC_TRANSACTIONAL_MEM > @@ -657,9 +687,11 @@ static struct dt_cpu_feature_match __initdata > {"machine-check-power9", feat_enable_mce_power9, 0}, > {"machine-check-power10", feat_enable_mce_power10, 0}, > {"machine-check-power11", feat_enable_mce_power11, 0}, > + {"machine-check-power12", feat_enable_mce_power12, 0}, > {"performance-monitor-power9", feat_enable_pmu_power9, 0}, > {"performance-monitor-power10", feat_enable_pmu_power10, 0}, > {"performance-monitor-power11", feat_enable_pmu_power10, 0}, > + {"performance-monitor-power12", feat_enable_pmu_power12, 0}, > {"event-based-branch-v3", feat_enable, 0}, > {"random-number-generator", feat_enable, 0}, > {"system-call-vectored", feat_disable, 0}, > @@ -714,6 +746,11 @@ static void __init cpufeatures_setup_start(u32 isa) > if (PVR_VER(mfspr(SPRN_PVR)) >= PVR_POWER11) > cur_cpu_spec->cpu_features |= CPU_FTR_P11_PVR; > } > + > + if (isa >= ISA_V3_2) { > + cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_32; > + cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_2; > + } > } > > static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) > diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c > index 67c545f61f0d7..4afaba19b5867 100644 > --- a/arch/powerpc/kernel/setup-common.c > +++ b/arch/powerpc/kernel/setup-common.c > @@ -304,6 +304,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) > break; > case 0x004e: /* POWER9 bits 12-15 give chip type */ > case 0x0080: /* POWER10 bit 12 gives SMT8/4 */ > + case 0x0083: /* POWER12 bit 12 gives SMT8/4 */ > maj = (pvr >> 8) & 0x0F; > min = pvr & 0xFF; > break; > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index 61dbeea317f3b..6ad4e3d0b5a08 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -388,7 +388,7 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr) > } > > /* Dummy value used in computing PCR value below */ > -#define PCR_ARCH_31 (PCR_ARCH_300 << 1) > +#define PCR_ARCH_32 (PCR_ARCH_31 << 1) > > static inline unsigned long map_pcr_to_cap(unsigned long pcr) > { > @@ -417,7 +417,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) > struct kvmppc_vcore *vc = vcpu->arch.vcore; > > /* We can (emulate) our own architecture version and anything older */ > - if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31)) > + if (cpu_has_feature(CPU_FTR_ARCH_32)) > + host_pcr_bit = PCR_ARCH_32; > + else if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31)) > host_pcr_bit = PCR_ARCH_31; > else if (cpu_has_feature(CPU_FTR_ARCH_300)) > host_pcr_bit = PCR_ARCH_300; > @@ -449,6 +451,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) > case PVR_ARCH_31_P11: > guest_pcr_bit = PCR_ARCH_31; > break; > + case PVR_ARCH_32: > + guest_pcr_bit = PCR_ARCH_32; > + break; > default: > return -EINVAL; > } > diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c > index e9e2dd70c0605..ab2a80e59011c 100644 > --- a/arch/powerpc/mm/book3s64/hash_native.c > +++ b/arch/powerpc/mm/book3s64/hash_native.c > @@ -184,9 +184,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) > va |= ssize << 8; > sllp = get_sllp_encoding(apsize); > va |= sllp << 5; > - asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1) > - : : "r" (va), "i" (CPU_FTR_ARCH_206) > - : "memory"); > + > + if (cpu_has_feature(CPU_FTR_ARCH_32)) { > + asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory"); > + } else { > + asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1) > + : : "r" (va), "i" (CPU_FTR_ARCH_206) > + : "memory"); > + } > break; > default: > /* We need 14 to 14 + i bits of va */ > @@ -203,9 +208,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) > */ > va |= (vpn & 0xfe); > va |= 1; /* L */ > - asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1) > - : : "r" (va), "i" (CPU_FTR_ARCH_206) > - : "memory"); > + > + if (cpu_has_feature(CPU_FTR_ARCH_32)) { > + asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory"); > + } else { > + asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1) > + : : "r" (va), "i" (CPU_FTR_ARCH_206) > + : "memory"); > + } > break; > } > trace_tlbie(0, 1, va, 0, 0, 0, 0); > diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c > index 64f0df5bb5cdc..0e777d7dc3326 100644 > --- a/arch/powerpc/mm/init_64.c > +++ b/arch/powerpc/mm/init_64.c > @@ -628,7 +628,9 @@ void __init mmu_early_init_devtree(void) > > of_scan_flat_dt(dt_scan_mmu_pid_width, NULL); > if (hvmode && !mmu_lpid_bits) { > - if (early_cpu_has_feature(CPU_FTR_ARCH_207S)) > + if (early_cpu_has_feature(CPU_FTR_ARCH_32)) > + mmu_lpid_bits = 16; /* POWER12 */ > + else if (early_cpu_has_feature(CPU_FTR_ARCH_207S)) > mmu_lpid_bits = 12; /* POWER8-10 */ > else > mmu_lpid_bits = 10; /* POWER7 */ > -- > 2.55.0 > >