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
>
>