aarch64 stage2: move fork save-area to Entry 2 (fix nested-fork hang)#9
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to fix an AArch64 stage2 nested-fork hang by relocating the fork-emulation “saved process memory” bump allocator away from the live kernel stack region by changing its initialization base address (and updating the corresponding documentation/encoded outputs).
Changes:
- Update the documented memory layout to describe the saved-process-memory region as being in paging Entry 2.
- Change
next_save_process_addressinitialization from0x78000000to0x80000000in the AArch64 stage2 source. - Propagate the same change into the
.hex2and.hex0representations.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| builder-hex0-aarch64-stage2.S | Updates memory-layout comments and the save-area base initialization constant. |
| builder-hex0-aarch64-stage2.hex2 | Mirrors the updated save-area base in the hex2-encoded stage2 output. |
| builder-hex0-aarch64-stage2.hex0 | Mirrors the updated save-area base in the hex0-encoded stage2 output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Owner
Author
|
The raspi3b issues are expected, it's the next step on this. |
The fork-emulation save area (a bump allocator that memcpy's the parent's whole process image plus its kernel and user stacks on every clone) was initialized at VA 0x78000000 -- inside paging Entry 1, growing up toward the kernel-stack top at 0x7B800000. That gave it only ~56MB AND backed it directly onto the live, descending kernel stack. A process with a heap of tens of MB therefore overran the save area into the kernel stack on its first fork, corrupting return addresses -> silent hang (a CPU fault would have printed "!EC:..." and exited 139 instead). hs hit this running its probe sweep (hs forks+execs hs; its startup heap is ~55MB), where riscv64 -- whose save area is 576MB and separate from the kernel stack -- did not. Move the save area to VA 0x80000000 on virt (Entry 2 -> PA 0x80000000): ~540MB up to file data at 0xA1900000, clear of the kernel stack. The base is chosen per board, because the two boards map the upper VA window to different physical RAM: raspi3b's Entry 2 aliases PA 0x00000000, so VA 0x80000000 there would overwrite the kernel in low RAM. raspi3b therefore keeps the legacy base VA 0x78000000 (Entry 1 -> PA 0x38000000, valid in its 1GB RAM) -- its original, unchanged behavior. Board is selected via x27 (3 = raspi3b, 0 = virt), the same id _trampoline/load_ram_base already use for storage/UART setup.
alganet
force-pushed
the
aarch64-fork-savearea-fix
branch
from
June 16, 2026 19:55
b0fe120 to
7f49d51
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The fork-emulation save area (a bump allocator that memcpy's the parent's whole process image plus its kernel and user stacks on every clone) was initialized at VA 0x78000000 -- inside paging Entry 1, growing up toward the kernel-stack top at 0x7B800000. That gave it only ~56MB AND backed it directly onto the live, descending kernel stack.
A process with a heap of tens of MB therefore overran the save area into the kernel stack on its first fork, corrupting return addresses -> silent hang (a CPU fault would have printed "!EC:..." and exited 139 instead). hs hit this running its probe sweep (hs forks+execs hs; its startup heap is ~55MB), where riscv64 -- whose save area is 576MB and separate from the kernel stack -- did not. The header comment already documented the intended Entry-2 layout ("saved process mem at 0xB0000000"); the code just shipped the wrong base.
Relocate the save area to VA 0x80000000 (Entry 2, identity-mapped): ~540MB up to file data at 0xA1900000, clear of the kernel stack. One constant.