diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2019-04-29 12:00:40 +0300 |
---|---|---|
committer | Paul Mackerras <paulus@ozlabs.org> | 2019-04-30 12:32:01 +0300 |
commit | 2940ba0c48bf18e15e85cbb0f26c0e88e1211587 (patch) | |
tree | 314b4cb4da889bfeb6c653a534bf2afe63689e1a /arch/powerpc/kvm/book3s_hv_builtin.c | |
parent | 7ae9bda7edf3dac56c9abaeec264ac08d399a1ff (diff) | |
download | linux-2940ba0c48bf18e15e85cbb0f26c0e88e1211587.tar.xz |
KVM: PPC: Book3S HV: Move HPT guest TLB flushing to C code
This replaces assembler code in book3s_hv_rmhandlers.S that checks
the kvm->arch.need_tlb_flush cpumask and optionally does a TLB flush
with C code in book3s_hv_builtin.c. Note that unlike the radix
version, the hash version doesn't do an explicit ERAT invalidation
because we will invalidate and load up the SLB before entering the
guest, and that will invalidate the ERAT.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv_builtin.c')
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index b0cf22477e87..489abe5d9797 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -805,3 +805,32 @@ void kvmppc_guest_entry_inject_int(struct kvm_vcpu *vcpu) vcpu->arch.doorbell_request = 0; } } + +void kvmppc_hpt_check_need_tlb_flush(struct kvm *kvm) +{ + int pcpu = raw_smp_processor_id(); + unsigned long rb, set; + + /* + * On POWER9, individual threads can come in here, but the + * TLB is shared between the 4 threads in a core, hence + * invalidating on one thread invalidates for all. + * Thus we make all 4 threads use the same bit. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) + pcpu = cpu_first_thread_sibling(pcpu); + + if (cpumask_test_cpu(pcpu, &kvm->arch.need_tlb_flush)) { + rb = PPC_BIT(52); /* IS = 2 */ + for (set = 0; set < kvm->arch.tlb_sets; ++set) { + asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) + : : "r" (rb), "i" (0), "i" (0), "i" (0), + "r" (0) : "memory"); + rb += PPC_BIT(51); /* increment set number */ + } + asm volatile("ptesync": : :"memory"); + + /* Clear the bit after the TLB flush */ + cpumask_clear_cpu(pcpu, &kvm->arch.need_tlb_flush); + } +} |