The PEI dispatcher handles PEIMs and embedded firmware volume images. PEIMs are loaded and called (1), while embedded firmware volume images are recursively scanned (2) for PEIMs and for further embedded firmware volume images. FirmwareVolmeInfoPpiNotifyCallback() is the function directly producing the newly detected entries for the dispatcher.
PeiDispatcher() [MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c] (3) DepexSatisfied() (4) PeiServicesFfsFindSectionData(DEPEX) [MdePkg/.../PeiServicesLib.c] PeiFfsFindSectionData() [MdeModulePkg/Core/Pei/FwVol/FwVol.c] PeiFfsFvPpiFindSectionByType() PeiFfsFvPpiFindSectionByType2() ProcessSection() (5) Decompress() [MdeModulePkg/Core/DxeIplPeim/DxeLoad.c] AllocatePages() [MdePkg/.../PeiMemoryAllocationLib] if satisfied: PeiFfsFvPpiGetFileInfo() [MdeModulePkg/Core/Pei/FwVol/FwVol.c] if EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: (2) ProcessFvFile() PeiServicesInstallFvInfo2Ppi() [MdePkg/.../PeiServicesLib] InternalPeiServicesInstallFvInfoPpi() PeiServicesInstallPpi() FirmwareVolmeInfoPpiNotifyCallback() [.../FwVol.c] ProcessFvFile() ... else: (1) PeiLoadImage() PeiDispatcher checks for dependency expressions first (3), and the type-dependent processing in (1) and (2) happens only if such a Depex is satisfied (or absent). Files of type EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE can have no Depex sections, they are pure containers. DepexSatisfied() at (3) always returns TRUE for them, so functionality is not directly harmed. However, an EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE can be compressed. In order to look up the (nonexistent) Depex section (4), the Decompress routine (5) is called. Unfortunately, the Decompress() routine allocates EfiBootServicesData memory. This is not permitted on the S3 Resume path, but PeiDispatcher() is part of the S3 Resume path. The problem is triggered by OVMF's firmware structure: FD.OVMF FV.FVMAIN_COMPACT uncompressed FV.MAINFV compressed with LzmaCompress individual PEI modules uncompressed FV.DXEFV compressed with PI_NONE individual DXE modules uncompressed FV.SECFV uncompressed FV.MAINFV is decompressed by OVMF's SEC and is only exposed to the PEI dispatcher in decompressed form, so that's not the problem. However FV.DXEFV, which is a direct sibling of the PEIMs, is compressed (with the PI_NONE === EFI_NOT_COMPRESSED compression subtype). This causes an invalid EfiBootServicesData allocation during S3 Resume, inside the useless Depex check. Avoiding the allocation by restricting the Depex check in PeiDispatcher() to PEIMs doesn't help: ProcessFvFile() under (2) triggers the same allocation by calling PeiFfsFvPpiFindSectionByType2() -- it must decompress the file in order to scan it. Changing FV.DXEFV's encapsulation from COMPRESS to GUIDED won't help either, because in that case ProcessSection() would want to call EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI.ExtractSection(), which again allocates memory. Solve this by flattening FV.MAINFV: FD.OVMF FV.FVMAIN_COMPACT uncompressed FV.MAINFV compressed with LzmaCompress individual PEI modules uncompressed individual DXE modules uncompressed FV.SECFV uncompressed This way we avoid recursive processing, without hurting the efficiency of the outermost compression (in FV.MAINFV). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- OvmfPkg/OvmfPkgX64.fdf | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index e435486..2508c22 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -250,6 +250,12 @@ APRIORI PEI { INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf } +APRIORI DXE { + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf +} + # # PEI Phase modules # @@ -261,39 +267,6 @@ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf INF OvmfPkg/EmuSmmPei/EmuSmmPei.inf INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf -FILE FV_IMAGE = A4EF5A93-3F1B-4232-A1C4-F0910E6D1D9C { - SECTION COMPRESS PI_NONE { - SECTION FV_IMAGE = DXEFV - } -} - -################################################################################ - -[FV.DXEFV] -BlockSize = 0x10000 -FvAlignment = 16 -ERASE_POLARITY = 1 -MEMORY_MAPPED = TRUE -STICKY_WRITE = TRUE -LOCK_CAP = TRUE -LOCK_STATUS = TRUE -WRITE_DISABLED_CAP = TRUE -WRITE_ENABLED_CAP = TRUE -WRITE_STATUS = TRUE -WRITE_LOCK_CAP = TRUE -WRITE_LOCK_STATUS = TRUE -READ_DISABLED_CAP = TRUE -READ_ENABLED_CAP = TRUE -READ_STATUS = TRUE -READ_LOCK_CAP = TRUE -READ_LOCK_STATUS = TRUE - -APRIORI DXE { - INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf - INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf - INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf -} - # # DXE Phase modules # -- 1.8.3.1 ------------------------------------------------------------------------------ Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel