With POWER10, tlbiel invalidates all the congruence class of TLB and hence we need to issue only one tlbiel with SET=0. Update POWER10_TLB_SETS to 1 and use that in the rest of the code.
Signed-off-by: Aneesh Kumar K.V <aneesh.ku...@linux.ibm.com> --- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1 + arch/powerpc/kvm/book3s_hv.c | 4 +++- arch/powerpc/kvm/book3s_hv_builtin.c | 8 +++++++- arch/powerpc/mm/book3s64/hash_native.c | 4 +++- arch/powerpc/mm/book3s64/radix_tlb.c | 13 ++++++++++--- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 683a9c7d1b03..755ae1ea910a 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -129,6 +129,7 @@ #define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */ #define POWER9_TLB_SETS_HASH 256 /* # sets in POWER9 TLB Hash mode */ #define POWER9_TLB_SETS_RADIX 128 /* # sets in POWER9 TLB Radix mode */ +#define POWER10_TLB_SETS 1 /* # sets in POWER10 TLB */ #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 3bd3118c7633..12553cb55ede 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4939,7 +4939,9 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) * Work out how many sets the TLB has, for the use of * the TLB invalidation loop in book3s_hv_rmhandlers.S. */ - if (radix_enabled()) + if (cpu_has_feature(CPU_FTR_ARCH_31)) + kvm->arch.tlb_sets = POWER10_TLB_SETS; /* 1 */ + else if (radix_enabled()) kvm->arch.tlb_sets = POWER9_TLB_SETS_RADIX; /* 128 */ else if (cpu_has_feature(CPU_FTR_ARCH_300)) kvm->arch.tlb_sets = POWER9_TLB_SETS_HASH; /* 256 */ diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 073617ce83e0..7dfe38771f3c 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -702,6 +702,7 @@ static void wait_for_sync(struct kvm_split_mode *sip, int phase) void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip) { + int num_sets; unsigned long rb, set; /* wait for every other thread to get to real mode */ @@ -712,11 +713,16 @@ void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip) mtspr(SPRN_LPID, sip->lpidr_req); isync(); + if (cpu_has_feature(CPU_FTR_ARCH_31)) + num_sets = POWER10_TLB_SETS; + else + num_sets = POWER9_TLB_SETS_RADIX; + /* Invalidate the TLB on thread 0 */ if (local_paca->kvm_hstate.tid == 0) { sip->do_set = 0; asm volatile("ptesync" : : : "memory"); - for (set = 0; set < POWER9_TLB_SETS_RADIX; ++set) { + for (set = 0; set < num_sets; ++set) { rb = TLBIEL_INVAL_SET_LPID + (set << TLBIEL_INVAL_SET_SHIFT); asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index cf20e5229ce1..abea64c804b2 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -130,7 +130,9 @@ void hash__tlbiel_all(unsigned int action) BUG(); } - if (early_cpu_has_feature(CPU_FTR_ARCH_300)) + if (early_cpu_has_feature(CPU_FTR_ARCH_31)) + tlbiel_all_isa300(POWER10_TLB_SETS, is); + else if (early_cpu_has_feature(CPU_FTR_ARCH_300)) tlbiel_all_isa300(POWER9_TLB_SETS_HASH, is); else if (early_cpu_has_feature(CPU_FTR_ARCH_207S)) tlbiel_all_isa206(POWER8_TLB_SETS, is); diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 143b4fd396f0..47db637755c4 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -83,7 +83,9 @@ void radix__tlbiel_all(unsigned int action) BUG(); } - if (early_cpu_has_feature(CPU_FTR_ARCH_300)) + if (early_cpu_has_feature(CPU_FTR_ARCH_31)) + tlbiel_all_isa300(POWER10_TLB_SETS, is); + else if (early_cpu_has_feature(CPU_FTR_ARCH_300)) tlbiel_all_isa300(POWER9_TLB_SETS_RADIX, is); else WARN(1, "%s called on pre-POWER9 CPU\n", __func__); @@ -284,7 +286,7 @@ static inline void fixup_tlbie_lpid(unsigned long lpid) */ static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) { - int set; + int set, num_sets; asm volatile("ptesync": : :"memory"); @@ -300,8 +302,13 @@ static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) return; } + if (cpu_has_feature(CPU_FTR_ARCH_31)) + num_sets = POWER10_TLB_SETS; + else + num_sets = POWER9_TLB_SETS_RADIX; + /* For the remaining sets, just flush the TLB */ - for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) + for (set = 1; set < num_sets; set++) __tlbiel_pid(pid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); -- 2.26.2