[<prev] [next>] [day] [month] [year] [list]
Message-ID: <82c78d1b-116c-4456-bf8f-a441a97b3def@fortanix.com>
Date: Mon, 19 Jan 2026 20:12:16 +0100
From: Jethro Beekman <jethro@...tanix.com>
To: Sean Christopherson <seanjc@...gle.com>,
Paolo Bonzini <pbonzini@...hat.com>, Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...ux.intel.com>, x86@...nel.org,
"H. Peter Anvin" <hpa@...or.com>, kvm@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-coco@...ts.linux.dev
Subject: [PATCH] KVM: SEV: Enable SNP AP CPU hotplug
The GHCB protocol states that after AP CREATE (as opposed to CREATE_ON_INIT),
the hypervisor must immediately proceed to VMRUN. Update vCPU state on AP
CREATE so this happens.
vCPUs created after SNP_LAUNCH_FINISH don't go through snp_launch_update_vmsa.
Ensure the vCPU state is updated properly during VMCB initialization.
Signed-off-by: Jethro Beekman <jethro@...tanix.com>
---
arch/x86/kvm/svm/sev.c | 43 ++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index cdaca10b8773..9af1bd5b2071 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -960,6 +960,19 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
return 0;
}
+static void sev_es_finalize_vcpu(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.guest_state_protected = true;
+ /*
+ * SEV-ES (and thus SNP) guest mandates LBR Virtualization to
+ * be _always_ ON. Enable it only after setting
+ * guest_state_protected because KVM_SET_MSRS allows dynamic
+ * toggling of LBRV (for performance reason) on write access to
+ * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+ */
+ svm_enable_lbrv(vcpu);
+}
+
static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
int *error)
{
@@ -999,15 +1012,9 @@ static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
* do xsave/xrstor on it.
*/
fpstate_set_confidential(&vcpu->arch.guest_fpu);
- vcpu->arch.guest_state_protected = true;
- /*
- * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it
- * only after setting guest_state_protected because KVM_SET_MSRS allows
- * dynamic toggling of LBRV (for performance reason) on write access to
- * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
- */
- svm_enable_lbrv(vcpu);
+ sev_es_finalize_vcpu(vcpu);
+
return 0;
}
@@ -2480,15 +2487,7 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
return ret;
}
- svm->vcpu.arch.guest_state_protected = true;
- /*
- * SEV-ES (and thus SNP) guest mandates LBR Virtualization to
- * be _always_ ON. Enable it only after setting
- * guest_state_protected because KVM_SET_MSRS allows dynamic
- * toggling of LBRV (for performance reason) on write access to
- * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
- */
- svm_enable_lbrv(vcpu);
+ sev_es_finalize_vcpu(vcpu);
}
return 0;
@@ -4030,6 +4029,10 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
/* Use the new VMSA */
svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
+ /* vCPU was added after SNP_LAUNCH_FINISH */
+ if (!vcpu->arch.guest_state_protected)
+ sev_es_finalize_vcpu(vcpu);
+
/* Mark the vCPU as runnable */
kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
@@ -4111,8 +4114,12 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
* Unless Creation is deferred until INIT, signal the vCPU to update
* its state.
*/
- if (request != SVM_VMGEXIT_AP_CREATE_ON_INIT)
+ if (request != SVM_VMGEXIT_AP_CREATE_ON_INIT) {
+ if (target_vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED ||
+ target_vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED)
+ kvm_set_mp_state(target_vcpu, KVM_MP_STATE_RUNNABLE);
kvm_make_request_and_kick(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, target_vcpu);
+ }
return 0;
}
--
2.43.0
Download attachment "smime.p7s" of type "application/pkcs7-signature" (4839 bytes)
Powered by blists - more mailing lists