Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/boot/sev: Support memory acceptance in the EFI stub under SVSM

Commit:

d54d610243a4 ("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: fcd042e86422 ("x86/sev: Perform PVALIDATE using the SVSM when not at VMPL0")
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Co-developed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: <stable@vger.kernel.org>
Cc: Dionna Amalie Glaze <dionnaglaze@google.com>
Cc: Kevin Loughlin <kevinloughlin@google.com>
Cc: linux-efi@vger.kernel.org
Link: https://lore.kernel.org/r/20250428174322.2780170-2-ardb+git@google.com

authored by

Ard Biesheuvel and committed by
Ingo Molnar
8ed12ab1 b4432656

+43 -4
+1 -4
arch/x86/boot/compressed/mem.c
··· 34 34 35 35 void arch_accept_memory(phys_addr_t start, phys_addr_t end) 36 36 { 37 - static bool sevsnp; 38 - 39 37 /* Platform-specific memory-acceptance call goes here */ 40 38 if (early_is_tdx_guest()) { 41 39 if (!tdx_accept_memory(start, end)) 42 40 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()) { 45 42 snp_accept_memory(start, end); 46 43 } else { 47 44 error("Cannot accept memory: unknown platform\n");
+40
arch/x86/boot/compressed/sev.c
··· 645 645 646 646 sev_verify_cbit(top_level_pgt); 647 647 } 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 + }
+2
arch/x86/boot/compressed/sev.h
··· 13 13 bool sev_snp_enabled(void); 14 14 void snp_accept_memory(phys_addr_t start, phys_addr_t end); 15 15 u64 sev_get_status(void); 16 + bool early_is_sevsnp_guest(void); 16 17 17 18 #else 18 19 19 20 static inline bool sev_snp_enabled(void) { return false; } 20 21 static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { } 21 22 static inline u64 sev_get_status(void) { return 0; } 23 + static inline bool early_is_sevsnp_guest(void) { return false; } 22 24 23 25 #endif 24 26