diff mbox series

[2/2] KVM: SEV: Configure "ALLOWED_SEV_FEATURES" VMCB Field

Message ID 20240802015732.3192877-3-kim.phillips@amd.com (mailing list archive)
State New, archived
Headers show
Series KVM: SEV: Add support for the ALLOWED_SEV_FEATURES feature | expand

Commit Message

Kim Phillips Aug. 2, 2024, 1:57 a.m. UTC
From: Kishon Vijay Abraham I <kvijayab@amd.com>

AMD EPYC 5th generation processors have introduced a feature that allows
the hypervisor to control the SEV_FEATURES that are set for or by a
guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
hypervisor does not want to be enabled.

When ALLOWED_SEV_FEATURES is enabled, a VMRUN will fail if any
non-reserved bits are 1 in SEV_FEATURES but are 0 in
ALLOWED_SEV_FEATURES.

[1] Section 15.36.20 "Allowed SEV Features", AMD64 Architecture
    Programmer's Manual, Pub. 24593 Rev. 3.42 - March 2024:
    https://bugzilla.kernel.org/attachment.cgi?id=306250

Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kim Phillips <kim.phillips@amd.com>
---
 arch/x86/include/asm/svm.h | 6 +++++-
 arch/x86/kvm/svm/sev.c     | 5 +++++
 2 files changed, 10 insertions(+), 1 deletion(-)

Comments

Nikunj A. Dadhania Aug. 9, 2024, 9:34 a.m. UTC | #1
On 8/2/2024 7:27 AM, Kim Phillips wrote:
> From: Kishon Vijay Abraham I <kvijayab@amd.com>
> 
> AMD EPYC 5th generation processors have introduced a feature that allows
> the hypervisor to control the SEV_FEATURES that are set for or by a
> guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
> to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
> hypervisor does not want to be enabled.
> 
> When ALLOWED_SEV_FEATURES is enabled, a VMRUN will fail if any
> non-reserved bits are 1 in SEV_FEATURES but are 0 in
> ALLOWED_SEV_FEATURES.
> 
> [1] Section 15.36.20 "Allowed SEV Features", AMD64 Architecture
>     Programmer's Manual, Pub. 24593 Rev. 3.42 - March 2024:
>     https://bugzilla.kernel.org/attachment.cgi?id=306250
> 
> Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
> Signed-off-by: Kim Phillips <kim.phillips@amd.com>

Looks good to me.

Reviewed-by: Nikunj A. Dadhania <nikunj@amd.com>

> ---
>  arch/x86/include/asm/svm.h | 6 +++++-
>  arch/x86/kvm/svm/sev.c     | 5 +++++
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
> index f0dea3750ca9..59516ad2028b 100644
> --- a/arch/x86/include/asm/svm.h
> +++ b/arch/x86/include/asm/svm.h
> @@ -158,7 +158,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
>  	u64 avic_physical_id;	/* Offset 0xf8 */
>  	u8 reserved_7[8];
>  	u64 vmsa_pa;		/* Used for an SEV-ES guest */
> -	u8 reserved_8[720];
> +	u8 reserved_8[40];
> +	u64 allowed_sev_features;	/* Offset 0x138 */
> +	u8 reserved_9[672];
>  	/*
>  	 * Offset 0x3e0, 32 bytes reserved
>  	 * for use by hypervisor/software.
> @@ -294,6 +296,8 @@ static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_
>  	(SVM_SEV_FEAT_RESTRICTED_INJECTION |	\
>  	 SVM_SEV_FEAT_ALTERNATE_INJECTION)
>  
> +#define VMCB_ALLOWED_SEV_FEATURES_VALID		BIT_ULL(63)
> +
>  struct vmcb_seg {
>  	u16 selector;
>  	u16 attrib;
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index a16c873b3232..d12b4d615b32 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -899,6 +899,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
>  static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
>  				    int *error)
>  {
> +	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
>  	struct sev_data_launch_update_vmsa vmsa;
>  	struct vcpu_svm *svm = to_svm(vcpu);
>  	int ret;
> @@ -908,6 +909,10 @@ static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
>  		return -EINVAL;
>  	}
>  
> +	if (cpu_feature_enabled(X86_FEATURE_ALLOWED_SEV_FEATURES))
> +		svm->vmcb->control.allowed_sev_features = VMCB_ALLOWED_SEV_FEATURES_VALID |
> +							  sev->vmsa_features;
> +
>  	/* Perform some pre-encryption checks against the VMSA */
>  	ret = sev_es_sync_vmsa(svm);
>  	if (ret)
Sean Christopherson Aug. 16, 2024, 10:59 p.m. UTC | #2
On Thu, Aug 01, 2024, Kim Phillips wrote:
> From: Kishon Vijay Abraham I <kvijayab@amd.com>
> 
> AMD EPYC 5th generation processors have introduced a feature that allows
> the hypervisor to control the SEV_FEATURES that are set for or by a
> guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
> to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
> hypervisor does not want to be enabled.

