[PATCH 2/2] KVM: nSVM: Track the ASID generation of the vmcb vmrun through the vmcb
From: Cathy Avery <hidden>
Date: 2021-01-12 16:45:22
Also in:
lkml
Subsystem:
kernel virtual machine for x86 (kvm/x86), the rest, x86 architecture (32-bit and 64-bit) · Maintainers:
Sean Christopherson, Paolo Bonzini, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
This patch moves the asid_generation from the vcpu to the vmcb in order to track the ASID generation that was active the last time the vmcb was run. If sd->asid_generation changes between two runs, the old ASID is invalid and must be changed. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Cathy Avery <redacted> --- arch/x86/kvm/svm/svm.c | 21 +++++++-------------- arch/x86/kvm/svm/svm.h | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 5b6998ff7aa1..73e63f7a0acf 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c@@ -1214,7 +1214,7 @@ static void init_vmcb(struct vcpu_svm *svm) save->cr3 = 0; save->cr4 = 0; } - svm->asid_generation = 0; + svm->current_vmcb->asid_generation = 0; svm->asid = 0; svm->nested.vmcb12_gpa = 0;
@@ -1296,13 +1296,6 @@ void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb) svm->vmcb = target_vmcb->ptr; svm->vmcb_pa = target_vmcb->pa; - /* - * Workaround: we don't yet track the ASID generation - * that was active the last time target_vmcb was run. - */ - - svm->asid_generation = 0; - /* * Track the physical CPU the target_vmcb is running on * in order to mark the VMCB dirty if the cpu changes at
@@ -1347,7 +1340,6 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) svm_switch_vmcb(svm, &svm->vmcb01); - svm->asid_generation = 0; init_vmcb(svm); svm_init_osvw(vcpu);
@@ -1784,7 +1776,7 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) vmcb_mark_dirty(svm->vmcb, VMCB_ASID); } - svm->asid_generation = sd->asid_generation; + svm->current_vmcb->asid_generation = sd->asid_generation; svm->asid = sd->next_asid++; }
@@ -3179,11 +3171,12 @@ static void pre_svm_run(struct vcpu_svm *svm) /* * If the previous vmrun of the vmcb occurred on - * a different physical cpu then we must mark the vmcb dirty. + * a different physical cpu then we must mark the vmcb dirty, + * update the asid_generation, and assign a new asid. */ if (unlikely(svm->current_vmcb->cpu != svm->vcpu.cpu)) { - svm->asid_generation = 0; + svm->current_vmcb->asid_generation = 0; vmcb_mark_all_dirty(svm->vmcb); svm->current_vmcb->cpu = svm->vcpu.cpu; }
@@ -3192,7 +3185,7 @@ static void pre_svm_run(struct vcpu_svm *svm) return pre_sev_run(svm, svm->vcpu.cpu); /* FIXME: handle wraparound of asid_generation */ - if (svm->asid_generation != sd->asid_generation) + if (svm->current_vmcb->asid_generation != sd->asid_generation) new_asid(svm, sd); }
@@ -3399,7 +3392,7 @@ void svm_flush_tlb(struct kvm_vcpu *vcpu) if (static_cpu_has(X86_FEATURE_FLUSHBYASID)) svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID; else - svm->asid_generation--; + svm->current_vmcb->asid_generation--; } static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 05baee934d03..edcfc2a4e77e 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h@@ -86,6 +86,7 @@ struct kvm_vmcb_info { struct vmcb *ptr; unsigned long pa; int cpu; + uint64_t asid_generation; }; struct svm_nested_state {
@@ -115,7 +116,6 @@ struct vcpu_svm { struct kvm_vmcb_info *current_vmcb; struct svm_cpu_data *svm_data; u32 asid; - uint64_t asid_generation; uint64_t sysenter_esp; uint64_t sysenter_eip; uint64_t tsc_aux;
--
2.20.1