Re: [PATCH 4/6] LoongArch: KVM: implement vmid updating logic

From: Huacai Chen

Date: Sun Aug 02 2026 - 10:14:04 EST


Hi, BIbo,

On Mon, Jul 27, 2026 at 3:30 PM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
>
> For every physical CPU, there is one vmid calculation method. For
> vCPUs on the same VM, vmid is the same. However for vCPUs on
> different VM, vmid is different. When vCPU is scheduled on the
> physical CPU, it checked vmid of this VM and the global cached
> vmid, and judge whether it is valid or not.
I think Patch#2/3/4 can be folded into one.


Huacai

>
> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> ---
> arch/loongarch/include/asm/kvm_host.h | 2 ++
> arch/loongarch/kvm/main.c | 42 ++++++++++++++++++++++++++-
> 2 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
> index e93307cbe740..a01623c42c7a 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -79,6 +79,7 @@ struct kvm_arch_memory_slot {
> #define HOST_MAX_PMNUM 16
> struct kvm_context {
> unsigned long vpid_cache;
> + unsigned long vmid_cache;
> struct kvm_vcpu *last_vcpu;
> /* Host PMU CSR */
> u64 perf_ctrl[HOST_MAX_PMNUM];
> @@ -132,6 +133,7 @@ struct kvm_arch {
> unsigned long kvm_features;
>
> s64 time_offset;
> + unsigned long vmid[NR_CPUS];
> struct kvm_context __percpu *vmcs;
> struct loongarch_ipi *ipi;
> struct loongarch_dmsintc *dmsintc;
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index 3df46e02594f..7b3661da8958 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -281,9 +281,33 @@ static void kvm_check_vcpuid(struct kvm_vcpu *vcpu)
> }
> }
>
> -static void kvm_check_vmid(struct kvm_vcpu *vcpu)
> +static void kvm_update_vmid(struct kvm_vcpu *vcpu, int cpu)
> {
> unsigned long vmid;
> + struct kvm_context *context;
> +
> + context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu);
> + vmid = context->vmid_cache + 1;
> + if (!(vmid & vpid_mask)) {
> + /* finish round of vmid loop */
> + if (unlikely(!vmid))
> + vmid = vpid_mask + 1;
> +
> + ++vmid; /* vmid 0 reserved for root */
> +
> + /* start new vmid cycle */
> + kvm_flush_tlb_all_stage2();
> + }
> +
> + context->vmid_cache = vmid;
> + vcpu->kvm->arch.vmid[cpu] = vmid;
> +}
> +
> +static void kvm_check_vmid(struct kvm_vcpu *vcpu)
> +{
> + int cpu;
> + unsigned long ver, old, vmid;
> + struct kvm_context *context;
>
> /* On some machines like 3A5000, vmid needs the same with vpid */
> if (!cpu_has_guestid) {
> @@ -295,6 +319,21 @@ static void kvm_check_vmid(struct kvm_vcpu *vcpu)
>
> return;
> }
> +
> + cpu = smp_processor_id();
> + context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu);
> +
> + /*
> + * Check if our vmid is of an older version
> + */
> + ver = vcpu->kvm->arch.vmid[cpu] & ~vpid_mask;
> + old = context->vmid_cache & ~vpid_mask;
> + if (ver != old) {
> + kvm_update_vmid(vcpu, cpu);
> + kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
> + }
> +
> + vcpu->arch.vmid = vcpu->kvm->arch.vmid[cpu] & vpid_mask;
> }
>
> void kvm_check_vpid(struct kvm_vcpu *vcpu)
> @@ -400,6 +439,7 @@ static int kvm_loongarch_env_init(void)
> for_each_possible_cpu(cpu) {
> context = per_cpu_ptr(vmcs, cpu);
> context->vpid_cache = vpid_mask + 1;
> + context->vmid_cache = vpid_mask + 1;
> context->last_vcpu = NULL;
> }
>
> --
> 2.39.3
>