summaryrefslogtreecommitdiff
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2024-06-05 10:18:56 -0500
committerBorislav Petkov (AMD) <bp@alien8.de>2024-06-17 20:42:58 +0200
commit99ef9f59847cab1f9091cd4b9d7efbee0ae4fc86 (patch)
tree63b6b544590a06603338728a53fa6eebfef4eadf /arch/x86/boot
parent627dc671518b7f004ce04c45e8711f8dca94a57c (diff)
downloadlwn-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.c17
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);
}