Track the guest as having a guest-provided VMSA as soon as control.vmsa_pa is invalidated, instead of waiting to see if the guest-provided VMSA is usable, so that KVM doesn't switch back to the original VMSA instead of exiting to userspace (due to an invalid VMSA). By the time a vCPU tries to load a guest-provided VMSA, KVM has already communicated "success" for AP creation, i.e. KVM has committed to using the guest-provided VMSA. Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/sev.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 04be49b1af57..7e06ed16f474 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -4001,23 +4001,6 @@ static void __sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa) */ vmcb_mark_all_dirty(svm->vmcb); - if (!VALID_PAGE(gpa)) - return; - - slot = gfn_to_memslot(vcpu->kvm, gfn); - if (!slot) - return; - - mmu_seq = kvm->mmu_invalidate_seq; - smp_rmb(); - - /* - * The new VMSA will be private memory guest memory, so retrieve the - * PFN from the gmem backend. - */ - if (kvm_gmem_get_pfn(vcpu->kvm, slot, gfn, &pfn, &page, NULL)) - return; - /* * From this point forward, the VMSA will always be a guest-mapped page * rather than the initial one allocated by KVM in svm->sev_es.vmsa. In @@ -4029,6 +4012,23 @@ static void __sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa) */ svm->sev_es.snp_has_guest_vmsa = true; + if (!VALID_PAGE(gpa)) + return; + + slot = gfn_to_memslot(vcpu->kvm, gfn); + if (!slot) + return; + + mmu_seq = kvm->mmu_invalidate_seq; + smp_rmb(); + + /* + * The new VMSA will be private memory guest memory, so retrieve the + * PFN from the gmem backend. + */ + if (kvm_gmem_get_pfn(vcpu->kvm, slot, gfn, &pfn, &page, NULL)) + return; + read_lock(&kvm->mmu_lock); /* * Save the guest-provided GPA. If retry is needed, then KVM will try -- 2.55.0.rc0.799.gd6f94ed593-goog