[PATCH 3/6] LoongArch: KVM: Add separate vmid feature support
Bibo Mao <[email protected]> Mon, 27 Jul 2026 15:21:06 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Feature cpu_has_guestid is used to check whether separate vmid/vpid is supported or not. Also add different vmid updating function. Signed-off-by: Bibo Mao <[email protected]> --- arch/loongarch/include/asm/kvm_host.h | 2 ++ arch/loongarch/kvm/main.c | 18 +++++++++++++----- arch/loongarch/kvm/tlb.c | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index ec7b0c402385..e93307cbe740 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -319,6 +319,8 @@ bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); /* MMU handling */ +void kvm_flush_tlb_all_stage1(void); +void kvm_flush_tlb_all_stage2(void); void kvm_flush_tlb_all(void); void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa); int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long badv, bool write, int ecode); diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c index c1e1d8424fa7..3df46e02594f 100644 --- a/arch/loongarch/kvm/main.c +++ b/arch/loongarch/kvm/main.c @@ -218,7 +218,10 @@ static void kvm_update_vpid(struct kvm_vcpu *vcpu, int cpu) ++vpid; /* vpid 0 reserved for root */ /* start new vpid cycle */ - kvm_flush_tlb_all(); + if (!cpu_has_guestid) + kvm_flush_tlb_all(); + else + kvm_flush_tlb_all_stage1(); } context->vpid_cache = vpid; @@ -282,10 +285,15 @@ static void kvm_check_vmid(struct kvm_vcpu *vcpu) { unsigned long vmid; - vmid = vcpu->arch.vpid & vpid_mask; - if (vcpu->arch.vmid != vmid) { - vcpu->arch.vmid = vmid; - kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu); + /* On some machines like 3A5000, vmid needs the same with vpid */ + if (!cpu_has_guestid) { + vmid = vcpu->arch.vpid & vpid_mask; + if (vcpu->arch.vmid != vmid) { + vcpu->arch.vmid = vmid; + kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu); + } + + return; } } diff --git a/arch/loongarch/kvm/tlb.c b/arch/loongarch/kvm/tlb.c index 38daf936021d..1d95e2208e82 100644 --- a/arch/loongarch/kvm/tlb.c +++ b/arch/loongarch/kvm/tlb.c @@ -21,6 +21,20 @@ void kvm_flush_tlb_all(void) local_irq_restore(flags); } +/* Invalidate all stage1 TLB entries including GVA-->GPA mappings */ +void kvm_flush_tlb_all_stage1(void) +{ + lockdep_assert_irqs_disabled(); + invtlb_all(INVGTLB_ALLGID_GVA_TO_GPA, 0, 0); +} + +/* Invalidate all stage2 TLB entries including GPA-->HPA mappings */ +void kvm_flush_tlb_all_stage2(void) +{ + lockdep_assert_irqs_disabled(); + invtlb_all(INVTLB_ALLGID_GPA_TO_HPA, 0, 0); +} + void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa) { unsigned int vmid; -- 2.39.3