Re: [PATCH v3 02/12] KVM: SEV: Extract loading of guest-provided VMSA to a separate helper

From: Michael Roth

Date: Wed Jul 01 2026 - 18:51:00 EST


On Tue, Jun 30, 2026 at 03:25:57PM -0700, Sean Christopherson wrote:
> Extract the loading/retrieval of a guest-provided VMSA to a separate helper
> so that KVM can reuse the core logic when refreshing the VMSA after an MMU
> invalidation from guest_memfd.
>
> No functional change intended.
>
> Cc: stable@xxxxxxxxxxxxxxx # 6.12.x
> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>

Reviewed-by: Michael Roth <michael.roth@xxxxxxx>

> ---
> arch/x86/kvm/svm/sev.c | 52 +++++++++++++++++++++++++-----------------
> 1 file changed, 31 insertions(+), 21 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 827f5dc06102..d8ed00f76aa3 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -3979,29 +3979,17 @@ static int snp_begin_psc(struct vcpu_svm *svm)
> return snp_do_psc(svm);
> }
>
> -/*
> - * Invoked as part of svm_vcpu_reset() processing of an init event.
> - */
> -static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
> +static void sev_snp_reload_vmsa(struct kvm_vcpu *vcpu, gpa_t gpa)
> {
> struct vcpu_svm *svm = to_svm(vcpu);
> struct kvm_memory_slot *slot;
> + gfn_t gfn = gpa_to_gfn(gpa);
> struct page *page;
> kvm_pfn_t pfn;
> - gfn_t gfn;
>
> - guard(mutex)(&svm->sev_es.snp_vmsa_mutex);
> + lockdep_assert_held(&svm->sev_es.snp_vmsa_mutex);
>
> - if (!svm->sev_es.snp_ap_waiting_for_reset)
> - return;
> -
> - svm->sev_es.snp_ap_waiting_for_reset = false;
> -
> - /* Mark the vCPU as offline and not runnable */
> - vcpu->arch.pv.pv_unhalted = false;
> - kvm_set_mp_state(vcpu, KVM_MP_STATE_HALTED);
> -
> - /* Clear use of the VMSA */
> + /* Clear use of the VMSA. */
> svm->vmcb->control.vmsa_pa = INVALID_PAGE;
> svm->sev_es.snp_guest_vmsa_gpa = INVALID_PAGE;
>
> @@ -4011,12 +3999,9 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
> */
> vmcb_mark_all_dirty(svm->vmcb);
>
> - if (!VALID_PAGE(svm->sev_es.snp_pending_vmsa_gpa))
> + if (!VALID_PAGE(gpa))
> return;
>
> - gfn = gpa_to_gfn(svm->sev_es.snp_pending_vmsa_gpa);
> - svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
> -
> slot = gfn_to_memslot(vcpu->kvm, gfn);
> if (!slot)
> return;
> @@ -4040,7 +4025,7 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
> svm->sev_es.snp_has_guest_vmsa = true;
>
> /* Use the new VMSA */
> - svm->sev_es.snp_guest_vmsa_gpa = gfn_to_gpa(gfn);
> + svm->sev_es.snp_guest_vmsa_gpa = gpa;
> svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
>
> /* Mark the vCPU as runnable */
> @@ -4054,6 +4039,31 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
> kvm_release_page_clean(page);
> }
>
> +/*
> + * Invoked as part of svm_vcpu_reset() processing of an init event.
> + */
> +static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
> +{
> + struct vcpu_svm *svm = to_svm(vcpu);
> + gpa_t gpa;
> +
> + guard(mutex)(&svm->sev_es.snp_vmsa_mutex);
> +
> + if (!svm->sev_es.snp_ap_waiting_for_reset)
> + return;
> +
> + svm->sev_es.snp_ap_waiting_for_reset = false;
> +
> + /* Mark the vCPU as offline and not runnable */
> + vcpu->arch.pv.pv_unhalted = false;
> + kvm_set_mp_state(vcpu, KVM_MP_STATE_HALTED);
> +
> + gpa = svm->sev_es.snp_pending_vmsa_gpa;
> + svm->sev_es.snp_pending_vmsa_gpa = INVALID_PAGE;
> +
> + sev_snp_reload_vmsa(vcpu, gpa);
> +}
> +
> static int sev_snp_ap_creation(struct vcpu_svm *svm)
> {
> struct kvm_sev_info *sev = to_kvm_sev_info(svm->vcpu.kvm);
> --
> 2.55.0.rc0.799.gd6f94ed593-goog
>