In a kernel build vfork() is reached through a system call, so the return
address and stack pointer the architecture's entry point can see for itself
are the kernel's, not the caller's. A child built from those resumes at a
kernel address, which is why x86_64 selected the fork family only for the
flat build.
x86_64_syscall() now publishes the caller's frame in xcp.sregs for the
duration of the stub call, and x86_64_fork() builds the child from it:
x86_64_fork_syscall() when xcp.sregs is non-NULL, so that the child
returns from the very same `syscall' instruction as
the parent, in user mode, on its own stack;
x86_64_fork_direct() otherwise, which is the flat build and any kernel
thread that calls the entry point as a plain
function.
The discriminator is xcp.sregs rather than TCB_FLAG_SYSCALL, which arm64 and
RISC-V use: that flag also defers signal actions, x86_64 has never raised it,
and its kernel-build signal path does not survive being made to -- a
pre-existing problem that does not belong to this work.
Two properties of SYSCALL/SYSRET shape the child's frame. The instruction
leaves the caller's RIP and RFLAGS in RCX and R11 rather than on a stack, so
they are moved into the RIP and RFLAGS slots of the interrupt frame the child
is resumed from; and the hardware never records the caller's CS and SS at all,
SYSRETQ reconstructing them from IA32_STAR, so the child's are filled in with
the user code and data selectors at RPL 3. The frame is therefore not copied
wholesale: the extended state and the general registers are inherited, while
the segment registers and the thread pointer stay as up_initial_state() left
them, the child's stack being a fresh allocation the parent's FS base does not
describe.
x86_64_fork_relocfp() is new and is not optional here. A function returns
with `leave', which feeds the frame pointer into the stack pointer, so
relocating only the RBP the child resumes with gets it exactly one frame:
the next return loads a saved RBP still pointing into the parent's stack.
With that in place ARCH_X86_64 can select ARCH_HAVE_VFORK unconditionally.
Build-verified on qemu-intel64:knsh_romfs and qemu-intel64:ostest. NuttX on
qemu-intel64 requires tsc-deadline and pcid, which TCG does not implement, so
it cannot be run on this host.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
|
||
|---|---|---|
| .github | ||
| arch | ||
| audio | ||
| binfmt | ||
| boards | ||
| cmake | ||
| crypto | ||
| Documentation | ||
| drivers | ||
| dummy | ||
| fs | ||
| graphics | ||
| include | ||
| libs | ||
| mm | ||
| net | ||
| openamp | ||
| pass1 | ||
| sched | ||
| syscall | ||
| tools | ||
| video | ||
| wireless | ||
| .asf.yaml | ||
| .codespell-ignore-lines | ||
| .codespellrc | ||
| .editorconfig | ||
| .gitignore | ||
| .gitmessage | ||
| .pre-commit-config.yaml | ||
| .yamllint | ||
| AUTHORS | ||
| CMakeLists.txt | ||
| CONTRIBUTING.md | ||
| INVIOLABLES.md | ||
| Kconfig | ||
| LICENSE | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
| ReleaseNotes | ||
Apache NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 64-bit microcontroller environments, the primary governing standards in NuttX are POSIX and ANSI standards. Additional standard APIs from Unix and other common RTOSs (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()).
For brevity, many parts of the documentation will refer to Apache NuttX as simply NuttX.
Getting Started
First time on NuttX? Read the Getting Started guide! If you don't have a board available, NuttX has its own simulator that you can run on terminal.
Documentation
You can find the current NuttX documentation on the Documentation Page.
Alternatively, you can build the documentation yourself by following the Documentation Build Instructions.
The old NuttX documentation is still available in the Apache wiki.
Supported Boards
NuttX supports a wide variety of platforms. See the full list on the Supported Platforms page.
Contributing
If you wish to contribute to the NuttX project, read the Contributing guidelines for information on Git usage, coding standard, workflow and the NuttX principles.
License
The code in this repository is under either the Apache 2 license, or a license compatible with the Apache 2 license. See the License Page for more information.