[Bug 286875] emulators/qemu-user-static-devel: Switch to blitz, and sync to 11.0.50; restore build on 15+
Date: Mon, 14 Sep 2026 07:55:13 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=286875
--- Comment #38 from Rick Richard <rick@sloservers.com> ---
Testing blitz HEAD (e725658f, VERSION 11.0.50) on FreeBSD 15.1-RELEASE-p2 amd64
with an armv7 guest jail, per comment #10.
blitz HEAD builds, but does not execute guest binaries on 15.1. Six defects,
all
in bsd-user, none of them port-side. The pull request below carries two further
fixes found afterwards: a lost thread wakeup, which armv7 does not reach, and
accept4(2) dropping its flags, which it does:
https://github.com/qemu-bsd-user/qemu-bsd-user/pull/68
1. target_mmap() checks MAP_EXCL against the guest address space with
page_check_range_empty() and then forwards the flag to the host mmap. When
reserved_va is set, qemu has already mapped the guest range as a PROT_NONE
reservation, so MAP_FIXED|MAP_EXCL returns ENOMEM for every PT_LOAD segment
the ELF loader places inside it. No guest binary reaches its entry point.
2. cap_rights_limit(2), cap_ioctls_limit(2), cap_fcntls_limit(2) and
cap_enter(2) return ENOSYS, and the cpu loop raises SIGSYS for any syscall
that returns ENOSYS. /bin/echo calls cap_rights_limit(2) during startup and
exits on SIGSYS.
3. TARGET_BIG_ENDIAN is written into the per-target config header as a value:
arm-bsd-user-config-target.h: #define TARGET_BIG_ENDIAN 0
ppc-bsd-user-config-target.h: #define TARGET_BIG_ENDIAN 1
Four sites in bsd-user still test it with #ifdef, which matches on every
target, so little-endian targets compile the big-endian branch. In
do_bsd_lseek() the two halves of the 64-bit off_t return are swapped:
lseek(fd, 0, SEEK_END) on a 154556-byte file returns 154556 << 32.
pkg-static reports "Seek error" and cannot extract packages. This is
issue #28, which also notes the ppc site.
4. loader_exec() resolves the program with realpath() into a stack array and
stores that pointer in bprm->fullpath, which outlives the call. The guest
reads it back through KERN_PROC_PATHNAME and gets an empty string. perl
derives $^X from that sysctl, so lang/perl5 fails in mkppport, which invokes
$^X and reaches the emulator binary instead of miniperl.
devel/p5-Locale-gettext
and devel/p5-Locale-libintl, the ports in issues #24 and #29, build with
this
applied.
5. posix_fadvise(2) is unimplemented, reaches the default case, and returns
ENOSYS, which becomes SIGSYS. xz(1) calls it, and devel/gettext-tools dies
in its autotools directory.
6. qemu_thread_create() leaves SIGSEGV, SIGFPE and SIGILL unblocked in helper
threads, since blocking a synchronous fault is undefined. A process-directed
signal can therefore arrive on a thread that runs no guest code, where
thread_cpu is NULL, and host_signal_handler() dereferenced it. A guest that
blocks SIGFPE and calls kill(getpid(), SIGFPE) crashes qemu. This is
issue #34.
Results for the libthr regressions tracked in issues #30 to #37. Three columns,
so that upstream's work and these patches are not conflated:
- 6.2.50: the version the port currently builds, with the #37 batching fix
from ab12ac38ef backported so the comparison is not against a known-broken
umtx path
- blitz: blitz HEAD with only the two patches needed to execute a guest at
all (items 1 and 2 above)
- blitz+8: blitz HEAD with the full series
6.2.50 blitz blitz+8
#37 umtx_op_test:batching pass pass pass
#36 timedmutex_test:mutex3 fail pass pass
#35 timedmutex_test:mutex2 pass pass pass
#34 sigmask_test:upcalls_not_started fail fail pass
#33 sem_test:before_start_one_thread timeout pass pass
#32 sem_test:before_start_no_threads timeout pass pass
#31 mutex_test:mutex2 timeout pass pass
#30 cond_test:cond_timedwait_race fail pass pass
Six of these are already fixed on blitz and owe nothing to the patches above;
the middle column is there to make that clear. Only #34 needed a new fix, item
6. The first column is the argument for moving the port off 6.2.50.
Regarding comment #28 and the reliable hang creating the pkg package: item 3
looks like the cause. pkg-static uses lseek heavily and was receiving offsets
with the halves transposed. That is a hypothesis rather than a confirmed
diagnosis, since I did not reproduce the hang before fixing the endianness
test,
but pkg-static has been exercised heavily since and has not hung.
With the first six applied, poudriere cross-built 80 armv7 packages: 80 built,
0
failed, 0 skipped, in 1h40m. A 14-port request expanded to that closure,
covering perl5, python312, ruby34, git, openssl, sqlite3, curl, cmake, nginx,
bash, libarchive, texinfo and the autotools. Every package went through
pkg-static create, and the run also exercises pkg-static add.
Host: FreeBSD 15.1-RELEASE-p2 amd64, 8 cores. Guest jail: 15.1-STABLE 1501502,
arm.armv7, built with poudriere jail -m git+https. Ports tree 8fd09ff988d2.
I am not proposing a port patch; the work in this bug covers what I ran into.
One port-side item in case it is not already handled: qemu 11 emits the target
binaries directly into ${BUILD_WRKSRC} with no per-target *-bsd-user
subdirectories, so an ELF_FEATURES setting of the form
"+wxneeded:*-bsd-user/qemu-*" matches nothing and elfctl fails the build.
Deriving the list from QEMU_TARGETS works:
ELF_FEATURES= ${QEMU_TARGETS:@t@+wxneeded:qemu-${t:S/-bsd-user//}@}
--
You are receiving this mail because:
You are the assignee for the bug.