[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <95d863d50c0984058b37681271a2034e65edcb89.1724795971.git.thomas.lendacky@amd.com>
Date: Tue, 27 Aug 2024 16:59:28 -0500
From: Tom Lendacky <thomas.lendacky@....com>
To: <kvm@...r.kernel.org>, <linux-kernel@...r.kernel.org>, <x86@...nel.org>,
<linux-coco@...ts.linux.dev>
CC: Paolo Bonzini <pbonzini@...hat.com>, Sean Christopherson
<seanjc@...gle.com>, Borislav Petkov <bp@...en8.de>, Dave Hansen
<dave.hansen@...ux.intel.com>, Ingo Molnar <mingo@...hat.com>, "Thomas
Gleixner" <tglx@...utronix.de>, Michael Roth <michael.roth@....com>, "Ashish
Kalra" <ashish.kalra@....com>, Joerg Roedel <jroedel@...e.de>, Roy Hopkins
<roy.hopkins@...e.com>, Carlos Bilbao <carlos.bilbao@....com>
Subject: [RFC PATCH 4/7] KVM: SVM: Maintain per-VMPL SEV features in kvm_sev_info
From: Carlos Bilbao <carlos.bilbao@....com>
Make struct kvm_sev_info maintain separate SEV features per VMPL, allowing
distinct SEV features depending on VMs privilege level.
Signed-off-by: Carlos Bilbao <carlos.bilbao@....com>
Signed-off-by: Tom Lendacky <thomas.lendacky@....com>
---
arch/x86/kvm/svm/sev.c | 22 +++++++++++++++-------
arch/x86/kvm/svm/svm.h | 4 ++--
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index e0f5122061e6..c6c9306c86ef 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -144,7 +144,7 @@ static bool sev_vcpu_has_debug_swap(struct vcpu_svm *svm)
struct kvm_vcpu *vcpu = &svm->vcpu;
struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info;
- return sev->vmsa_features & SVM_SEV_FEAT_DEBUG_SWAP;
+ return sev->vmsa_features[cur_vmpl(svm)] & SVM_SEV_FEAT_DEBUG_SWAP;
}
/* Must be called with the sev_bitmap_lock held */
@@ -428,7 +428,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
sev->active = true;
sev->es_active = es_active;
- sev->vmsa_features = data->vmsa_features;
+ sev->vmsa_features[SVM_SEV_VMPL0] = data->vmsa_features;
sev->ghcb_version = data->ghcb_version;
/*
@@ -440,7 +440,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
sev->ghcb_version = GHCB_VERSION_DEFAULT;
if (vm_type == KVM_X86_SNP_VM)
- sev->vmsa_features |= SVM_SEV_FEAT_SNP_ACTIVE;
+ sev->vmsa_features[SVM_SEV_VMPL0] |= SVM_SEV_FEAT_SNP_ACTIVE;
ret = sev_asid_new(sev);
if (ret)
@@ -468,7 +468,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
sev_asid_free(sev);
sev->asid = 0;
e_no_asid:
- sev->vmsa_features = 0;
+ sev->vmsa_features[SVM_SEV_VMPL0] = 0;
sev->es_active = false;
sev->active = false;
return ret;
@@ -852,7 +852,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
save->xss = svm->vcpu.arch.ia32_xss;
save->dr6 = svm->vcpu.arch.dr6;
- save->sev_features = sev->vmsa_features;
+ save->sev_features = sev->vmsa_features[SVM_SEV_VMPL0];
/*
* Skip FPU and AVX setup with KVM_SEV_ES_INIT to avoid
@@ -1985,7 +1985,7 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
dst->pages_locked = src->pages_locked;
dst->enc_context_owner = src->enc_context_owner;
dst->es_active = src->es_active;
- dst->vmsa_features = src->vmsa_features;
+ memcpy(dst->vmsa_features, src->vmsa_features, sizeof(dst->vmsa_features));
src->asid = 0;
src->active = false;
@@ -4034,8 +4034,16 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
/* Interrupt injection mode shouldn't change for AP creation */
sev_features = vcpu->arch.regs[VCPU_REGS_RAX];
- sev_features ^= sev->vmsa_features;
+ /*
+ * The SNPActive feature must at least be set. If the SEV
+ * features of this AP are zero, this is the first vCPU created at
+ * this VMPL.
+ */
+ if (!sev->vmsa_features[vmpl])
+ sev->vmsa_features[vmpl] = sev_features | SVM_SEV_FEAT_SNP_ACTIVE;
+
+ sev_features ^= sev->vmsa_features[vmpl];
if (sev_features & SVM_SEV_FEAT_INT_INJ_MODES) {
vcpu_unimpl(vcpu, "vmgexit: invalid AP injection mode [%#lx] from guest\n",
vcpu->arch.regs[VCPU_REGS_RAX]);
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index d1ef349556f7..55f1f6ffb871 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -87,7 +87,7 @@ struct kvm_sev_info {
unsigned long pages_locked; /* Number of pages locked */
struct list_head regions_list; /* List of registered regions */
u64 ap_jump_table; /* SEV-ES AP Jump Table address */
- u64 vmsa_features;
+ u64 vmsa_features[SVM_SEV_VMPL_MAX];
u16 ghcb_version; /* Highest guest GHCB protocol version allowed */
struct kvm *enc_context_owner; /* Owner of copied encryption context */
struct list_head mirror_vms; /* List of VMs mirroring */
@@ -416,7 +416,7 @@ static __always_inline bool sev_snp_guest(struct kvm *kvm)
#ifdef CONFIG_KVM_AMD_SEV
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
- return (sev->vmsa_features & SVM_SEV_FEAT_SNP_ACTIVE) &&
+ return (sev->vmsa_features[SVM_SEV_VMPL0] & SVM_SEV_FEAT_SNP_ACTIVE) &&
!WARN_ON_ONCE(!sev_es_guest(kvm));
#else
return false;
--
2.43.2
Powered by blists - more mailing lists