nuttx/Documentation/guides
Marco Casaroli 067e30e14f arch/x86_64: Build fork() children from the caller's syscall frame.
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>
2026-08-10 08:57:30 -03:00
..
image docs/guides/bootsequence: Migrate UML diagram to PlantUML 2026-02-15 08:47:23 +01:00
porting-case-studies !arch/arm: Use r9 as the PIC base register. 2026-08-06 01:38:23 +08:00
armv7m_runtimestackcheck.rst style: Fix "the the" typo across the codebase. 2026-03-23 11:07:49 +01:00
automounter.rst Documentation: migrate "Auto-Mounter" from wiki 2023-11-06 18:42:17 -03:00
building_nuttx_with_app_out_of_src_tree.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
building_uclibcpp.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
changing_systemclockconfig.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
cpp_cmake.rst Documentation/guides: Update CMake C++ guide 2025-09-15 15:30:15 -03:00
custom_app_directories.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
customapps.rst Doc: Fix CustomApps/CustomHello example 2024-07-20 13:17:48 +08:00
customboards.rst docs/guides/customboards: Mention special Kconfig settings 2026-06-18 21:51:48 +08:00
devicetree.rst fdt: add fdt description document 2024-09-30 14:20:49 +08:00
drivers.rst Documentation: various cosmetic changes 2023-10-30 20:29:54 +08:00
etcromfs.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
fork_vfork_migration.rst arch/x86_64: Build fork() children from the caller's syscall frame. 2026-08-10 08:57:30 -03:00
fortify.rst Doc: Fortify Instructions 2025-01-23 15:36:14 +08:00
fully_linked_elf.rst docs: Update the ELF guides 2025-06-11 23:11:08 +08:00
include_files_board_h.rst style: Fix "the the" typo across the codebase. 2026-03-23 11:07:49 +01:00
index.rst !Documentation: Describe the fork()/vfork() split. 2026-08-10 08:57:30 -03:00
integrate_newlib.rst style: fix typos 2025-04-30 13:45:46 +08:00
ipv6.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
kernel_threads_with_custom_stacks.rst sched/task: fix Redundant memory allocation. 2026-01-01 07:25:04 -03:00
logging_rambuffer.rst drivers/syslog: remove implement of syslog_putc() 2024-11-15 19:46:36 +08:00
lwl.rst docs/guides/lwl: move lwl's README.txt to lwl.rst 2025-12-23 15:20:06 +01:00
multiple_nsh_sessions.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
nestedinterrupts.rst Documentation: Fix typos 2023-10-29 10:35:51 +08:00
nfs.rst documentation: correct the nfs command format 2023-07-03 10:18:00 -03:00
nix_flake.rst tools/nix: move nix flakes to tools/ 2025-08-28 10:04:01 +08:00
nsh_network_link_management.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
ofloader.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
optee.rst drivers/misc/optee: Expanded RPC support. 2025-08-06 02:29:33 +08:00
partially_linked_elf.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
platform_directories.rst style: fix typos 2025-04-30 13:45:46 +08:00
port.rst style: fix typos 2025-04-30 13:45:46 +08:00
port_bootsequence.rst docs/guides/bootsequence: Migrate UML diagram to PlantUML 2026-02-15 08:47:23 +01:00
port_drivers_to_stm32f7.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
port_relatedkernelconfigrations.rst Documentation/guides: add the guide:how to port. 2024-12-12 21:52:24 +08:00
protected_build.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
pysimcoder.rst Documentation: fix spelling 2025-05-15 11:33:41 +08:00
qemu_tips.rst Documentation: add notes about TAP configuration for qemu 2025-12-18 11:39:54 -03:00
ram_rom_disks.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
reading_can_msgs.rst nuttx/can: add message alignment 2025-11-24 14:11:41 +08:00
remove_device_drivers_nsh.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
renode.rst !arch/stm32h7: use common STM32 Kconfig symbols 2026-06-14 11:35:31 -03:00
rndis.rst style: fix typos 2025-04-30 13:45:46 +08:00
rust.rst !sched/clock: remove CONFIG_SYSTEM_TIME64 and always use 64-bit time 2026-05-19 16:21:28 +08:00
semihosting.rst doc: Add semihost syslog guide instructions 2025-10-24 09:56:24 +08:00
signal_events_interrupt_handlers.rst Doc: Replace link from old wiki to new wiki in signaling events from int 2024-10-28 09:35:07 +08:00
signaling_sem_priority_inheritance.rst Doc: Migration Signaling Semaphores and priority inheritance 2024-10-28 09:35:07 +08:00
simulator.rst Documentation: add nxmodbus doc 2026-04-21 09:39:04 +08:00
smaller_vector_tables.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
specialstuff_in_nuttxheaderfiles.rst Doc: Migrate Put special stuff in NuttX header files 2024-10-15 01:22:59 +08:00
stm32_ports.rst arch/arm/src/stm32: unify pulse count driver into common/stm32 2026-07-12 09:35:51 +08:00
stm32ccm.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
stm32nullpointer.rst style: Fix "the the" typo across the codebase. 2026-03-23 11:07:49 +01:00
testingtcpip.rst Documentation: Fix various typos 2023-11-23 16:38:19 -08:00
thread_local_storage.rst doc: Fix code blocks in thread_local_storage.rst 2024-08-03 21:15:05 +08:00
updating_release_system_elf.rst Doc: improve and add documentations for the guide section of the wiki 2024-12-30 12:32:42 +08:00
usbtrace.rst !boards: Remove NSH_ARCHINIT and board_app_initialize 2026-05-02 18:36:46 +08:00
usingkernelthreads.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00
versioning_and_task_names.rst Documentation/Make: add implementation/make_build_system.rst 2025-11-20 09:39:16 -05:00
zerolatencyinterrupts.rst !arch/stm32: move stm32l1 and finalize the directory split 2026-06-24 14:54:44 -03:00