2024-04-24 16:02:50

by Tom Lendacky

[permalink] [raw]
Subject: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

Currently, the sev-guest driver uses the vmpck-0 key by default. When an
SVSM is present the kernel is running at a VMPL other than 0 and the
vmpck-0 key is no longer available. If a specific vmpck key has not be
requested by the user via the vmpck_id module parameter, choose the vmpck
key based on the active VMPL level.

Signed-off-by: Tom Lendacky <[email protected]>
---
arch/x86/include/asm/sev.h | 2 ++
arch/x86/kernel/sev.c | 6 ++++++
drivers/virt/coco/sev-guest/sev-guest.c | 10 +++++++---
3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index a7312b936d16..64fcadd6d602 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -307,6 +307,7 @@ u64 snp_get_unsupported_features(u64 status);
u64 sev_get_status(void);
void sev_show_status(void);
void snp_remap_svsm_ca(void);
+int snp_get_vmpl(void);
#else
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
static inline void sev_es_ist_exit(void) { }
@@ -337,6 +338,7 @@ static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
static inline u64 sev_get_status(void) { return 0; }
static inline void sev_show_status(void) { }
static inline void snp_remap_svsm_ca(void) { }
+static inline int snp_get_vmpl(void) { return 0; }
#endif

#ifdef CONFIG_KVM_AMD_SEV
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index 8edf7362136b..75f11da867a3 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -2454,6 +2454,12 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
}
EXPORT_SYMBOL_GPL(snp_issue_guest_request);

+int snp_get_vmpl(void)
+{
+ return vmpl;
+}
+EXPORT_SYMBOL_GPL(snp_get_vmpl);
+
static struct platform_device sev_guest_device = {
.name = "sev-guest",
.id = -1,
diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
index 04a7bd1e4314..e7dd7df86427 100644
--- a/drivers/virt/coco/sev-guest/sev-guest.c
+++ b/drivers/virt/coco/sev-guest/sev-guest.c
@@ -2,7 +2,7 @@
/*
* AMD Secure Encrypted Virtualization (SEV) guest driver interface
*
- * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ * Copyright (C) 2021-2024 Advanced Micro Devices, Inc.
*
* Author: Brijesh Singh <[email protected]>
*/
@@ -70,8 +70,8 @@ struct snp_guest_dev {
u8 *vmpck;
};

-static u32 vmpck_id;
-module_param(vmpck_id, uint, 0444);
+static int vmpck_id = -1;
+module_param(vmpck_id, int, 0444);
MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");

/* Mutex to serialize the shared buffer access and command handling. */
@@ -923,6 +923,10 @@ static int __init sev_guest_probe(struct platform_device *pdev)
if (!snp_dev)
goto e_unmap;

+ /* Adjust the default VMPCK key based on the executing VMPL level */
+ if (vmpck_id == -1)
+ vmpck_id = snp_get_vmpl();
+
ret = -EINVAL;
snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno);
if (!snp_dev->vmpck) {
--
2.43.2



2024-05-01 23:57:53

by Jacob Xu

[permalink] [raw]
Subject: Re: [svsm-devel] [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

General question on VMPCKs: the secrets page defines them listed all
together one at a time, does that mean any guest at any VMPL can
observe all the VMPCKs? Or is SVSM running at VMPL0 supposed to clear
VMPCK0 before it hands off control to edk2?


On Wed, Apr 24, 2024 at 8:59 AM Tom Lendacky <[email protected]> wrote:
>
> Currently, the sev-guest driver uses the vmpck-0 key by default. When an
> SVSM is present the kernel is running at a VMPL other than 0 and the
> vmpck-0 key is no longer available. If a specific vmpck key has not be
> requested by the user via the vmpck_id module parameter, choose the vmpck
> key based on the active VMPL level.
>
> Signed-off-by: Tom Lendacky <[email protected]>
> ---
> arch/x86/include/asm/sev.h | 2 ++
> arch/x86/kernel/sev.c | 6 ++++++
> drivers/virt/coco/sev-guest/sev-guest.c | 10 +++++++---
> 3 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
> index a7312b936d16..64fcadd6d602 100644
> --- a/arch/x86/include/asm/sev.h
> +++ b/arch/x86/include/asm/sev.h
> @@ -307,6 +307,7 @@ u64 snp_get_unsupported_features(u64 status);
> u64 sev_get_status(void);
> void sev_show_status(void);
> void snp_remap_svsm_ca(void);
> +int snp_get_vmpl(void);
> #else
> static inline void sev_es_ist_enter(struct pt_regs *regs) { }
> static inline void sev_es_ist_exit(void) { }
> @@ -337,6 +338,7 @@ static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
> static inline u64 sev_get_status(void) { return 0; }
> static inline void sev_show_status(void) { }
> static inline void snp_remap_svsm_ca(void) { }
> +static inline int snp_get_vmpl(void) { return 0; }
> #endif
>
> #ifdef CONFIG_KVM_AMD_SEV
> diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
> index 8edf7362136b..75f11da867a3 100644
> --- a/arch/x86/kernel/sev.c
> +++ b/arch/x86/kernel/sev.c
> @@ -2454,6 +2454,12 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
> }
> EXPORT_SYMBOL_GPL(snp_issue_guest_request);
>
> +int snp_get_vmpl(void)
> +{
> + return vmpl;
> +}
> +EXPORT_SYMBOL_GPL(snp_get_vmpl);
> +
> static struct platform_device sev_guest_device = {
> .name = "sev-guest",
> .id = -1,
> diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
> index 04a7bd1e4314..e7dd7df86427 100644
> --- a/drivers/virt/coco/sev-guest/sev-guest.c
> +++ b/drivers/virt/coco/sev-guest/sev-guest.c
> @@ -2,7 +2,7 @@
> /*
> * AMD Secure Encrypted Virtualization (SEV) guest driver interface
> *
> - * Copyright (C) 2021 Advanced Micro Devices, Inc.
> + * Copyright (C) 2021-2024 Advanced Micro Devices, Inc.
> *
> * Author: Brijesh Singh <[email protected]>
> */
> @@ -70,8 +70,8 @@ struct snp_guest_dev {
> u8 *vmpck;
> };
>
> -static u32 vmpck_id;
> -module_param(vmpck_id, uint, 0444);
> +static int vmpck_id = -1;
> +module_param(vmpck_id, int, 0444);
> MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");
>
> /* Mutex to serialize the shared buffer access and command handling. */
> @@ -923,6 +923,10 @@ static int __init sev_guest_probe(struct platform_device *pdev)
> if (!snp_dev)
> goto e_unmap;
>
> + /* Adjust the default VMPCK key based on the executing VMPL level */
> + if (vmpck_id == -1)
> + vmpck_id = snp_get_vmpl();
> +
> ret = -EINVAL;
> snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno);
> if (!snp_dev->vmpck) {
> --
> 2.43.2
>
> --
> Svsm-devel mailing list
> [email protected]
> https://mail.8bytes.org/cgi-bin/mailman/listinfo/svsm-devel

2024-05-02 13:18:05

by Tom Lendacky

[permalink] [raw]
Subject: Re: [svsm-devel] [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On 5/1/24 18:57, Jacob Xu wrote:
> General question on VMPCKs: the secrets page defines them listed all
> together one at a time, does that mean any guest at any VMPL can
> observe all the VMPCKs? Or is SVSM running at VMPL0 supposed to clear
> VMPCK0 before it hands off control to edk2?

The SVSM should clear VMPCK0 in the copy of the secrets page provided to
the guest BIOS/OS.

Thanks,
Tom

>
>
> On Wed, Apr 24, 2024 at 8:59 AM Tom Lendacky <[email protected]> wrote:
>>
>> Currently, the sev-guest driver uses the vmpck-0 key by default. When an
>> SVSM is present the kernel is running at a VMPL other than 0 and the
>> vmpck-0 key is no longer available. If a specific vmpck key has not be
>> requested by the user via the vmpck_id module parameter, choose the vmpck
>> key based on the active VMPL level.
>>
>> Signed-off-by: Tom Lendacky <[email protected]>
>> ---
>> arch/x86/include/asm/sev.h | 2 ++
>> arch/x86/kernel/sev.c | 6 ++++++
>> drivers/virt/coco/sev-guest/sev-guest.c | 10 +++++++---
>> 3 files changed, 15 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
>> index a7312b936d16..64fcadd6d602 100644
>> --- a/arch/x86/include/asm/sev.h
>> +++ b/arch/x86/include/asm/sev.h
>> @@ -307,6 +307,7 @@ u64 snp_get_unsupported_features(u64 status);
>> u64 sev_get_status(void);
>> void sev_show_status(void);
>> void snp_remap_svsm_ca(void);
>> +int snp_get_vmpl(void);
>> #else
>> static inline void sev_es_ist_enter(struct pt_regs *regs) { }
>> static inline void sev_es_ist_exit(void) { }
>> @@ -337,6 +338,7 @@ static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
>> static inline u64 sev_get_status(void) { return 0; }
>> static inline void sev_show_status(void) { }
>> static inline void snp_remap_svsm_ca(void) { }
>> +static inline int snp_get_vmpl(void) { return 0; }
>> #endif
>>
>> #ifdef CONFIG_KVM_AMD_SEV
>> diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
>> index 8edf7362136b..75f11da867a3 100644
>> --- a/arch/x86/kernel/sev.c
>> +++ b/arch/x86/kernel/sev.c
>> @@ -2454,6 +2454,12 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct sn
>> }
>> EXPORT_SYMBOL_GPL(snp_issue_guest_request);
>>
>> +int snp_get_vmpl(void)
>> +{
>> + return vmpl;
>> +}
>> +EXPORT_SYMBOL_GPL(snp_get_vmpl);
>> +
>> static struct platform_device sev_guest_device = {
>> .name = "sev-guest",
>> .id = -1,
>> diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
>> index 04a7bd1e4314..e7dd7df86427 100644
>> --- a/drivers/virt/coco/sev-guest/sev-guest.c
>> +++ b/drivers/virt/coco/sev-guest/sev-guest.c
>> @@ -2,7 +2,7 @@
>> /*
>> * AMD Secure Encrypted Virtualization (SEV) guest driver interface
>> *
>> - * Copyright (C) 2021 Advanced Micro Devices, Inc.
>> + * Copyright (C) 2021-2024 Advanced Micro Devices, Inc.
>> *
>> * Author: Brijesh Singh <[email protected]>
>> */
>> @@ -70,8 +70,8 @@ struct snp_guest_dev {
>> u8 *vmpck;
>> };
>>
>> -static u32 vmpck_id;
>> -module_param(vmpck_id, uint, 0444);
>> +static int vmpck_id = -1;
>> +module_param(vmpck_id, int, 0444);
>> MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");
>>
>> /* Mutex to serialize the shared buffer access and command handling. */
>> @@ -923,6 +923,10 @@ static int __init sev_guest_probe(struct platform_device *pdev)
>> if (!snp_dev)
>> goto e_unmap;
>>
>> + /* Adjust the default VMPCK key based on the executing VMPL level */
>> + if (vmpck_id == -1)
>> + vmpck_id = snp_get_vmpl();
>> +
>> ret = -EINVAL;
>> snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno);
>> if (!snp_dev->vmpck) {
>> --
>> 2.43.2
>>
>> --
>> Svsm-devel mailing list
>> [email protected]
>> https://mail.8bytes.org/cgi-bin/mailman/listinfo/svsm-devel

2024-05-31 12:55:34

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On Wed, Apr 24, 2024 at 10:58:06AM -0500, Tom Lendacky wrote:
> +int snp_get_vmpl(void)
> +{
> + return vmpl;

The vmpl doesn't change after init, right?

If so, you can make that vmpl variable __ro_after_init and drop yet
another parrotting accessor.

> -static u32 vmpck_id;
> -module_param(vmpck_id, uint, 0444);
> +static int vmpck_id = -1;
> +module_param(vmpck_id, int, 0444);
> MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");

Can the driver figure out the vmpck_id from the kernel directly instead
of having to supply it with a module param?

This is yet another silly module param which you have to go and engineer
into the loading and have to know what you're doing.

If you can automate that, then it is a win-win thing.

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2024-05-31 18:36:21

by Tom Lendacky

[permalink] [raw]
Subject: Re: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On 5/31/24 07:55, Borislav Petkov wrote:
> On Wed, Apr 24, 2024 at 10:58:06AM -0500, Tom Lendacky wrote:
>> +int snp_get_vmpl(void)
>> +{
>> + return vmpl;
>
> The vmpl doesn't change after init, right?
>
> If so, you can make that vmpl variable __ro_after_init and drop yet

It already is __ro_after_init.

> another parrotting accessor.

The sev-guest driver needs to access it. Given it is a driver/module, I
created the accessor rather than mark the variable EXPORT_SYMBOL_GPL().
Your call, I'm fine with either.

>
>> -static u32 vmpck_id;
>> -module_param(vmpck_id, uint, 0444);
>> +static int vmpck_id = -1;
>> +module_param(vmpck_id, int, 0444);
>> MODULE_PARM_DESC(vmpck_id, "The VMPCK ID to use when communicating with the PSP.");
>
> Can the driver figure out the vmpck_id from the kernel directly instead
> of having to supply it with a module param?

Yes, the driver can and does figure it out. However, this module parameter
was added in the off chance the default VMPCK gets wiped. Then you can
reload the driver and use a different (less privileged) VMPCK.

Thanks,
Tom

>
> This is yet another silly module param which you have to go and engineer
> into the loading and have to know what you're doing.
>
> If you can automate that, then it is a win-win thing.
>
> Thx.
>

2024-05-31 19:05:50

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On Fri, May 31, 2024 at 01:36:06PM -0500, Tom Lendacky wrote:
> The sev-guest driver needs to access it. Given it is a driver/module, I
> created the accessor rather than mark the variable EXPORT_SYMBOL_GPL(). Your
> call, I'm fine with either.

Yeah, if the variable doesn't change after init, then you don't really
need an accessor.

> Yes, the driver can and does figure it out. However, this module parameter
> was added in the off chance the default VMPCK gets wiped. Then you can
> reload the driver and use a different (less privileged) VMPCK.

Is that what the text over snp_disable_vmpck() is alluding to?

Or where are we documenting this intended use?

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2024-05-31 19:34:52

by Tom Lendacky

[permalink] [raw]
Subject: Re: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On 5/31/24 14:03, Borislav Petkov wrote:
> On Fri, May 31, 2024 at 01:36:06PM -0500, Tom Lendacky wrote:
>> The sev-guest driver needs to access it. Given it is a driver/module, I
>> created the accessor rather than mark the variable EXPORT_SYMBOL_GPL(). Your
>> call, I'm fine with either.
>
> Yeah, if the variable doesn't change after init, then you don't really
> need an accessor.
>
>> Yes, the driver can and does figure it out. However, this module parameter
>> was added in the off chance the default VMPCK gets wiped. Then you can
>> reload the driver and use a different (less privileged) VMPCK.
>
> Is that what the text over snp_disable_vmpck() is alluding to?

Yes, I believe so.

>
> Or where are we documenting this intended use?

It probably should have been documented above the module parameter itself
and/or in the sev-guest documentation. Those can be done as part of this
patch or separate, whichever is preferred.

Thanks,
Tom

>
> Thx.
>

2024-06-01 09:17:50

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v4 10/15] virt: sev-guest: Choose the VMPCK key based on executing VMPL

On Fri, May 31, 2024 at 02:34:37PM -0500, Tom Lendacky wrote:
> It probably should have been documented above the module parameter itself
> and/or in the sev-guest documentation. Those can be done as part of this
> patch or separate, whichever is preferred.

Yeah, pls do it while you're touching that area.

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette