From a21a3438f795deecb24e1843c1636f95c485017c Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Mon, 16 May 2022 15:24:02 -0500 Subject: [PATCH] OvmfPkg: Make an Ia32/X64 hybrid build work with SEV The BaseMemEncryptSevLib functionality was updated to rely on the use of the OVMF/SEV workarea to check for SEV guests. However, this area is only updated when running the X64 OVMF build, not the hybrid Ia32/X64 build. Base SEV support is allowed under the Ia32/X64 build, but it now fails to boot as a result of the change. Update the ResetVector code to check for SEV features when built for 32-bit mode, not just 64-bit mode (requiring updates to both the Ia32 and Ia32X64 fdf files). Fixes: f1d1c337e7c0575da7fd248b2dd9cffc755940df Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Erdem Aktas Cc: James Bottomley Cc: Michael Roth Cc: Min Xu Signed-off-by: Tom Lendacky Reviewed-by: Ard Biesheuvel --- OvmfPkg/OvmfPkgIa32.fdf | 11 ++++ OvmfPkg/OvmfPkgIa32X64.fdf | 8 +++ OvmfPkg/OvmfPkgX64.fdf | 3 +- OvmfPkg/ResetVector/Ia32/AmdSev.asm | 4 ++ OvmfPkg/ResetVector/Main.asm | 6 +++ OvmfPkg/ResetVector/ResetVector.nasmb | 74 +++++++++++++-------------- 6 files changed, 68 insertions(+), 38 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 3ab1755749..57d13b7130 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -76,6 +76,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid. 0x007000|0x001000 gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize +0x008000|0x001000 +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize + 0x010000|0x010000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize @@ -87,6 +90,14 @@ FV = PEIFV gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV +########################################################################################## +# Set the SEV-ES specific work area PCDs (used for all forms of SEV since the +# the SEV STATUS MSR is now saved in the work area) +# +SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader +SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader +########################################################################################## + ################################################################################ [FV.SECFV] diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index e1638fa6ea..ccde366887 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -90,6 +90,14 @@ FV = PEIFV gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV +########################################################################################## +# Set the SEV-ES specific work area PCDs (used for all forms of SEV since the +# the SEV STATUS MSR is now saved in the work area) +# +SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader +SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader +########################################################################################## + ################################################################################ [FV.SECFV] diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index aa9a83032d..438806fba8 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -106,7 +106,8 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm FV = DXEFV ########################################################################################## -# Set the SEV-ES specific work area PCDs +# Set the SEV-ES specific work area PCDs (used for all forms of SEV since the +# the SEV STATUS MSR is now saved in the work area) # SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase = $(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader SET gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize - gUefiOvmfPkgTokenSpaceGuid.PcdOvmfConfidentialComputingWorkAreaHeader diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm index 864d683853..9350b04068 100644 --- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm +++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm @@ -150,6 +150,8 @@ BITS 32 SevEsUnexpectedRespTerminate: TerminateVmgExit TERM_UNEXPECTED_RESP_CODE +%ifdef ARCH_X64 + ; If SEV-ES is enabled then initialize and make the GHCB page shared SevClearPageEncMaskForGhcbPage: ; Check if SEV is enabled @@ -209,6 +211,8 @@ GetSevCBitMaskAbove31: GetSevCBitMaskAbove31Exit: OneTimeCallRet GetSevCBitMaskAbove31 +%endif + ; Check if Secure Encrypted Virtualization (SEV) features are enabled. ; ; Register usage is tight in this routine, so multiple calls for the diff --git a/OvmfPkg/ResetVector/Main.asm b/OvmfPkg/ResetVector/Main.asm index 5cfc0b5c72..46cfa87c4c 100644 --- a/OvmfPkg/ResetVector/Main.asm +++ b/OvmfPkg/ResetVector/Main.asm @@ -75,6 +75,12 @@ SearchBfv: %ifdef ARCH_IA32 + ; + ; SEV support can be built and run using the Ia32/X64 split environment. + ; Set the OVMF/SEV work area as appropriate. + ; + OneTimeCall CheckSevFeatures + ; ; Restore initial EAX value into the EAX register ; diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb index 9421f48189..94fbb0a87b 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -47,7 +47,36 @@ %include "Ia32/SearchForBfvBase.asm" %include "Ia32/SearchForSecEntry.asm" -%define WORK_AREA_GUEST_TYPE (FixedPcdGet32 (PcdOvmfWorkAreaBase)) +%define WORK_AREA_GUEST_TYPE (FixedPcdGet32 (PcdOvmfWorkAreaBase)) +%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) + +%define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) +%define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase)) +%define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize)) +%define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase)) +%define SEV_ES_WORK_AREA_SIZE 25 +%define SEV_ES_WORK_AREA_STATUS_MSR (FixedPcdGet32 (PcdSevEsWorkAreaBase)) +%define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8) +%define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16) +%define SEV_ES_WORK_AREA_RECEIVED_VC (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24) +%define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) +%define SEV_SNP_SECRETS_BASE (FixedPcdGet32 (PcdOvmfSnpSecretsBase)) +%define SEV_SNP_SECRETS_SIZE (FixedPcdGet32 (PcdOvmfSnpSecretsSize)) +%define CPUID_BASE (FixedPcdGet32 (PcdOvmfCpuidBase)) +%define CPUID_SIZE (FixedPcdGet32 (PcdOvmfCpuidSize)) +%define SNP_SEC_MEM_BASE_DESC_1 (FixedPcdGet32 (PcdOvmfSecPageTablesBase)) +%define SNP_SEC_MEM_SIZE_DESC_1 (FixedPcdGet32 (PcdOvmfSecGhcbBase) - SNP_SEC_MEM_BASE_DESC_1) +; +; The PcdOvmfSecGhcbBase reserves two GHCB pages. The first page is used +; as GHCB shared page and second is used for bookkeeping to support the +; nested GHCB in SEC phase. The bookkeeping page is mapped private. The VMM +; does not need to validate the shared page but it need to validate the +; bookkeeping page. +; +%define SNP_SEC_MEM_BASE_DESC_2 (GHCB_BASE + 0x1000) +%define SNP_SEC_MEM_SIZE_DESC_2 (SEV_SNP_SECRETS_BASE - SNP_SEC_MEM_BASE_DESC_2) +%define SNP_SEC_MEM_BASE_DESC_3 (CPUID_BASE + CPUID_SIZE) +%define SNP_SEC_MEM_SIZE_DESC_3 (FixedPcdGet32 (PcdOvmfPeiMemFvBase) - SNP_SEC_MEM_BASE_DESC_3) %ifdef ARCH_X64 #include @@ -94,44 +123,15 @@ %define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4) %define TDX_WORK_AREA_GPAW (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8) - %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) - - %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) - %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase)) - %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize)) - %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase)) - %define SEV_ES_WORK_AREA_SIZE 25 - %define SEV_ES_WORK_AREA_STATUS_MSR (FixedPcdGet32 (PcdSevEsWorkAreaBase)) - %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8) - %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16) - %define SEV_ES_WORK_AREA_RECEIVED_VC (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24) - %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) - %define SEV_SNP_SECRETS_BASE (FixedPcdGet32 (PcdOvmfSnpSecretsBase)) - %define SEV_SNP_SECRETS_SIZE (FixedPcdGet32 (PcdOvmfSnpSecretsSize)) - %define CPUID_BASE (FixedPcdGet32 (PcdOvmfCpuidBase)) - %define CPUID_SIZE (FixedPcdGet32 (PcdOvmfCpuidSize)) - %define SNP_SEC_MEM_BASE_DESC_1 (FixedPcdGet32 (PcdOvmfSecPageTablesBase)) - %define SNP_SEC_MEM_SIZE_DESC_1 (FixedPcdGet32 (PcdOvmfSecGhcbBase) - SNP_SEC_MEM_BASE_DESC_1) - ; - ; The PcdOvmfSecGhcbBase reserves two GHCB pages. The first page is used - ; as GHCB shared page and second is used for bookkeeping to support the - ; nested GHCB in SEC phase. The bookkeeping page is mapped private. The VMM - ; does not need to validate the shared page but it need to validate the - ; bookkeeping page. - ; - %define SNP_SEC_MEM_BASE_DESC_2 (GHCB_BASE + 0x1000) - %define SNP_SEC_MEM_SIZE_DESC_2 (SEV_SNP_SECRETS_BASE - SNP_SEC_MEM_BASE_DESC_2) - %define SNP_SEC_MEM_BASE_DESC_3 (CPUID_BASE + CPUID_SIZE) - %define SNP_SEC_MEM_SIZE_DESC_3 (FixedPcdGet32 (PcdOvmfPeiMemFvBase) - SNP_SEC_MEM_BASE_DESC_3) - -%include "X64/IntelTdxMetadata.asm" -%include "Ia32/Flat32ToFlat64.asm" -%include "Ia32/AmdSev.asm" -%include "Ia32/PageTables64.asm" -%include "Ia32/IntelTdx.asm" -%include "X64/OvmfSevMetadata.asm" + %include "X64/IntelTdxMetadata.asm" + %include "Ia32/Flat32ToFlat64.asm" + %include "Ia32/PageTables64.asm" + %include "Ia32/IntelTdx.asm" + %include "X64/OvmfSevMetadata.asm" %endif +%include "Ia32/AmdSev.asm" + %include "Ia16/Real16ToFlat32.asm" %include "Ia16/Init16.asm" -- 2.39.2