diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2024-06-05 10:18:56 -0500 |
---|---|---|
committer | Borislav Petkov (AMD) <bp@alien8.de> | 2024-06-17 20:42:58 +0200 |
commit | 99ef9f59847cab1f9091cd4b9d7efbee0ae4fc86 (patch) | |
tree | 63b6b544590a06603338728a53fa6eebfef4eadf /arch/x86/boot | |
parent | 627dc671518b7f004ce04c45e8711f8dca94a57c (diff) | |
download | lwn-99ef9f59847cab1f9091cd4b9d7efbee0ae4fc86.tar.gz lwn-99ef9f59847cab1f9091cd4b9d7efbee0ae4fc86.zip |
x86/sev: Allow non-VMPL0 execution when an SVSM is present
To allow execution at a level other than VMPL0, an SVSM must be present.
Allow the SEV-SNP guest to continue booting if an SVSM is detected and
the hypervisor supports the SVSM feature as indicated in the GHCB
hypervisor features bitmap.
[ bp: Massage a bit. ]
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/2ce7cf281cce1d0cba88f3f576687ef75dc3c953.1717600736.git.thomas.lendacky@amd.com
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/compressed/sev.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c index ce941a9890f8..697057250faa 100644 --- a/arch/x86/boot/compressed/sev.c +++ b/arch/x86/boot/compressed/sev.c @@ -610,11 +610,15 @@ void sev_enable(struct boot_params *bp) * features. */ if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) { - if (!(get_hv_features() & GHCB_HV_FT_SNP)) + u64 hv_features; + int ret; + + hv_features = get_hv_features(); + if (!(hv_features & GHCB_HV_FT_SNP)) sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); /* - * Enforce running at VMPL0. + * Enforce running at VMPL0 or with an SVSM. * * Use RMPADJUST (see the rmpadjust() function for a description of * what the instruction does) to update the VMPL1 permissions of a @@ -623,7 +627,14 @@ void sev_enable(struct boot_params *bp) * only ever run at a single VMPL level so permission mask changes of a * lesser-privileged VMPL are a don't-care. */ - if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1)) + ret = rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1); + + /* + * Running at VMPL0 is not required if an SVSM is present and the hypervisor + * supports the required SVSM GHCB events. + */ + if (ret && + !(snp_vmpl && (hv_features & GHCB_HV_FT_SNP_MULTI_VMPL))) sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0); } |