]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: KVM: Move host CSR_GSTAT save and restore in context switch
authorBibo Mao <maobibo@loongson.cn>
Thu, 9 Apr 2026 10:56:36 +0000 (18:56 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Thu, 9 Apr 2026 10:56:36 +0000 (18:56 +0800)
CSR register LOONGARCH_CSR_GSTAT stores guest VMID information. With
existing implementation method, VMID is per vCPU, similar with ASID in
kernel. LOONGARCH_CSR_GSTAT is written at VM entry even if VMID is not
changed.

Here move LOONGARCH_CSR_GSTAT save/restore in vCPU context switch, and
update LOONGARCH_CSR_GSTAT only when VMID is updated at VM entry. At
most time VM enter/exit is much more frequent than vCPU thread context
switch.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kvm/main.c
arch/loongarch/kvm/vcpu.c

index 2c593ac7892f6c294a3bd93d132793a831d9ffce..304c83863e7124fcd5673b0610687ab2dc5ce3e2 100644 (file)
@@ -271,11 +271,11 @@ void kvm_check_vpid(struct kvm_vcpu *vcpu)
                 * memory with new address is changed on other VCPUs.
                 */
                set_gcsr_llbctl(CSR_LLBCTL_WCLLB);
-       }
 
-       /* Restore GSTAT(0x50).vpid */
-       vpid = (vcpu->arch.vpid & vpid_mask) << CSR_GSTAT_GID_SHIFT;
-       change_csr_gstat(vpid_mask << CSR_GSTAT_GID_SHIFT, vpid);
+               /* Restore GSTAT(0x50).vpid */
+               vpid = (vcpu->arch.vpid & vpid_mask) << CSR_GSTAT_GID_SHIFT;
+               change_csr_gstat(vpid_mask << CSR_GSTAT_GID_SHIFT, vpid);
+       }
 }
 
 void kvm_init_vmcs(struct kvm *kvm)
index 3367a9886b63743fd1c527aa6e739e520152a20d..e28084c49e6820180b6e653ea834abaa215962ed 100644 (file)
@@ -1699,6 +1699,7 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
        /* Restore Root.GINTC from unused Guest.GINTC register */
        write_csr_gintc(csr->csrs[LOONGARCH_CSR_GINTC]);
+       write_csr_gstat(csr->csrs[LOONGARCH_CSR_GSTAT]);
 
        /*
         * We should clear linked load bit to break interrupted atomics. This
@@ -1794,6 +1795,7 @@ static int _kvm_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
                kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR3);
        }
 
+       csr->csrs[LOONGARCH_CSR_GSTAT] = read_csr_gstat();
        vcpu->arch.aux_inuse |= KVM_LARCH_SWCSR_LATEST;
 
 out: