Browse Source

documentation and test cleanups

- improve clarity of user-mode docs
   - remove reference to TAP tarball
   - add new hypervisor test for aarch64 EL2
   - reduce combinatorial explosion of plugin tests
   - make docker-all-test-cross more friendly to non-x86 hosts
   - expose unittests to sysv.args for embedded help
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmiFUdoACgkQ+9DbCVqe
 KkQn+Af/RpTh4XmIcqiLvXrygLWo8hSELS0gjIRZgAA8QyBmojZ+e13los3pzm2Z
 WWlQhh4T0OHgMtZCPPrP+XUc/QDgV3Pt41C1O6SWRwqD4v/7oWNNZz+pFra7x160
 CLBJfcVuRKdFzuR1NZldR8LJufmAMnPnBwE+cV9SpBlGe/lvcLPPvjF0eXQnW1yP
 fWmNgf7VnLBPEQ3NQkliZ23Ku6p4yWDfJLfqgUAXe57Eom1PpDEaPlc+5UaYtAKs
 ee6Gk5CqVFUhIj0v50qBn1giLyaqaXyGn9yWiwiNDL/qVV1v+DK7LNt5B0bTXCfd
 X1KTwpJJdbzmcDftrAq+oacaeXryIA==
 =Sxa/
 -----END PGP SIGNATURE-----

Merge tag 'pull-10.1-rc1-maintainer-260725-1' of https://gitlab.com/stsquad/qemu into staging

documentation and test cleanups

  - improve clarity of user-mode docs
  - remove reference to TAP tarball
  - add new hypervisor test for aarch64 EL2
  - reduce combinatorial explosion of plugin tests
  - make docker-all-test-cross more friendly to non-x86 hosts
  - expose unittests to sysv.args for embedded help

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmiFUdoACgkQ+9DbCVqe
# KkQn+Af/RpTh4XmIcqiLvXrygLWo8hSELS0gjIRZgAA8QyBmojZ+e13los3pzm2Z
# WWlQhh4T0OHgMtZCPPrP+XUc/QDgV3Pt41C1O6SWRwqD4v/7oWNNZz+pFra7x160
# CLBJfcVuRKdFzuR1NZldR8LJufmAMnPnBwE+cV9SpBlGe/lvcLPPvjF0eXQnW1yP
# fWmNgf7VnLBPEQ3NQkliZ23Ku6p4yWDfJLfqgUAXe57Eom1PpDEaPlc+5UaYtAKs
# ee6Gk5CqVFUhIj0v50qBn1giLyaqaXyGn9yWiwiNDL/qVV1v+DK7LNt5B0bTXCfd
# X1KTwpJJdbzmcDftrAq+oacaeXryIA==
# =Sxa/
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 26 Jul 2025 18:08:26 EDT
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-10.1-rc1-maintainer-260725-1' of https://gitlab.com/stsquad/qemu:
  tests/functional: expose sys.argv to unittest.main
  tests/docker: handle host-arch selection for all-test-cross
  tests/docker: add --arch-only to qemu deps for all-test-cross
  tests/tcg: reduce the number of plugin tests combinations
  configure: expose PYTHON to test/tcg/config-host.mak
  tests/tcg: don't include multiarch tests if not supported
  tests/tcg: remove ADDITIONAL_PLUGINS_TESTS
  tests/tcg: skip libsyscall.so on softmmu tests
  tests/functional: add hypervisor test for aarch64
  docs/user: expand section on threading
  docs/user: slightly reword section on system calls
  docs/user: clean up headings
  docs/system: reword the TAP notes to remove tarball ref
  docs/user: clarify user-mode expects the same OS

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
pull/304/head
Stefan Hajnoczi 8 months ago
parent
commit
20b28f58b4
  1. 1
      configure
  2. 16
      docs/system/devices/net.rst
  3. 5
      docs/user/index.rst
  4. 60
      docs/user/main.rst
  5. 34
      tests/docker/dockerfiles/debian-all-test-cross.docker
  6. 1
      tests/functional/meson.build
  7. 2
      tests/functional/qemu_test/testcase.py
  8. 71
      tests/functional/test_aarch64_kvm.py
  9. 36
      tests/tcg/Makefile.target
  10. 8
      tests/tcg/multiarch/Makefile.target
  11. 16
      tests/tcg/multiarch/system/Makefile.softmmu-target

1
configure

@ -1800,6 +1800,7 @@ echo "SRC_PATH=$source_path" >> tests/tcg/$config_host_mak
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> tests/tcg/$config_host_mak
fi
echo "PYTHON=$python" >> tests/tcg/$config_host_mak
tcg_tests_targets=
for target in $target_list; do

16
docs/system/devices/net.rst

@ -21,11 +21,17 @@ configure it as if it was a real ethernet card.
Linux host
^^^^^^^^^^
As an example, you can download the ``linux-test-xxx.tar.gz`` archive
and copy the script ``qemu-ifup`` in ``/etc`` and configure properly
``sudo`` so that the command ``ifconfig`` contained in ``qemu-ifup`` can
be executed as root. You must verify that your host kernel supports the
TAP network interfaces: the device ``/dev/net/tun`` must be present.
A distribution will generally provide specific helper scripts when it
packages QEMU. By default these are found at ``/etc/qemu-ifup`` and
``/etc/qemu-ifdown`` and are called appropriately when QEMU wants to
change the network state.
If QEMU is being run as a non-privileged user you may need properly
configure ``sudo`` so that network commands in the scripts can be
executed as root.
You must verify that your host kernel supports the TAP network
interfaces: the device ``/dev/net/tun`` must be present.
See :ref:`sec_005finvocation` to have examples of command
lines using the TAP network interfaces.

5
docs/user/index.rst

@ -5,8 +5,9 @@ User Mode Emulation
-------------------
This section of the manual is the overall guide for users using QEMU
for user-mode emulation. In this mode, QEMU can launch
processes compiled for one CPU on another CPU.
for user-mode emulation. In this mode, QEMU can launch programs
compiled for one CPU architecture on the same Operating System (OS)
but running on a different CPU architecture.
.. toctree::
:maxdepth: 2

60
docs/user/main.rst

@ -17,28 +17,44 @@ Features
QEMU user space emulation has the following notable features:
**System call translation:**
QEMU includes a generic system call translator. This means that the
parameters of the system calls can be converted to fix endianness and
32/64-bit mismatches between hosts and targets. IOCTLs can be
converted too.
**POSIX signal handling:**
QEMU can redirect to the running program all signals coming from the
host (such as ``SIGALRM``), as well as synthesize signals from
virtual CPU exceptions (for example ``SIGFPE`` when the program
executes a division by zero).
QEMU relies on the host kernel to emulate most signal system calls,
for example to emulate the signal mask. On Linux, QEMU supports both
normal and real-time signals.
**Threading:**
On Linux, QEMU can emulate the ``clone`` syscall and create a real
host thread (with a separate virtual CPU) for each emulated thread.
Note that not all targets currently emulate atomic operations
correctly. x86 and Arm use a global lock in order to preserve their
semantics.
System call translation
~~~~~~~~~~~~~~~~~~~~~~~
System calls are the principle interface between user-space and the
kernel. Generally the same system calls exist on all versions of the
kernel so QEMU includes a generic system call translator. The
translator takes care of adjusting endianess, 32/64 bit parameter size
and then calling the equivalent host system call.
QEMU can also adjust device specific ``ioctl()`` calls in a similar
fashion.
POSIX signal handling
~~~~~~~~~~~~~~~~~~~~~
QEMU can redirect to the running program all signals coming from the
host (such as ``SIGALRM``), as well as synthesize signals from
virtual CPU exceptions (for example ``SIGFPE`` when the program
executes a division by zero).
QEMU relies on the host kernel to emulate most signal system calls,
for example to emulate the signal mask. On Linux, QEMU supports both
normal and real-time signals.
Threading
~~~~~~~~~
On Linux, QEMU can emulate the ``clone`` syscall and create a real
host thread (with a separate virtual CPU) for each emulated thread.
However as QEMU relies on the system libc to call ``clone`` on its
behalf we limit the flags accepted to those it uses. Specifically this
means flags affecting namespaces (e.g. container runtimes) are not
supported. QEMU user-mode processes can still be run inside containers
though.
While QEMU does its best to emulate atomic operations properly
differences between the host and guest memory models can cause issues
for software that makes assumptions about the memory model.
QEMU was conceived so that ultimately it can emulate itself. Although it
is not very useful, it is an important test to show the power of the

34
tests/docker/dockerfiles/debian-all-test-cross.docker

@ -15,7 +15,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y eatmydata && \
eatmydata apt-get dist-upgrade -y && \
apt build-dep -yy qemu
apt build-dep -yy --arch-only qemu
# Add extra build tools and as many cross compilers as we can for testing
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
@ -23,7 +23,9 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
bison \
ccache \
clang \
dpkg-dev \
flex \
gcc \
git \
libclang-rt-dev \
ninja-build \
@ -33,16 +35,11 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
python3-venv \
python3-wheel
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt install -y --no-install-recommends \
gcc-aarch64-linux-gnu \
# All the generally available compilers
ENV AVAILABLE_COMPILERS gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
gcc-arm-linux-gnueabihf \
libc6-dev-armhf-cross \
gcc-hppa-linux-gnu \
libc6-dev-hppa-cross \
gcc-m68k-linux-gnu \
libc6-dev-m68k-cross \
gcc-mips-linux-gnu \
libc6-dev-mips-cross \
gcc-mips64-linux-gnuabi64 \
@ -51,18 +48,25 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
libc6-dev-mips64el-cross \
gcc-mipsel-linux-gnu \
libc6-dev-mipsel-cross \
gcc-powerpc-linux-gnu \
libc6-dev-powerpc-cross \
gcc-powerpc64-linux-gnu \
libc6-dev-ppc64-cross \
gcc-powerpc64le-linux-gnu \
libc6-dev-ppc64el-cross \
gcc-riscv64-linux-gnu \
libc6-dev-riscv64-cross \
gcc-s390x-linux-gnu \
libc6-dev-s390x-cross \
gcc-sparc64-linux-gnu \
libc6-dev-sparc64-cross && \
libc6-dev-s390x-cross
RUN if dpkg-architecture -e amd64; then \
export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-hppa-linux-gnu libc6-dev-hppa-cross"; \
export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-m68k-linux-gnu libc6-dev-m68k-cross"; \
export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc-linux-gnu libc6-dev-powerpc-cross"; \
export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross"; \
export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-sparc64-linux-gnu libc6-dev-sparc64-cross"; \
fi && \
echo "compilers: ${AVAILABLE_COMPILERS}"
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
apt install -y --no-install-recommends \
${AVAILABLE_COMPILERS} && \
dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt

1
tests/functional/meson.build

@ -89,6 +89,7 @@ tests_aarch64_system_thorough = [
'aarch64_device_passthrough',
'aarch64_hotplug_pci',
'aarch64_imx8mp_evk',
'aarch64_kvm',
'aarch64_raspi3',
'aarch64_raspi4',
'aarch64_replay',

2
tests/functional/qemu_test/testcase.py

@ -249,7 +249,7 @@ class QemuBaseTest(unittest.TestCase):
tr = pycotap.TAPTestRunner(message_log = pycotap.LogMode.LogToError,
test_output_log = pycotap.LogMode.LogToError)
res = unittest.main(module = None, testRunner = tr, exit = False,
argv=["__dummy__", path])
argv=[sys.argv[0], path] + sys.argv[1:])
for (test, message) in res.result.errors + res.result.failures:
if hasattr(test, "log_filename"):

71
tests/functional/test_aarch64_kvm.py

@ -0,0 +1,71 @@
#!/usr/bin/env python3
#
# Functional test that runs subsets of kvm-unit-tests on Aarch64.
# These can run on TCG and any accelerator supporting nested
# virtualisation.
#
# Copyright (c) 2025 Linaro
#
# Author:
# Alex Bennée <alex.bennee@linaro.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import Asset
from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait
from qemu_test.linuxkernel import LinuxKernelTest
class Aarch64VirtKVMTests(LinuxKernelTest):
ASSET_KVM_TEST_KERNEL = Asset(
'https://fileserver.linaro.org/s/HmjaxXXYHYSqbes/'
'download?path=%2F&files='
'image-with-kvm-tool-and-unit-tests.gz',
'34de4aaea90db5da42729e7d28b77f392c37a2f4da859f889a5234aaf0970696')
# make it easier to detect successful return to shell
PS1 = 'RES=[$?] # '
OK_CMD = 'RES=[0] # '
# base of tests
KUT_BASE = "/usr/share/kvm-unit-tests/"
def _launch_guest(self, kvm_mode="nvhe"):
self.set_machine('virt')
kernel_path = self.ASSET_KVM_TEST_KERNEL.fetch()
self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
f"console=ttyAMA0 kvm-arm.mode={kvm_mode}")
self.vm.add_args("-cpu", "cortex-a72")
self.vm.add_args("-machine", "virt,gic-version=3,virtualization=on",
'-kernel', kernel_path,
'-append', kernel_command_line)
self.vm.add_args("-smp", "2", "-m", "320")
self.vm.launch()
self.wait_for_console_pattern('buildroot login:')
ec_and_wait(self, 'root', '#')
ec_and_wait(self, f"export PS1='{self.PS1}'", self.OK_CMD)
# this is just a smoketest, we don't run all the tests in the image
def _smoketest_kvm(self):
ec_and_wait(self, f"{self.KUT_BASE}/selftest-setup", self.OK_CMD)
ec_and_wait(self, f"{self.KUT_BASE}/selftest-smp", self.OK_CMD)
ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-kernel", self.OK_CMD)
ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-user", self.OK_CMD)
def test_aarch64_nvhe_selftest(self):
self._launch_guest("nvhe")
self._smoketest_kvm()
def test_aarch64_vhe_selftest(self):
self._launch_guest("vhe")
self._smoketest_kvm()
if __name__ == '__main__':
LinuxKernelTest.main()

36
tests/tcg/Makefile.target

@ -127,8 +127,14 @@ else
# build options for bare programs are usually pretty different. They
# are expected to provide their own build recipes.
EXTRA_CFLAGS += -ffreestanding -fno-stack-protector
# We skip the multiarch tests if the target hasn't provided a boot.S
MULTIARCH_SOFTMMU_TARGETS = i386 alpha aarch64 arm loongarch64 s390x x86_64
ifneq ($(filter $(TARGET_NAME),$(MULTIARCH_SOFTMMU_TARGETS)),)
-include $(SRC_PATH)/tests/tcg/minilib/Makefile.target
-include $(SRC_PATH)/tests/tcg/multiarch/system/Makefile.softmmu-target
endif
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.softmmu-target
endif
@ -155,21 +161,37 @@ VPATH+=$(PLUGIN_LIB)
# For example, libpatch.so only needs to run against the arch-specific patch
# target test, so we explicitly run it in the arch-specific Makefile.
DISABLE_PLUGINS=libpatch.so
# Likewise don't bother with the syscall plugin for softmmu
ifneq ($(filter %-softmmu, $(TARGET)),)
DISABLE_PLUGINS += libsyscall.so
endif
PLUGINS=$(filter-out $(DISABLE_PLUGINS), \
$(patsubst %.c, lib%.so, $(notdir $(wildcard $(PLUGIN_SRC)/*.c))))
# We need to ensure expand the run-plugin-TEST-with-PLUGIN
# pre-requistes manually here as we can't use stems to handle it. We
# only expand MULTIARCH_TESTS which are common on most of our targets
# to avoid an exponential explosion as new tests are added. We also
# add some special helpers the run-plugin- rules can use below.
# In more, extra tests can be added using ADDITIONAL_PLUGINS_TESTS variable.
# and rotate the plugins so we don't grow too out of control as new
# tests are added. Plugins that need to run with a specific test
# should ensure they add their combination to EXTRA_RUNS.
ifneq ($(MULTIARCH_TESTS),)
$(foreach p,$(PLUGINS), \
$(foreach t,$(MULTIARCH_TESTS) $(ADDITIONAL_PLUGINS_TESTS),\
$(eval run-plugin-$(t)-with-$(p): $t $p) \
$(eval RUN_TESTS+=run-plugin-$(t)-with-$(p))))
NUM_PLUGINS := $(words $(PLUGINS))
NUM_TESTS := $(words $(MULTIARCH_TESTS))
define mod_plus_one
$(shell $(PYTHON) -c "print( ($(1) % $(2)) + 1 )")
endef
$(foreach _idx, $(shell seq 1 $(NUM_TESTS)), \
$(eval _test := $(word $(_idx), $(MULTIARCH_TESTS))) \
$(eval _plugin := $(word $(call mod_plus_one, $(_idx), $(NUM_PLUGINS)), $(PLUGINS))) \
$(eval run-plugin-$(_test)-with-$(_plugin): $(_test) $(_plugin)) \
$(eval RUN_TESTS+=run-plugin-$(_test)-with-$(_plugin)))
endif # MULTIARCH_TESTS
endif # CONFIG_PLUGIN

8
tests/tcg/multiarch/Makefile.target

@ -189,6 +189,10 @@ run-plugin-semiconsole-with-%:
TESTS += semihosting semiconsole
endif
test-plugin-mem-access: CFLAGS+=-pthread -O0
test-plugin-mem-access: LDFLAGS+=-pthread -O0
ifeq ($(CONFIG_PLUGIN),y)
# Test plugin memory access instrumentation
run-plugin-test-plugin-mem-access-with-libmem.so: \
PLUGIN_ARGS=$(COMMA)print-accesses=true
@ -197,8 +201,8 @@ run-plugin-test-plugin-mem-access-with-libmem.so: \
$(SRC_PATH)/tests/tcg/multiarch/check-plugin-output.sh \
$(QEMU) $<
test-plugin-mem-access: CFLAGS+=-pthread -O0
test-plugin-mem-access: LDFLAGS+=-pthread -O0
EXTRA_RUNS += run-plugin-test-plugin-mem-access-with-libmem.so
endif
# Update TESTS
TESTS += $(MULTIARCH_TESTS)

16
tests/tcg/multiarch/system/Makefile.softmmu-target

@ -6,6 +6,11 @@
# architecture to add to the test dependencies and deal with the
# complications of building.
#
# To support the multiarch guests the target arch needs to provide a
# boot.S that jumps to main and provides a __sys_outc functions.
# Remember to update MULTIARCH_SOFTMMU_TARGETS in the tcg test
# Makefile.target when this is done.
#
MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
MULTIARCH_SYSTEM_SRC=$(MULTIARCH_SRC)/system
@ -66,8 +71,11 @@ endif
MULTIARCH_RUNS += run-gdbstub-memory run-gdbstub-interrupt \
run-gdbstub-untimely-packet run-gdbstub-registers
ifeq ($(CONFIG_PLUGIN),y)
# Test plugin memory access instrumentation
run-plugin-memory-with-libmem.so: \
PLUGIN_ARGS=$(COMMA)region-summary=true
run-plugin-memory-with-libmem.so: \
CHECK_PLUGIN_OUTPUT_COMMAND=$(MULTIARCH_SYSTEM_SRC)/validate-memory-counts.py $@.out
run-plugin-memory-with-libmem.so: memory libmem.so
run-plugin-memory-with-libmem.so: PLUGIN_ARGS=$(COMMA)region-summary=true
run-plugin-memory-with-libmem.so: CHECK_PLUGIN_OUTPUT_COMMAND=$(MULTIARCH_SYSTEM_SRC)/validate-memory-counts.py $@.out
EXTRA_RUNS += run-plugin-memory-with-libmem.so
endif

Loading…
Cancel
Save