Skip to content

MsvmPkg: fix CLANGPDB X64 boot hang from misaligned PEI - #96

Merged
John Starks (jstarks) merged 1 commit into
microsoft:mainfrom
jstarks:clangpdb
Jul 22, 2026
Merged

MsvmPkg: fix CLANGPDB X64 boot hang from misaligned PEI#96
John Starks (jstarks) merged 1 commit into
microsoft:mainfrom
jstarks:clangpdb

Conversation

@jstarks

Copy link
Copy Markdown
Member

The CLANGPDB X64 firmware hangs in early PEI: PeiCore dispatches its first PEIMs (the apriori PcdPeim and EfiDiagnosticsPei), fails to load them, and then never runs PlatformPei to install permanent memory, so it asserts on PeiMemoryInstalled == TRUE at PeiMain.c(560). Because no exception handlers are installed this early, the failure surfaces only as a silently wedged VP.

The root cause is an FV packing mismatch. The X64 FDF packed PEI_CORE and PEIM files with a fixed 32-byte alignment (Align=32), a legacy idiom that assumes XIP PEI modules have small section alignment. But the platform DSC forces 4K section alignment on all PEI-phase modules for page protection, and x64 PE images default to 4K section alignment regardless. When a module's section alignment exceeds the FV packing alignment, PeiCore's image loader cannot execute it in place, and in pre-memory PEI it cannot shadow it to RAM either, so dispatch fails. CLANGPDB exposes this because it honors the 4K section alignment, leaving every dispatched PEIM at a 32-byte-aligned flash address that PeiCore rejects.

Switch the PEI_CORE, PEIM, and PLATFORM_PEI rules to Align=Auto so GenFds pads each file to the actual section alignment reported by its PE header, which is the standard EDK2 idiom (matching upstream OvmfPkg). This makes the packing adapt to whatever alignment the toolchain emits instead of assuming 32 bytes.

Apply the same Align=Auto change to the AARCH64 FDF for consistency. That FDF already used a hardcoded Align=4K that happens to match its 4K PEI section alignment, so Auto resolves to the same value and placement is unchanged; it is switched purely to keep both FDFs on the same, self-adjusting rule.

The CLANGPDB X64 firmware hangs in early PEI: PeiCore dispatches its
first PEIMs (the apriori PcdPeim and EfiDiagnosticsPei), fails to load
them, and then never runs PlatformPei to install permanent memory, so
it asserts on PeiMemoryInstalled == TRUE at PeiMain.c(560). Because no
exception handlers are installed this early, the failure surfaces only
as a silently wedged VP.

The root cause is an FV packing mismatch. The X64 FDF packed PEI_CORE
and PEIM files with a fixed 32-byte alignment (Align=32), a legacy
idiom that assumes XIP PEI modules have small section alignment. But
the platform DSC forces 4K section alignment on all PEI-phase modules
for page protection, and x64 PE images default to 4K section alignment
regardless. When a module's section alignment exceeds the FV packing
alignment, PeiCore's image loader cannot execute it in place, and in
pre-memory PEI it cannot shadow it to RAM either, so dispatch fails.
CLANGPDB exposes this because it honors the 4K section alignment,
leaving every dispatched PEIM at a 32-byte-aligned flash address that
PeiCore rejects.

Switch the PEI_CORE, PEIM, and PLATFORM_PEI rules to Align=Auto so
GenFds pads each file to the actual section alignment reported by its
PE header, which is the standard EDK2 idiom (matching upstream OvmfPkg).
This makes the packing adapt to whatever alignment the toolchain emits
instead of assuming 32 bytes.

Apply the same Align=Auto change to the AARCH64 FDF for consistency.
That FDF already used a hardcoded Align=4K that happens to match its 4K
PEI section alignment, so Auto resolves to the same value and placement
is unchanged; it is switched purely to keep both FDFs on the same,
self-adjusting rule.
@jstarks
John Starks (jstarks) merged commit 6375720 into microsoft:main Jul 22, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants