BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Allocate memory for the GHCB pages and the per-CPU variable pages during SEV initialization for use during Pei and Dxe phases. The GHCB page(s) must be shared pages, so clear the encryption mask from the current page table entries. Upon successful allocation, set the GHCB PCDs (PcdGhcbBase and PcdGhcbSize). The per-CPU variable page needs to be unique per AP. Using the page after the GHCB ensures that it is unique per AP. But, it also ends up being marked shared/unencrypted when it doesn't need to be. It is possible during PEI to mark only the GHCB pages as shared (and that is done), but DXE is not as easy. There needs to be a way to change the pagetables created for DXE using CreateIdentityMappingPageTables() before switching to them. The GHCB pages (one per vCPU) will be used by the PEI and DXE #VC exception handlers. The #VC exception handler will fill in the necessary fields of the GHCB and exit to the hypervisor using the VMGEXIT instruction. The hypervisor then accesses the GHCB associated with the vCPU in order to perform the requested function. Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org> Reviewed-by: Laszlo Ersek <ler...@redhat.com> Signed-off-by: Tom Lendacky <thomas.lenda...@amd.com> --- OvmfPkg/OvmfPkgIa32.dsc | 2 ++ OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++ OvmfPkg/OvmfPkgX64.dsc | 2 ++ OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++ OvmfPkg/PlatformPei/AmdSev.c | 38 ++++++++++++++++++++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index d9dd2db52ea6..56670eefde6b 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -570,6 +570,8 @@ [PcdsDynamicDefault] # Set SEV-ES defaults gEfiMdeModulePkgTokenSpaceGuid.PcdSevEsIsEnabled|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0 !if $(SMM_REQUIRE) == TRUE gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8 diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 291cb6d1f603..9897e6889573 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -582,6 +582,8 @@ [PcdsDynamicDefault] # Set SEV-ES defaults gEfiMdeModulePkgTokenSpaceGuid.PcdSevEsIsEnabled|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0 !if $(SMM_REQUIRE) == TRUE gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8 diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 5990dab4f65e..59c4f9207fc3 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -581,6 +581,8 @@ [PcdsDynamicDefault] # Set SEV-ES defaults gEfiMdeModulePkgTokenSpaceGuid.PcdSevEsIsEnabled|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0 !if $(SMM_REQUIRE) == TRUE gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8 diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index 920b619446f0..25bb59d161de 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -100,6 +100,8 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdSevEsIsEnabled gEfiMdeModulePkgTokenSpaceGuid.PcdSecGhcbBase gEfiMdeModulePkgTokenSpaceGuid.PcdSecGhcbSize + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c index c12aea46d94e..900b0d977d61 100644 --- a/OvmfPkg/PlatformPei/AmdSev.c +++ b/OvmfPkg/PlatformPei/AmdSev.c @@ -9,12 +9,15 @@ // // The package level header files this module uses // +#include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> #include <Library/HobLib.h> #include <Library/MemEncryptSevLib.h> +#include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include <PiPei.h> #include <Register/Amd/Cpuid.h> +#include <Register/Amd/Msr.h> #include <Register/Cpuid.h> #include "Platform.h" @@ -30,7 +33,10 @@ AmdSevEsInitialize ( VOID ) { - RETURN_STATUS PcdStatus; + VOID *GhcbBase; + PHYSICAL_ADDRESS GhcbBasePa; + UINTN GhcbPageCount; + RETURN_STATUS PcdStatus, DecryptStatus; if (!MemEncryptSevEsIsEnabled ()) { return; @@ -38,6 +44,36 @@ AmdSevEsInitialize ( PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE); ASSERT_RETURN_ERROR (PcdStatus); + + // + // Allocate GHCB and per-CPU variable pages. + // + GhcbPageCount = mMaxCpuCount * 2; + GhcbBase = AllocatePages (GhcbPageCount); + ASSERT (GhcbBase != NULL); + + GhcbBasePa = (PHYSICAL_ADDRESS)(UINTN) GhcbBase; + + DecryptStatus = MemEncryptSevClearPageEncMask ( + 0, + GhcbBasePa, + GhcbPageCount, + TRUE + ); + ASSERT_RETURN_ERROR (DecryptStatus); + + ZeroMem (GhcbBase, EFI_PAGES_TO_SIZE (GhcbPageCount)); + + PcdStatus = PcdSet64S (PcdGhcbBase, GhcbBasePa); + ASSERT_RETURN_ERROR (PcdStatus); + PcdStatus = PcdSet64S (PcdGhcbSize, EFI_PAGES_TO_SIZE (GhcbPageCount)); + ASSERT_RETURN_ERROR (PcdStatus); + + DEBUG ((DEBUG_INFO, + "SEV-ES is enabled, %lu GHCB pages allocated starting at 0x%p\n", + (UINT64)GhcbPageCount, GhcbBase)); + + AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa); } /** -- 2.17.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#50968): https://edk2.groups.io/g/devel/message/50968 Mute This Topic: https://groups.io/mt/60973127/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-