[PATCH 5/6] LoongArch: KVM: Add remote tlb flushing support
Bibo Mao <[email protected]> Mon, 27 Jul 2026 15:21:08 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
With remote tlb flushing, vpid index stays unchanged and only vmid index is updated, since remote tlb flushing is to flush TLBs relative GPA --> HPA. For flushing method, cpumask tlb_flush_pending is added and set for all possible CPUs. When vCPUs is sched on the physical CPU, vmid is updated and cpumask for this physical CPU is cleared. Signed-off-by: Bibo Mao <[email protected]> --- arch/loongarch/include/asm/kvm_host.h | 3 +++ arch/loongarch/kvm/main.c | 2 ++ arch/loongarch/kvm/mmu.c | 16 ++++++++++++++++ arch/loongarch/kvm/vcpu.c | 7 ++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index a01623c42c7a..2c3cb475abf9 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -133,6 +133,7 @@ struct kvm_arch { unsigned long kvm_features; s64 time_offset; + cpumask_t tlb_flush_pending; unsigned long vmid[NR_CPUS]; struct kvm_context __percpu *vmcs; struct loongarch_ipi *ipi; @@ -357,6 +358,8 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} void kvm_check_vpid(struct kvm_vcpu *vcpu); enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer); +#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS +int kvm_arch_flush_remote_tlbs(struct kvm *kvm); void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot); void kvm_init_vmcs(struct kvm *kvm); void kvm_exc_entry(void); diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c index 7b3661da8958..86b1af823e2b 100644 --- a/arch/loongarch/kvm/main.c +++ b/arch/loongarch/kvm/main.c @@ -322,6 +322,8 @@ static void kvm_check_vmid(struct kvm_vcpu *vcpu) cpu = smp_processor_id(); context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu); + if (cpumask_test_and_clear_cpu(cpu, &vcpu->kvm->arch.tlb_flush_pending)) + vcpu->kvm->arch.vmid[cpu] = 0; /* * Check if our vmid is of an older version diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c index e104897aa532..560a2d0f111f 100644 --- a/arch/loongarch/kvm/mmu.c +++ b/arch/loongarch/kvm/mmu.c @@ -940,6 +940,22 @@ void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot) { } +int kvm_arch_flush_remote_tlbs(struct kvm *kvm) +{ + /* + * Queue a TLB invalidation for each CPU to perform on next + * vcpu loading + */ + if (cpu_has_guestid) { + cpumask_setall(&kvm->arch.tlb_flush_pending); + /* Be sure that other CPUS can watch the changes */ + smp_wmb(); + } + + /* Return 1 continue to send ipi to running vCPUs */ + return 1; +} + void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot) { diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 20c207d80e31..19c81ae8941a 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -210,7 +210,12 @@ static int kvm_check_requests(struct kvm_vcpu *vcpu) return RESUME_GUEST; if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu)) - vcpu->arch.vpid = 0; /* Drop vpid for this vCPU */ + /* + * vpid need the same with vmid if vpid is not separated + * with vmid + */ + if (!cpu_has_guestid) + vcpu->arch.vpid = 0; /* Drop vpid for this vCPU */ if (kvm_dirty_ring_check_request(vcpu)) return RESUME_HOST; -- 2.39.3