How does the host communicate to the guest which features are allowed?  And based
on this blurb:

  Some SEV features can only be used if the Allowed SEV Features Mask is enabled,
  and the mask is configured to permit the corresponding feature. If the Allowed
  SEV Features Mask is not enabled, these features are not available (see SEV_FEATURES
  in Appendix B, Table B-4).

and the appendix, this only applies to PmcVirtualization and SecureAvic.  Adding
that info in the changelog would be *very* helpful.

And I see that SVM_SEV_FEAT_DEBUG_SWAP, a.k.a. DebugVirtualization, is a guest
controlled feature and doesn't honor ALLOWED_SEV_FEATURES.  Doesn't that mean
sev_vcpu_has_debug_swap() is broken, i.e. that KVM must assume the guest can
DebugVirtualization on and off at will?  Or am I missing something?
Kim Phillips Aug. 19, 2024, 9:38 p.m. UTC | #3
On 8/16/24 5:59 PM, Sean Christopherson wrote:
> On Thu, Aug 01, 2024, Kim Phillips wrote:
>> From: Kishon Vijay Abraham I <kvijayab@amd.com>
>>
>> AMD EPYC 5th generation processors have introduced a feature that allows
>> the hypervisor to control the SEV_FEATURES that are set for or by a
>> guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
>> to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
>> hypervisor does not want to be enabled.
> 
> How does the host communicate to the guest which features are allowed?

I'm not familiar with any future plans to negotiate with the guest directly,
but since commit ac5c48027bac ("KVM: SEV: publish supported VMSA features"),
userspace can retrieve sev_supported_vmsa_features via an ioctl.

> And based on this blurb:
> 
>    Some SEV features can only be used if the Allowed SEV Features Mask is enabled,
>    and the mask is configured to permit the corresponding feature. If the Allowed
>    SEV Features Mask is not enabled, these features are not available (see SEV_FEATURES
>    in Appendix B, Table B-4).
> 
> and the appendix, this only applies to PmcVirtualization and SecureAvic.  Adding
> that info in the changelog would be *very* helpful.

Ok, how about adding:

"The PmcVirtualization and SecureAvic features explicitly require
ALLOWED_SEV_FEATURES to enable them before they can be used."

> And I see that SVM_SEV_FEAT_DEBUG_SWAP, a.k.a. DebugVirtualization, is a guest
> controlled feature and doesn't honor ALLOWED_SEV_FEATURES.  Doesn't that mean
> sev_vcpu_has_debug_swap() is broken, i.e. that KVM must assume the guest can
> DebugVirtualization on and off at will?  Or am I missing something?

