diff --git a/OvmfPkg/PlatformPei/Fv.c b/OvmfPkg/PlatformPei/Fv.c index 3ed775c850..248c585085 100644 --- a/OvmfPkg/PlatformPei/Fv.c +++ b/OvmfPkg/PlatformPei/Fv.c @@ -32,6 +32,8 @@ PeiFvInitialization ( VOID ) { + BOOLEAN SecureS3Needed; + DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n")); // @@ -50,15 +52,38 @@ PeiFvInitialization ( // BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize)); + SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire); + // // Create a memory allocation HOB for the DXE FV. // + // If "secure" S3 is needed, then SEC will decompress both PEI and DXE + // firmware volumes at S3 resume too, hence we need to keep away the OS from + // DXEFV as well. Otherwise we only need to keep away DXE itself from the + // DXEFV area. + // BuildMemoryAllocationHob ( PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize), - EfiBootServicesData + SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData ); + // + // Additionally, said decompression will use temporary memory above the end + // of DXEFV, so let's keep away the OS from there too. + // + if (SecureS3Needed) { + UINT32 DxeMemFvEnd; + + DxeMemFvEnd = PcdGet32 (PcdOvmfDxeMemFvBase) + + PcdGet32 (PcdOvmfDxeMemFvSize); + BuildMemoryAllocationHob ( + DxeMemFvEnd, + PcdGet32 (PcdOvmfDecompressionScratchEnd) - DxeMemFvEnd, + EfiACPIMemoryNVS + ); + } + // // Let PEI know about the DXE FV so it can find the DXE Core // diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c index 612bb4a3ef..5fe8b282c0 100644 --- a/OvmfPkg/PlatformPei/MemDetect.c +++ b/OvmfPkg/PlatformPei/MemDetect.c @@ -222,7 +222,16 @@ PublishPeiMemory ( // // Determine the range of memory to use during PEI // - MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize); + // Technically we could lay the permanent PEI RAM over SEC's temporary + // decompression and scratch buffer even if "secure S3" is needed, since + // their lifetimes don't overlap. However, PeiFvInitialization() will cover + // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory + // allocation HOB, and other allocations served from the permanent PEI RAM + // shouldn't overlap with that HOB. + // + MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ? + PcdGet32 (PcdOvmfDecompressionScratchEnd) : + PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize); MemorySize = LowerMemorySize - MemoryBase; if (MemorySize > PeiMemoryCap) { MemoryBase = LowerMemorySize - PeiMemoryCap; diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index c2c7da94c4..4b1e68de43 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -74,6 +74,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize @@ -87,6 +88,9 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire + [Ppis] gEfiPeiMasterBootModePpiGuid diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index 93e3594e29..a12e6768ae 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -539,13 +539,25 @@ FindPeiCoreImageBase ( OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase ) { + BOOLEAN S3Resume; + *PeiCoreImageBase = 0; - if (IsS3Resume ()) { + S3Resume = IsS3Resume (); + if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) { + // + // A malicious runtime OS may have injected something into our previously + // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required. + // DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n")); GetS3ResumePeiFv (BootFv); } else { - DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n")); + // + // We're either not resuming, or resuming "securely" -- we'll decompress + // both PEI FV and DXE FV from pristine flash. + // + DEBUG ((EFI_D_VERBOSE, "SEC: %a\n", + S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot")); FindMainFv (BootFv); DecompressMemFvs (BootFv); diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf index 9e8571dddd..711b595309 100644 --- a/OvmfPkg/Sec/SecMain.inf +++ b/OvmfPkg/Sec/SecMain.inf @@ -71,3 +71,6 @@ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd + +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire