Skip to content

Commit 8ed12ab

Browse files
ardbiesheuvelIngo Molnar
authored andcommitted
x86/boot/sev: Support memory acceptance in the EFI stub under SVSM
Commit: d54d610 ("x86/boot/sev: Avoid shared GHCB page for early memory acceptance") provided a fix for SEV-SNP memory acceptance from the EFI stub when running at VMPL #0. However, that fix was insufficient for SVSM SEV-SNP guests running at VMPL >0, as those rely on a SVSM calling area, which is a shared buffer whose address is programmed into a SEV-SNP MSR, and the SEV init code that sets up this calling area executes much later during the boot. Given that booting via the EFI stub at VMPL >0 implies that the firmware has configured this calling area already, reuse it for performing memory acceptance in the EFI stub. Fixes: fcd042e ("x86/sev: Perform PVALIDATE using the SVSM when not at VMPL0") Tested-by: Tom Lendacky <[email protected]> Co-developed-by: Tom Lendacky <[email protected]> Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Cc: <[email protected]> Cc: Dionna Amalie Glaze <[email protected]> Cc: Kevin Loughlin <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent b443265 commit 8ed12ab

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

arch/x86/boot/compressed/mem.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,11 @@ static bool early_is_tdx_guest(void)
3434

3535
void arch_accept_memory(phys_addr_t start, phys_addr_t end)
3636
{
37-
static bool sevsnp;
38-
3937
/* Platform-specific memory-acceptance call goes here */
4038
if (early_is_tdx_guest()) {
4139
if (!tdx_accept_memory(start, end))
4240
panic("TDX: Failed to accept memory\n");
43-
} else if (sevsnp || (sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED)) {
44-
sevsnp = true;
41+
} else if (early_is_sevsnp_guest()) {
4542
snp_accept_memory(start, end);
4643
} else {
4744
error("Cannot accept memory: unknown platform\n");

arch/x86/boot/compressed/sev.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,43 @@ void sev_prep_identity_maps(unsigned long top_level_pgt)
645645

646646
sev_verify_cbit(top_level_pgt);
647647
}
648+
649+
bool early_is_sevsnp_guest(void)
650+
{
651+
static bool sevsnp;
652+
653+
if (sevsnp)
654+
return true;
655+
656+
if (!(sev_get_status() & MSR_AMD64_SEV_SNP_ENABLED))
657+
return false;
658+
659+
sevsnp = true;
660+
661+
if (!snp_vmpl) {
662+
unsigned int eax, ebx, ecx, edx;
663+
664+
/*
665+
* CPUID Fn8000_001F_EAX[28] - SVSM support
666+
*/
667+
eax = 0x8000001f;
668+
ecx = 0;
669+
native_cpuid(&eax, &ebx, &ecx, &edx);
670+
if (eax & BIT(28)) {
671+
struct msr m;
672+
673+
/* Obtain the address of the calling area to use */
674+
boot_rdmsr(MSR_SVSM_CAA, &m);
675+
boot_svsm_caa = (void *)m.q;
676+
boot_svsm_caa_pa = m.q;
677+
678+
/*
679+
* The real VMPL level cannot be discovered, but the
680+
* memory acceptance routines make no use of that so
681+
* any non-zero value suffices here.
682+
*/
683+
snp_vmpl = U8_MAX;
684+
}
685+
}
686+
return true;
687+
}

arch/x86/boot/compressed/sev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
bool sev_snp_enabled(void);
1414
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
1515
u64 sev_get_status(void);
16+
bool early_is_sevsnp_guest(void);
1617

1718
#else
1819

1920
static inline bool sev_snp_enabled(void) { return false; }
2021
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
2122
static inline u64 sev_get_status(void) { return 0; }
23+
static inline bool early_is_sevsnp_guest(void) { return false; }
2224

2325
#endif
2426

0 commit comments

Comments
 (0)