Skip to content

arch/x86: Provide vfork() - #19777

Draft
casaroli wants to merge 1 commit into
apache:masterfrom
casaroli:x86-vfork
Draft

arch/x86: Provide vfork()#19777
casaroli wants to merge 1 commit into
apache:masterfrom
casaroli:x86-vfork

Conversation

@casaroli

Copy link
Copy Markdown
Contributor

Summary

x86 selected neither fork primitive. vfork() was not available on this architecture at all. This pull request provides it.

fork.S takes the register snapshot of the caller and hands it to x86_fork(), which allocates the child, copies the used part of the stack of the caller, and starts it. There is one entry point for both primitives, because the snapshot is the same for either.

The calling convention differs from every other architecture that has this. cdecl puts the flag on the stack, so up_fork() loads it from 4(%esp) rather than keeping a register alive. That slot is also the stack pointer the caller had: the caller pushed the argument, then call pushed the return address. The low end of the region that x86_fork() copies is therefore unchanged.

Impact

The change is specific to x86. It adds capability and removes none.

vfork() becomes available on x86. Code that tests CONFIG_ARCH_HAVE_VFORK now finds it here.

POSIX fork() is not provided. It needs an address environment that can be duplicated, and this architecture has none, so CONFIG_ARCH_HAVE_FORK is never set. x86_fork.c makes that a build error rather than a silent omission:

#ifdef CONFIG_ARCH_HAVE_FORK
#  error "x86 has no address environment; fork() cannot be provided"
#endif

No board configuration changes.

Testing

Emulation only. QEMU 11.0.3 on macOS 15 with Apple Silicon, i686-elf-gcc from Homebrew.

qemu-i486:nsh, with ostest typed at the prompt:

qemu-system-i386 -cpu qemu32,+fpu -m 128 -kernel nuttx.elf \
  -nographic -no-reboot -net none
NuttShell (NSH) NuttX-12.2.1
user_main: vfork() test
vfork_test: Started
vfork_test: Child 5 ran and exited before the parent resumed
ostest_main: Exiting with status 0

fork() is correctly absent from that run.

tools/checkpatch.sh -c -u -m -g gives no errors.

Two notes for anyone repeating this. i686-elf-gcc is a bare cross compiler with no libc, so nothing provides math.h and the build stops in lib_strtold.c. Select CONFIG_LIBM instead of CONFIG_LIBM_TOOLCHAIN. And use qemu-i486:nsh, not qemu-i486:ostest: that configuration consoles through CONFIG_CONSOLE_SYSLOG and floods the output, which is #19568 and unrelated to this change.

What is not tested

No x86 hardware.

A report from a board would be welcome. Take this branch with apache/nuttx-apps#3685, build qemu-i486:nsh and run ostest. The vfork() test is the first output.

@github-actions github-actions Bot added Arch: x86 Issues related to the x86 architecture Size: L The size of the change in this PR is large labels Aug 10, 2026
x86 selected neither fork primitive, so vfork() was not available on this
architecture at all.

fork.S takes the register snapshot and hands it to x86_fork(), which allocates
the child, copies the used part of the caller's stack, and starts it.  There is
one entry point for both primitives, because the snapshot is the same for
either.

Unlike the register-passing architectures, cdecl puts the flag on the stack, so
up_fork() loads it from 4(%esp).  That slot is also the stack pointer the
caller had:  it pushed the argument, then `call' pushed the return address.  So
the low end of the region that x86_fork() copies is unchanged.

POSIX fork() is not provided.  It needs an address environment that can be
duplicated and this architecture has none, so CONFIG_ARCH_HAVE_FORK is never
set here.  x86_fork.c makes that a build error rather than a silent omission.

Verified under QEMU with qemu-i486:nsh.  ostest runs to the end and reports
"Child 5 ran and exited before the parent resumed", with fork() correctly
absent.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: x86 Issues related to the x86 architecture Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant