Skip to content

Commit 745ff82

Browse files
committed
KVM: SVM: Require AP's "requested" SEV_FEATURES to match KVM's view
When handling an "AP Create" event, return an error if the "requested" SEV features for the vCPU don't exactly match KVM's view of the VM-scoped features. There is no known use case for heterogeneous SEV features across vCPUs, and while KVM can't actually enforce an exact match since the value in RAX isn't guaranteed to match what the guest shoved into the VMSA, KVM can at least avoid knowingly letting the guest run in an unsupported state. E.g. if a VM is created with DebugSwap disabled, KVM will intercept #DBs and DRs for all vCPUs, even if an AP is "created" with DebugSwap enabled in its VMSA. Note, the GHCB spec only "requires" that "AP use the same interrupt injection mechanism as the BSP", but given the disaster that is DebugSwap and SEV_FEATURES in general, it's safe to say that AMD didn't consider all possible complications with mismatching features between the BSP and APs. Opportunistically fold the check into the relevant request flavors; the "request < AP_DESTROY" check is just a bizarre way of implementing the AP_CREATE_ON_INIT => AP_CREATE fallthrough. Fixes: e366f92 ("KVM: SEV: Support SEV-SNP AP Creation NAE event") Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com> Link: https://lore.kernel.org/r/20250227012541.3234589-6-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent d26638b commit 745ff82

File tree

2 files changed

+8
-19
lines changed

2 files changed

+8
-19
lines changed

arch/x86/include/asm/svm.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,6 @@ static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_
291291
#define SVM_SEV_FEAT_ALTERNATE_INJECTION BIT(4)
292292
#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
293293

294-
#define SVM_SEV_FEAT_INT_INJ_MODES \
295-
(SVM_SEV_FEAT_RESTRICTED_INJECTION | \
296-
SVM_SEV_FEAT_ALTERNATE_INJECTION)
297-
298294
struct vmcb_seg {
299295
u16 selector;
300296
u16 attrib;

arch/x86/kvm/svm/sev.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,6 +3938,7 @@ void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
39383938

39393939
static int sev_snp_ap_creation(struct vcpu_svm *svm)
39403940
{
3941+
struct kvm_sev_info *sev = to_kvm_sev_info(svm->vcpu.kvm);
39413942
struct kvm_vcpu *vcpu = &svm->vcpu;
39423943
struct kvm_vcpu *target_vcpu;
39433944
struct vcpu_svm *target_svm;
@@ -3969,26 +3970,18 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
39693970

39703971
mutex_lock(&target_svm->sev_es.snp_vmsa_mutex);
39713972

3972-
/* Interrupt injection mode shouldn't change for AP creation */
3973-
if (request < SVM_VMGEXIT_AP_DESTROY) {
3974-
u64 sev_features;
3975-
3976-
sev_features = vcpu->arch.regs[VCPU_REGS_RAX];
3977-
sev_features ^= to_kvm_sev_info(svm->vcpu.kvm)->vmsa_features;
3978-
3979-
if (sev_features & SVM_SEV_FEAT_INT_INJ_MODES) {
3980-
vcpu_unimpl(vcpu, "vmgexit: invalid AP injection mode [%#lx] from guest\n",
3981-
vcpu->arch.regs[VCPU_REGS_RAX]);
3982-
ret = -EINVAL;
3983-
goto out;
3984-
}
3985-
}
3986-
39873973
switch (request) {
39883974
case SVM_VMGEXIT_AP_CREATE_ON_INIT:
39893975
kick = false;
39903976
fallthrough;
39913977
case SVM_VMGEXIT_AP_CREATE:
3978+
if (vcpu->arch.regs[VCPU_REGS_RAX] != sev->vmsa_features) {
3979+
vcpu_unimpl(vcpu, "vmgexit: mismatched AP sev_features [%#lx] != [%#llx] from guest\n",
3980+
vcpu->arch.regs[VCPU_REGS_RAX], sev->vmsa_features);
3981+
ret = -EINVAL;
3982+
goto out;
3983+
}
3984+
39923985
if (!page_address_valid(vcpu, svm->vmcb->control.exit_info_2)) {
39933986
vcpu_unimpl(vcpu, "vmgexit: invalid AP VMSA address [%#llx] from guest\n",
39943987
svm->vmcb->control.exit_info_2);

0 commit comments

Comments
 (0)