Re: [PATCH 3/4] kvm: svm: Support guest-provided VMSA for launching
Sean Christopherson <[email protected]> Tue, 23 Jun 2026 14:07:59 -0700
| Newsgroups | dev.linux.lists.coconut-svsm,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jun 11, 2026, J=C3=B6rg R=C3=B6del wrote: > From: Joerg Roedel <[email protected]> >=20 > Introduce a way to provide a guest GPA as the initial BSP VMSA and > avoid allocating KVM-managed VMSAs in this case. Only one > guest-provided VMSA is supported at the moment as IGVM also only No. Design uAPI that makes sense for KVM and is extensible. If it turns o= ut that allowing exactly one VMSA is the simplest, most logical approach, then= so be it. But "thing X only needs Y" isn't sufficient justification. But I'm not remotely convinced that hacking in BSP-only support like this i= s the way to go. This entire approach is convoluted, as is the code. E.g. t= he below iterates over all vCPUs, but then only actually does anything for vcp= u_idx=3D0. And the ioctl is VM-scoped, but really operates on a vCPU. At a (very rough) glance, I don't see any reason we can't have a vCPU-scope= d ioctl to effectively mimic SVM_VMGEXIT_AP_CREATE. > supports to set a single VMSA. >=20 > Signed-off-by: Joerg Roedel <[email protected]> > --- > arch/x86/kvm/svm/sev.c | 62 ++++++++++++++++++++++++++++++------------ > arch/x86/kvm/svm/svm.h | 1 + > 2 files changed, 45 insertions(+), 18 deletions(-) >=20 > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 350bb97c32c0..88db83b3ff8e 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -726,6 +726,7 @@ static int __sev_guest_init(struct kvm *kvm, struct k= vm_sev_cmd *argp, > =20 > INIT_LIST_HEAD(&sev->regions_list); > INIT_LIST_HEAD(&sev->mirror_vms); > + sev->initial_vmsa_gpa =3D INVALID_PAGE; > sev->need_init =3D false; > =20 > kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_SEV); > @@ -2680,6 +2681,46 @@ static int snp_launch_update(struct kvm *kvm, stru= ct kvm_sev_cmd *argp) > return 0; > } > =20 > +static int snp_init_guest_vmsa(struct kvm_vcpu *vcpu, gpa_t vmsa_gpa) > +{ > + /* Only one initial guest VMSA can exist (per IGVM) - so it belongs to = the BSP */ > + if (vcpu->vcpu_idx !=3D 0) > + return 0; > + > + /* VMSA already private and encrypted via LAUNCH_UPDATE */ > + sev_es_set_guest_vmsa(vcpu, vmsa_gpa); > + > + return 0; > +} > + > +static int snp_init_kvm_vmsa(struct kvm_vcpu *vcpu, > + struct sev_data_snp_launch_update *data, > + struct kvm_sev_cmd *argp) > +{ > + struct vcpu_svm *svm =3D to_svm(vcpu); > + int ret; > + void *vmsa; > + > + ret =3D sev_es_sync_vmsa(svm); > + if (ret) > + return ret; > + > + vmsa =3D sev_es_vmsa_ref(vcpu); > + > + ret =3D sev_es_vcpu_vmsa_make_private(vcpu); > + if (ret) > + return ret; > + > + /* Issue the SNP command to encrypt the VMSA */ > + data->address =3D __sme_pa(vmsa); > + ret =3D __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_UPDATE, > + data, &argp->error); > + if (ret) > + sev_snp_vcpu_reclaim_vmsa(vcpu); > + > + return ret; Separate code movement from new functi0onality. > +} > + > static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *a= rgp) > { > struct kvm_sev_info *sev =3D to_kvm_sev_info(kvm); > @@ -2700,28 +2741,13 @@ static int snp_launch_update_vmsa(struct kvm *kvm= , struct kvm_sev_cmd *argp) > =20 > kvm_for_each_vcpu(i, vcpu, kvm) { > struct vcpu_svm *svm =3D to_svm(vcpu); > - void *vmsa; > =20 > - ret =3D sev_es_sync_vmsa(svm); > + ret =3D VALID_PAGE(sev->initial_vmsa_gpa) ? > + snp_init_guest_vmsa(vcpu, sev->initial_vmsa_gpa) : > + snp_init_kvm_vmsa(vcpu, &data, argp); > if (ret) > goto out; > =20 > - vmsa =3D sev_es_vmsa_ref(vcpu); > - > - ret =3D sev_es_vcpu_vmsa_make_private(vcpu); > - if (ret) > - goto out; > - > - /* Issue the SNP command to encrypt the VMSA */ > - data.address =3D __sme_pa(vmsa); > - ret =3D __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_UPDATE, > - &data, &argp->error); > - if (ret) { > - sev_snp_vcpu_reclaim_vmsa(vcpu); > - > - goto out; > - } > - > svm->vcpu.arch.guest_state_protected =3D true; > =20 > /* VMSA encrypted - put it into the VMCB */ > diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h > index 3d4799f09b23..cc7e84c230bb 100644 > --- a/arch/x86/kvm/svm/svm.h > +++ b/arch/x86/kvm/svm/svm.h > @@ -117,6 +117,7 @@ struct kvm_sev_info { > struct mutex guest_req_mutex; /* Must acquire before using bounce buffe= rs */ > cpumask_var_t have_run_cpus; /* CPUs that have done VMRUN for this VM. = */ > bool snp_certs_enabled; /* SNP certificate-fetching support. */ > + gpa_t initial_vmsa_gpa; /* Optinal GPA of BSP VMSA - SEV-SNP only */ > }; > #endif > =20 > --=20 > 2.53.0 >=20