Repository navigation
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
Boot-critical manifest access and heap relocation need platform validation covering MMU/cache behavior, exhausted IMR space, and D3 suspend/resume.
No open issues 🎉
What changed in this PR
This PR prevents L3 heap allocations from overwriting the firmware image retained in IMR, addressing suspend/resume boot failures with LL userspace enabled on NVL.
Changes:
- Calculate the heap start from the manifest’s preload page count, keeping it at or beyond the existing fixed base.
- Calculate available heap space from the adjusted start.
- Skip heap initialization and reject L3 allocations when no usable IMR space remains.
| File | Description |
|---|---|
zephyr/lib/alloc.c |
Places the L3 heap after the retained firmware image and handles exhausted IMR space. |
Review effort: Balanced
PR 11335: test resultsRun date: 2026-10-22 17:07 UTC Tested commit: 8b94716f02622d0d6c1eccc2f172e6307e83e5da |
| image_end = IMR_BOOT_LDR_MANIFEST_BASE + | ||
| desc->header.preload_page_count * HOST_PAGE_SIZE; | ||
|
|
||
| return ROUND_UP(MAX(IMR_L3_HEAP_BASE, image_end), L3_MEM_PAGE_SIZE); |
There was a problem hiding this comment.
maybe we should just get rid of IMR_L3_HEAP_BASE. The define is marked with "FIXME"
There was a problem hiding this comment.
Ack @wjablon1 , it seems it's not used anywhere else, so indeed, let's just drop it. I'll updated this to V2. Once merged, we can post a PR to remove the definition from Zephyr side.
| */ | ||
| size_t offset = IMR_L3_HEAP_BASE - L3_MEM_BASE_ADDR; | ||
| uintptr_t imr_end = L3_MEM_BASE_ADDR + ace_imr_get_mem_size(); | ||
| uintptr_t start = get_l3_heap_start(); |
There was a problem hiding this comment.
Minor: Since the calculation is now more complicated, I would consider renaming those functions to calc_heap_start and calc_heap_size and call them only upon heap creation. After that the size could be obtain from heap global structure.
There was a problem hiding this comment.
Ack, addressed in V2.
The L3 heap started at the fixed IMR_L3_HEAP_BASE offset. The firmware image stays in IMR after boot, and when the DSP is resumed from IMR, the boot loader copies the image to SRAM again from there. If the image extends beyond IMR_L3_HEAP_BASE, heap initialization and L3 allocations (e.g. the LLEXT context saved before D3) overwrite the tail of the image and the next IMR boot hangs before the firmware is ready. This happens with LL userspace enabled on NVL, where the image ends at L3 base + 0x185000 while the heap started at L3 base + 0x151000. The host reports "Firmware boot failure due to timeout" when the stream is started after the DSP has been suspended. Drop the fixed IMR_L3_HEAP_BASE and calculate the end of the image from the preload page count in the firmware manifest and start the heap after it. Leave the L3 heap uninitialized if there is no IMR space left after the image, and fail L3 allocations in that case. Rename get_l3_heap_start() and get_l3_heap_size() and only call the new calc_l3_heap_*() functions at l3 heap init time. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
8b94716 to
1181ba7
Compare
|
V2 pushed:
|
The L3 heap started at the fixed IMR_L3_HEAP_BASE offset. The firmware image stays in IMR after boot, and when the DSP is resumed from IMR, the boot loader copies the image to SRAM again from there. If the image extends beyond IMR_L3_HEAP_BASE, heap initialization and L3 allocations (e.g. the LLEXT context saved before D3) overwrite the tail of the image and the next IMR boot hangs before the firmware is ready.
This happens with LL userspace enabled on NVL, where the image ends at L3 base + 0x185000 while the heap started at L3 base + 0x151000. The host reports "Firmware boot failure due to timeout" when the stream is started after the DSP has been suspended.
Calculate the end of the image from the preload page count in the firmware manifest and start the heap after it, if that is beyond IMR_L3_HEAP_BASE. Leave the L3 heap uninitialized if there is no IMR space left after the image, and fail L3 allocations in that case.