KVM: SVM: Move asid to vcpu_svm
authorCathy Avery <cavery@redhat.com>
Sun, 11 Oct 2020 18:48:17 +0000 (14:48 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 16 Nov 2020 18:14:21 +0000 (13:14 -0500)
KVM does not have separate ASIDs for L1 and L2; either the nested
hypervisor and nested guests share a single ASID, or on older processor
the ASID is used only to implement TLB flushing.

Either way, ASIDs are handled at the VM level.  In preparation
for having different VMCBs passed to VMLOAD/VMRUN/VMSAVE for L1 and
L2, store the current ASID to struct vcpu_svm and only move it to
the VMCB in svm_vcpu_run.  This way, TLB flushes can be applied
no matter which VMCB will be active during the next svm_vcpu_run.

Signed-off-by: Cathy Avery <cavery@redhat.com>
Message-Id: <20201011184818.3609-2-cavery@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index 2538092..3b53a7e 100644 (file)
@@ -1215,6 +1215,7 @@ static void init_vmcb(struct vcpu_svm *svm)
                save->cr4 = 0;
        }
        svm->asid_generation = 0;
+       svm->asid = 0;
 
        svm->nested.vmcb12_gpa = 0;
        svm->vcpu.arch.hflags = 0;
@@ -1755,12 +1756,11 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
                ++sd->asid_generation;
                sd->next_asid = sd->min_asid;
                svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
+               vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
        }
 
        svm->asid_generation = sd->asid_generation;
-       svm->vmcb->control.asid = sd->next_asid++;
-
-       vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
+       svm->asid = sd->next_asid++;
 }
 
 static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value)
@@ -3570,6 +3570,10 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
 
        sync_lapic_to_cr8(vcpu);
 
+       if (unlikely(svm->asid != svm->vmcb->control.asid)) {
+               svm->vmcb->control.asid = svm->asid;
+               vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
+       }
        svm->vmcb->save.cr2 = vcpu->arch.cr2;
 
        /*
index eb6fbaf..fdff76e 100644 (file)
@@ -106,6 +106,7 @@ struct vcpu_svm {
        struct vmcb *vmcb;
        unsigned long vmcb_pa;
        struct svm_cpu_data *svm_data;
+       u32 asid;
        uint64_t asid_generation;
        uint64_t sysenter_esp;
        uint64_t sysenter_eip;