rvvm_user: standalone userland runner with Linux syscall layer hardening - #288
Merged
Conversation
- Add src/rvvm_user_main.c entry point and rvvm_user build target
behind the RVVM_USER_TEST flag (project.mk)
- syscall fixes for running real static ELF binaries (musl/ant runtime):
* 425 io_uring_setup: return -ENOSYS instead of falling through
* 123 sched_getaffinity: pass through host affinity mask
* 21/22 epoll_ctl/epoll_pwait: convert between packed x86-64 host
struct epoll_event (12B) and naturally-aligned guest layout (16B)
* 259 riscv_flush_icache: optional RVVM_JITDUMP=1 dumps each flushed
guest code range for inspection
* 220 clone: RVVM_USER_NO_THREADS=1 forces -EAGAIN (debug knob)
- Allow prefix_path override via RVVM_USER_PREFIX env var (empty value
disables the prefix entirely); the hardcoded default broke absolute
guest paths
- Improve ELF load failure diagnostics: retry open, distinguish open vs
VMA-collision failures, dump /proc/self/maps on load failure
- rvvm_create_userland: RVVM_NOJIT env var disables host JIT
(pure interpreter mode for bisecting)
- elf_load: map ELF_USERLAND_HEAP_MARGIN (256MB) past the fixed ELF
image so early brk accesses do not fault, matching kernel behavior
Verified with a 67MB static musl RISC-V ELF embedding the ant JS
runtime: boots, runs the event loop and produces output identical to
qemu-riscv64.
…nalyzer fd false positives
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.
Motivation
Upstream ships
rvvm_user.cas dormant experimental code:RVVM_USER_TESTiscommented out and there is no build target for it. This PR makes the userland
runner actually usable as a standalone
rvvm_userbinary, and hardens theLinux syscall layer until real-world static RISC-V binaries run to completion.
For validation this PR borrows guest ELFs from a reproduction package aimed at
user-mode host implementations of a guest-JIT bug: a statically linked
riscv64 musl JS runtime ("ant", cross-compiled with zig) plus a 1MB JS
workload. They are used here solely to verify that
rvvm_userrunsreal-world static binaries.
Summary
A standalone userland runner (
rvvm_user) plus a set of Linux syscall-layerfixes discovered while running real-world static RISC-V binaries under
user-mode emulation.
Changes
New entry point / build
src/rvvm_user_main.c: standalonervvm_userbinary entryproject.mk: buildsrvvm_userand definesRVVM_USER_TESTonly on64-bit Linux targets; all other targets (including i386) keep the existing
upstream stub behavior unchanged
Syscall correctness fixes
425 io_uring_setup: return-ENOSYSinstead of falling through123 sched_getaffinity: pass through the host affinity mask21/22 epoll_ctl / epoll_pwait: translate between the packed x86-64 hoststruct epoll_event(12 bytes) and the naturally-aligned guest layout(16 bytes); previously events were corrupted on x86-64 hosts
259 riscv_flush_icache: optionalRVVM_JITDUMP=1dumps each flushedguest code range (useful for debugging guest JITs)
220 clone:RVVM_USER_NO_THREADS=1knob forcing-EAGAIN(debug aid)Usability
RVVM_USER_PREFIXenv var overrides the hardcodedprefix_path(emptyvalue disables the prefix); the hardcoded default silently broke absolute
guest paths
RVVM_NOJITenv var for pure-interpreter userland (bisecting JIT issues)errors,
/proc/self/mapsdumpELF loading
ELF_USERLAND_HEAP_MARGIN) past the fixed ELF image as theinitial brk area, matching how real kernels map pages after the image;
without this, early brk accesses on non-relocatable static ELFs fault
CI / build hygiene
prefix_pathconst-correctness andgetcwd/chdirreturn value checks(
-Werrorclean)-fanalyzerfd-leak false positives: guest fd numbers passedthrough the syscall dispatch are not host descriptors (scoped
#pragma,GCC 12+ only)
Testing
make CFLAGS="-Werror"clean on x86_64 GCC/clang, riscv64 cross-compile,and a mingw cross-build simulation;
make test(riscv-tests) passeshttps://github.com/linsmod/ant_agent_repro/releases/download/binaries-v1/ant_jit_runner_repro.zip