My understanding is that users control KVM's DEBUG_SWAP setting
with a module parameter since commit 4dd5ecacb9a4 ("KVM: SEV: allow
SEV-ES DebugSwap again").  If the module parameter is not set, with
this patch, VMRUN will fail since the host doesn't allow DEBUG_SWAP.

Thanks for your review!

Kim
Sean Christopherson Aug. 19, 2024, 10:23 p.m. UTC | #4
On Mon, Aug 19, 2024, Kim Phillips wrote:
> On 8/16/24 5:59 PM, Sean Christopherson wrote:
> > On Thu, Aug 01, 2024, Kim Phillips wrote:
> > > From: Kishon Vijay Abraham I <kvijayab@amd.com>
> > > 
> > > AMD EPYC 5th generation processors have introduced a feature that allows
> > > the hypervisor to control the SEV_FEATURES that are set for or by a
> > > guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
> > > to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
> > > hypervisor does not want to be enabled.
> > 
> > How does the host communicate to the guest which features are allowed?
> 
> I'm not familiar with any future plans to negotiate with the guest directly,

I feel like I'm missing something.  What happens if the guest wants to enable
PmcVirtualization and it's unexpectedly disallowed?  Does the guest simply panic?

> but since commit ac5c48027bac ("KVM: SEV: publish supported VMSA features"),
> userspace can retrieve sev_supported_vmsa_features via an ioctl.
> 
> > And based on this blurb:
> > 
> >    Some SEV features can only be used if the Allowed SEV Features Mask is enabled,
> >    and the mask is configured to permit the corresponding feature. If the Allowed
> >    SEV Features Mask is not enabled, these features are not available (see SEV_FEATURES
> >    in Appendix B, Table B-4).
> > 
> > and the appendix, this only applies to PmcVirtualization and SecureAvic.  Adding
> > that info in the changelog would be *very* helpful.
> 
> Ok, how about adding:
> 
> "The PmcVirtualization and SecureAvic features explicitly require
> ALLOWED_SEV_FEATURES to enable them before they can be used."
> 
> > And I see that SVM_SEV_FEAT_DEBUG_SWAP, a.k.a. DebugVirtualization, is a guest
> > controlled feature and doesn't honor ALLOWED_SEV_FEATURES.  Doesn't that mean
> > sev_vcpu_has_debug_swap() is broken, i.e. that KVM must assume the guest can
> > DebugVirtualization on and off at will?  Or am I missing something?
> 
> My understanding is that users control KVM's DEBUG_SWAP setting
> with a module parameter since commit 4dd5ecacb9a4 ("KVM: SEV: allow
> SEV-ES DebugSwap again").  If the module parameter is not set, with
> this patch, VMRUN will fail since the host doesn't allow DEBUG_SWAP.

But that's just KVM's view of vmsa_features.  With SNP's wonderful
SVM_VMGEXIT_AP_CREATE, can't the guest create a VMSA with whatever sev_features
it wants, so long as they aren't host-controllable, i.e. aren't PmcVirtualization
or SecureAvic?
Kim Phillips Aug. 20, 2024, 3:26 p.m. UTC | #5
On 8/19/24 5:23 PM, Sean Christopherson wrote:
> On Mon, Aug 19, 2024, Kim Phillips wrote:
>> On 8/16/24 5:59 PM, Sean Christopherson wrote:
>>> On Thu, Aug 01, 2024, Kim Phillips wrote:
>>>> From: Kishon Vijay Abraham I <kvijayab@amd.com>
>>>>
>>>> AMD EPYC 5th generation processors have introduced a feature that allows
>>>> the hypervisor to control the SEV_FEATURES that are set for or by a
>>>> guest [1]. The ALLOWED_SEV_FEATURES feature can be used by the hypervisor
>>>> to enforce that SEV-ES and SEV-SNP guests cannot enable features that the
>>>> hypervisor does not want to be enabled.
>>>
>>> How does the host communicate to the guest which features are allowed?
>>
>> I'm not familiar with any future plans to negotiate with the guest directly,
> 
> I feel like I'm missing something.  What happens if the guest wants to enable
> PmcVirtualization and it's unexpectedly disallowed?  Does the guest simply panic?

In SNP, VMRUN will return with an exit code of VMEXIT_INVALID (0xffffffff)
if the guest tries to set it.

In SEV-ES, the hypervisor can set it, and the same thing will happen to VMRUN.

In both cases, SEV_FEATURES is saved to VMCB field GUEST_SEV_FEATURES at
offset 140h on the VMEXIT, indicating to the host which feature was
attempted but caught as not allowed.

>> but since commit ac5c48027bac ("KVM: SEV: publish supported VMSA features"),
>> userspace can retrieve sev_supported_vmsa_features via an ioctl.
>>
>>> And based on this blurb:
>>>
>>>     Some SEV features can only be used if the Allowed SEV Features Mask is enabled,
>>>     and the mask is configured to permit the corresponding feature. If the Allowed
>>>     SEV Features Mask is not enabled, these features are not available (see SEV_FEATURES
>>>     in Appendix B, Table B-4).
>>>
>>> and the appendix, this only applies to PmcVirtualization and SecureAvic.  Adding
>>> that info in the changelog would be *very* helpful.
>>
>> Ok, how about adding:
>>
>> "The PmcVirtualization and SecureAvic features explicitly require
>> ALLOWED_SEV_FEATURES to enable them before they can be used."
>>
>>> And I see that SVM_SEV_FEAT_DEBUG_SWAP, a.k.a. DebugVirtualization, is a guest
>>> controlled feature and doesn't honor ALLOWED_SEV_FEATURES.  Doesn't that mean
>>> sev_vcpu_has_debug_swap() is broken, i.e. that KVM must assume the guest can
>>> DebugVirtualization on and off at will?  Or am I missing something?
>>
>> My understanding is that users control KVM's DEBUG_SWAP setting
>> with a module parameter since commit 4dd5ecacb9a4 ("KVM: SEV: allow
>> SEV-ES DebugSwap again").  If the module parameter is not set, with
>> this patch, VMRUN will fail since the host doesn't allow DEBUG_SWAP.
> 
> But that's just KVM's view of vmsa_features.  With SNP's wonderful
> SVM_VMGEXIT_AP_CREATE, can't the guest create a VMSA with whatever sev_features
> it wants, so long as they aren't host-controllable, i.e. aren't PmcVirtualization
> or SecureAvic?

No, as above, if the guest tries any silly business the host will
get a VMEXIT_INVALID, no matter if using the feature *requires*
ALLOWED_SEV_FEATURES to be enabled and explicitly allow it (currently
PmcVirtualization or SecureAvic).

Kim
Sean Christopherson Aug. 20, 2024, 4:12 p.m. UTC | #6
On Tue, Aug 20, 2024, Kim Phillips wrote:
> On 8/19/24 5:23 PM, Sean Christopherson wrote:
> > On Mon, Aug 19, 2024, Kim Phillips wrote:
> > > but since commit ac5c48027bac ("KVM: SEV: publish supported VMSA features"),
> > > userspace can retrieve sev_supported_vmsa_features via an ioctl.
> > > 
> > > > And based on this blurb:
> > > > 
> > > >     Some SEV features can only be used if the Allowed SEV Features Mask is enabled,
> > > >     and the mask is configured to permit the corresponding feature. If the Allowed
> > > >     SEV Features Mask is not enabled, these features are not available (see SEV_FEATURES
> > > >     in Appendix B, Table B-4).
> > > > 
> > > > and the appendix, this only applies to PmcVirtualization and SecureAvic.  Adding
> > > > that info in the changelog would be *very* helpful.
> > > 
> > > Ok, how about adding:
> > > 
> > > "The PmcVirtualization and SecureAvic features explicitly require
> > > ALLOWED_SEV_FEATURES to enable them before they can be used."
> > > 
> > > > And I see that SVM_SEV_FEAT_DEBUG_SWAP, a.k.a. DebugVirtualization, is a guest
> > > > controlled feature and doesn't honor ALLOWED_SEV_FEATURES.  Doesn't that mean
> > > > sev_vcpu_has_debug_swap() is broken, i.e. that KVM must assume the guest can
> > > > DebugVirtualization on and off at will?  Or am I missing something?
> > > 
> > > My understanding is that users control KVM's DEBUG_SWAP setting
> > > with a module parameter since commit 4dd5ecacb9a4 ("KVM: SEV: allow
> > > SEV-ES DebugSwap again").  If the module parameter is not set, with
> > > this patch, VMRUN will fail since the host doesn't allow DEBUG_SWAP.
> > 
> > But that's just KVM's view of vmsa_features.  With SNP's wonderful
> > SVM_VMGEXIT_AP_CREATE, can't the guest create a VMSA with whatever sev_features
> > it wants, so long as they aren't host-controllable, i.e. aren't PmcVirtualization
> > or SecureAvic?
> 
> No, as above, if the guest tries any silly business the host will
> get a VMEXIT_INVALID, no matter if using the feature *requires*
> ALLOWED_SEV_FEATURES to be enabled and explicitly allow it (currently
> PmcVirtualization or SecureAvic).

Oooh, I finally get it.  PmcVirtualization and SecureAvic require an opt-in via
ALLOWED_SEV_FEATURES, i.e. are off-by-default, whereas all other features are
effectively on-by-default, but still honor ALLOWED_SEV_FEATURES.
diff mbox series

Patch

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f0dea3750ca9..59516ad2028b 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -158,7 +158,9 @@  struct __attribute__ ((__packed__)) vmcb_control_area {
 	u64 avic_physical_id;	/* Offset 0xf8 */
 	u8 reserved_7[8];
 	u64 vmsa_pa;		/* Used for an SEV-ES guest */
-	u8 reserved_8[720];
+	u8 reserved_8[40];
+	u64 allowed_sev_features;	/* Offset 0x138 */
+	u8 reserved_9[672];
 	/*
 	 * Offset 0x3e0, 32 bytes reserved
 	 * for use by hypervisor/software.
@@ -294,6 +296,8 @@  static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_
 	(SVM_SEV_FEAT_RESTRICTED_INJECTION |	\
 	 SVM_SEV_FEAT_ALTERNATE_INJECTION)
 
+#define VMCB_ALLOWED_SEV_FEATURES_VALID		BIT_ULL(63)
+
 struct vmcb_seg {
 	u16 selector;
 	u16 attrib;
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index a16c873b3232..d12b4d615b32 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -899,6 +899,7 @@  static int sev_es_sync_vmsa(struct vcpu_svm *svm)
 static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
 				    int *error)
 {
+	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
 	struct sev_data_launch_update_vmsa vmsa;
 	struct vcpu_svm *svm = to_svm(vcpu);
 	int ret;
@@ -908,6 +909,10 @@  static int __sev_launch_update_vmsa(struct kvm *kvm, struct kvm_vcpu *vcpu,
 		return -EINVAL;
 	}
 
+	if (cpu_feature_enabled(X86_FEATURE_ALLOWED_SEV_FEATURES))
+		svm->vmcb->control.allowed_sev_features = VMCB_ALLOWED_SEV_FEATURES_VALID |
+							  sev->vmsa_features;
+
 	/* Perform some pre-encryption checks against the VMSA */
 	ret = sev_es_sync_vmsa(svm);
 	if (ret)