Bug#1123033: trixie-pu: package qemu/1:10.0.7+ds-0+deb13u1
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: qemu@packages.debian.org, pkg-qemu-devel@lists.alioth.debian.org
Control: affects -1 + src:qemu
User: release.debian.org@packages.debian.org
Usertags: pu
[ Reason ]
There's a new upstream stable/bugfix release of qemu,
v10.0.7, wich includes a large assortment of fixes.
Among these, there are fixes for two securty issues:
#1119917, CVE-2025-12464 (buffer overflow in e1000_receive_iov)
#1117153, CVE-2025-11234 (UAF in websocket handshake code)
Additionally, there are fixes for xen packaging (missing
dependency, which has alredy been fixed for bookworm but
were forgotten in trixie), -- #1035676, #1120146.
[ Tests ]
This release passes complete upstream testsuite, and also
my usual assortment of guests (a few debian and windows
versions, and some more) works fine in it. This version
is already used in production in our environment.
[ Risks ]
The amount of changes (see below for explanation of the testing/CI
bits) is large this time (it is the first qemu stable release with
3-digit number of patches in it). However, actual code changes aren't
that many and each of them is focused too. So I don't expect any
breakage from this release. However, it'd be nice to have it in
s-p-u for a while, just in case.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
Since most changes (besides the xen fix) are in the upstream
release, it might be easier to review as git commits:
https://salsa.debian.org/qemu-team/qemu/-/commits/v10.0.7
(up to previous upstream release, v10.0.6), which is already
part of debian.
[ Other info ]
The difference of this upstream stable release, compared to
the previous release, is huge. However, the wast majority of
changes are in testing/CI area (and in the docs covering it), -
this is to keep 10.0.x LTS release testable in long run.
Here are the diffstats of testing bits, and the rest.
Just the testing parts:
$ git diff --stat v10.0.6..v10.0.7 -- tests .gitlab-ci.d docs/devel
.gitlab-ci.d/base.yml | 8 +-
.gitlab-ci.d/buildtest-template.yml | 13 +-
.gitlab-ci.d/buildtest.yml | 33 +-
docs/devel/build-system.rst | 11 +-
docs/devel/codebase.rst | 5 -
docs/devel/submitting-a-pull-request.rst | 2 +-
docs/devel/testing/avocado.rst | 581 ---------------------
docs/devel/testing/ci-definitions.rst.inc | 121 -----
docs/devel/testing/ci-jobs.rst.inc | 19 +-
docs/devel/testing/ci.rst | 28 +-
docs/devel/testing/functional.rst | 3 -
docs/devel/testing/index.rst | 1 -
docs/devel/testing/main.rst | 80 ++-
tests/Makefile.include | 60 +--
tests/avocado/README.rst | 10 -
tests/avocado/avocado_qemu/__init__.py | 424 ---------------
tests/avocado/avocado_qemu/linuxtest.py | 253 ---------
tests/avocado/boot_linux.py | 132 -----
tests/avocado/boot_linux_console.py | 96 ----
tests/avocado/linux_ssh_mips_malta.py | 205 --------
tests/avocado/replay_kernel.py | 110 ----
tests/avocado/replay_linux.py | 206 --------
tests/avocado/smmu.py | 139 -----
tests/data/acpi/aarch64/virt/DSDT | Bin 5196 -> 5196 bytes
tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt | Bin 5282 -> 5282 bytes
tests/data/acpi/aarch64/virt/DSDT.memhp | Bin 6557 -> 6557 bytes
tests/data/acpi/aarch64/virt/DSDT.pxb | Bin 7679 -> 7679 bytes
tests/data/acpi/aarch64/virt/DSDT.topology | Bin 5398 -> 5398 bytes
tests/data/acpi/riscv64/virt/DSDT | Bin 3576 -> 3576 bytes
tests/data/acpi/x86/microvm/DSDT.pcie | Bin 3023 -> 3023 bytes
tests/functional/aspeed.py | 2 +-
tests/functional/meson.build | 13 +-
tests/functional/qemu_test/asset.py | 12 +-
tests/functional/qemu_test/ports.py | 3 +-
tests/functional/qemu_test/tuxruntest.py | 11 +-
tests/functional/qemu_test/uncompress.py | 2 +-
tests/{avocado => functional}/reverse_debugging.py | 114 +---
tests/functional/test_aarch64_aspeed.py | 2 +-
tests/functional/test_aarch64_replay.py | 37 +-
tests/functional/test_aarch64_reverse_debug.py | 38 ++
tests/functional/test_aarch64_rme_sbsaref.py | 6 +-
tests/functional/test_aarch64_rme_virt.py | 2 -
tests/functional/test_aarch64_sbsaref_alpine.py | 3 -
tests/functional/test_aarch64_sbsaref_freebsd.py | 2 -
tests/functional/test_aarch64_smmu.py | 205 ++++++++
tests/functional/test_aarch64_tcg_plugins.py | 1 -
tests/functional/test_aarch64_virt.py | 13 +-
tests/functional/test_aarch64_virt_gpu.py | 8 +-
tests/functional/test_aarch64_xen.py | 12 +-
tests/functional/test_arm_aspeed_ast2500.py | 9 +-
tests/functional/test_arm_aspeed_ast2600.py | 36 +-
tests/functional/test_arm_aspeed_bletchley.py | 4 +-
tests/functional/test_arm_aspeed_palmetto.py | 4 +-
tests/functional/test_arm_aspeed_romulus.py | 4 +-
tests/functional/test_arm_aspeed_witherspoon.py | 4 +-
tests/functional/test_arm_bpim2u.py | 2 +-
tests/functional/test_arm_cubieboard.py | 4 +-
tests/functional/test_arm_orangepi.py | 2 +-
tests/functional/test_arm_quanta_gsj.py | 2 -
tests/functional/test_arm_smdkc210.py | 2 -
tests/functional/test_i386_replay.py | 28 +
tests/functional/test_migration.py | 3 +-
tests/functional/test_mips64_malta.py | 35 ++
tests/functional/test_mips64el_malta.py | 22 +
tests/functional/test_mips64el_replay.py | 6 +-
tests/functional/test_mips_malta.py | 108 +++-
tests/functional/test_mips_replay.py | 2 +-
tests/functional/test_mipsel_malta.py | 22 +
tests/functional/test_mipsel_replay.py | 2 +-
tests/functional/test_netdev_ethtool.py | 14 +-
tests/functional/test_ppc64_hv.py | 8 +-
tests/functional/test_ppc64_reverse_debug.py | 41 ++
tests/functional/test_s390x_topology.py | 12 +-
tests/functional/test_vnc.py | 6 +-
tests/functional/test_x86_64_kvm_xen.py | 19 +-
tests/functional/test_x86_64_replay.py | 43 +-
tests/functional/test_x86_64_reverse_debug.py | 36 ++
tests/qemu-iotests/024 | 46 ++
tests/qemu-iotests/024.out | 25 +
tests/qemu-iotests/tests/commit-zero-blocks | 96 ++++
tests/qemu-iotests/tests/commit-zero-blocks.out | 54 ++
tests/qtest/am53c974-test.c | 40 ++
tests/tcg/multiarch/linux/linux-test.c | 9 +-
tests/tcg/s390x/Makefile.softmmu-target | 1 +
tests/tcg/s390x/sckc.S | 63 +++
tests/unit/crypto-tls-x509-helpers.h | 6 +-
tests/unit/test-crypto-tlscredsx509.c | 36 +-
tests/unit/test-crypto-tlssession.c | 14 +-
tests/unit/test-io-channel-tls.c | 4 +-
89 files changed, 1191 insertions(+), 2709 deletions(-)
And the non-testing bits:
$ git diff --stat v10.0.6..v10.0.7 -- :!tests :!.gitlab-ci.d :!docs/devel
MAINTAINERS | 28 ++++-----
VERSION | 2 +-
accel/kvm/kvm-all.c | 4 +-
backends/hostmem-shm.c | 1 +
block/block-backend.c | 8 ++-
block/commit.c | 118 +++++++++++++++++++++++++-----------
block/crypto.c | 32 +++++++---
block/curl.c | 47 +++++++++-----
block/io.c | 3 +
block/io_uring.c | 16 ++++-
block/nfs.c | 41 +++++--------
block/nvme.c | 70 ++++++++++++---------
block/rbd.c | 12 ++--
chardev/char-pty.c | 2 +-
configure | 2 +-
crypto/tlscredsx509.c | 10 +--
docs/about/build-platforms.rst | 10 +--
docs/system/tls.rst | 13 ++--
gdbstub/syscalls.c | 2 +-
hw/arm/armv7m.c | 12 ++++
hw/arm/aspeed_ast10x0.c | 2 +
hw/arm/aspeed_ast2600.c | 2 +
hw/arm/aspeed_ast27x0.c | 2 +
hw/core/machine.c | 2 +
hw/display/exynos4210_fimd.c | 7 +++
hw/display/xlnx_dp.c | 83 ++++++++++++++++++++++---
hw/dma/xlnx-zynq-devcfg.c | 2 +-
hw/hppa/machine.c | 2 +-
hw/i386/pc.c | 17 +++---
hw/i386/x86-common.c | 11 ++++
hw/intc/riscv_aplic.c | 29 +++++----
hw/misc/aspeed_xdma.c | 2 +-
hw/misc/npcm_clk.c | 5 +-
hw/net/e1000e_core.c | 85 ++++++++++++++++++--------
hw/nvram/ds1225y.c | 2 +-
hw/pci-host/gpex-acpi.c | 2 +-
hw/pci/msix.c | 10 ++-
hw/ppc/e500.c | 6 +-
hw/riscv/sifive_u.c | 2 +-
hw/rtc/aspeed_rtc.c | 2 +-
hw/scsi/esp.c | 6 +-
hw/scsi/virtio-scsi.c | 14 ++++-
hw/sd/aspeed_sdhci.c | 2 +-
hw/virtio/vhost-user.c | 40 ++++--------
hw/virtio/virtio-qmp.c | 2 +-
include/hw/misc/lasi.h | 4 +-
include/hw/pci/msix.h | 4 +-
include/io/channel-websock.h | 3 +-
include/io/net-listener.h | 2 +
io/channel-tls.c | 10 +++
io/channel-websock.c | 33 +++++++---
io/net-listener.c | 73 +++++++++++++++++-----
io/trace-events | 5 ++
linux-user/ioctls.h | 4 +-
linux-user/syscall.c | 25 ++++----
migration/migration.c | 4 +-
net/net.c | 10 +++
pythondeps.toml | 8 +--
qemu-img.c | 4 +-
target/arm/helper.c | 2 +-
target/arm/tcg/translate-a64.c | 2 +-
target/hppa/fpu_helper.c | 7 ++-
target/i386/hvf/x86hvf.c | 1 +
target/i386/kvm/kvm.c | 7 +++
target/i386/kvm/kvm_i386.h | 1 +
target/i386/nvmm/nvmm-all.c | 1 +
target/i386/tcg/decode-new.c.inc | 11 +++-
target/i386/tcg/helper-tcg.h | 2 +-
target/i386/tcg/seg_helper.c | 4 +-
target/i386/tcg/system/svm_helper.c | 6 +-
target/i386/whpx/whpx-all.c | 1 +
target/microblaze/cpu.h | 1 +
target/microblaze/op_helper.c | 49 +++++++++------
target/microblaze/translate.c | 12 +---
target/riscv/cpu_helper.c | 3 +-
target/riscv/kvm/kvm-cpu.c | 17 ++++--
target/s390x/tcg/mem_helper.c | 11 +++-
target/s390x/tcg/misc_helper.c | 12 ++--
target/s390x/tcg/translate.c | 11 ++--
ui/gtk-gl-area.c | 17 +++++-
ui/vnc.c | 9 ++-
81 files changed, 774 insertions(+), 374 deletions(-)
So, while the number of changes is still significant,
it is dramatically smaller than the testing bits.
One patch has been included in the previous debian release:
linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch.
Thanks,
/mjt
diff -Nru qemu-10.0.6+ds/debian/changelog qemu-10.0.7+ds/debian/changelog
--- qemu-10.0.6+ds/debian/changelog 2025-11-04 16:40:44.000000000 +0300
+++ qemu-10.0.7+ds/debian/changelog 2025-12-16 10:01:50.000000000 +0300
@@ -1,6 +1,149 @@
+qemu (1:10.0.7+ds-0+deb13u1) trixie; urgency=medium
+
+ * 10.0.7 upstream stable/bugfix release:
+ - Update version for 10.0.7 release
+ - kvm: Fix kvm_vm_ioctl() and kvm_device_ioctl() return value
+ - docs/devel: Update URL for make-pullreq script
+ - target/arm: Fix assert on BRA.
+ - hw/aspeed/{xdma, rtc, sdhci}: Fix endianness to DEVICE_LITTLE_ENDIAN
+ - hw/core/machine: Provide a description for aux-ram-share property
+ - hw/pci: Make msix_init take a uint32_t for nentries
+ - block/io_uring: avoid potentially getting stuck after resubmit
+ at the end of ioq_submit()
+ - block-backend: Fix race when resuming queued requests
+ - ui/vnc: Fix qemu abort when query vnc info
+ - chardev/char-pty: Do not ignore chr_write() failures
+ - hw/display/exynos4210_fimd: Account for zero length
+ in fimd_update_memory_section()
+ - hw/arm/armv7m: Disable reentrancy guard for v7m_sysreg_ns_ops MRs
+ - hw/arm/aspeed: Fix missing SPI IRQ connection causing
+ DMA interrupt failure
+ - migration: Fix transition to COLO state from precopy
+ - qmp: Fix a typo for a USO feature
+ - MAINTAINERS: Add functional tests that are not covered yet
+ - tests/functional: Remove unnecessary import statements
+ - tests/functional: Remove semicolons at the end of lines
+ - Remove the remainders of the Avocado tests
+ - docs/devel/testing: Dissolve the ci-definitions.rst.inc file
+ - gitlab-ci: Update QEMU_JOB_AVOCADO and QEMU_CI_AVOCADO_TESTING
+ - tests/functional: Convert the SMMU test to the functional framework
+ - tests/functional: Use the tuxrun kernel for the aarch64 replay test
+ - tests/functional: Use the tuxrun kernel for the x86 replay test
+ - tests/avocado: Remove the boot_linux.py tests
+ - tests/functional: Convert the 64-bit big endian Wheezy mips test
+ - tests/functional: Convert the 64-bit little endian Wheezy mips test
+ - tests/functional: Convert the 32-bit little endian Wheezy mips test
+ - tests/functional: Convert the 32-bit big endian Wheezy mips test
+ - tests/avocado: Remove the LinuxKernelTest class
+ - tests/functional: Convert the i386 replay avocado test
+ - tests/functional: Convert reverse_debugging tests to the
+ functional framework
+ - tests/functional: Move the check for the parameters from avocado
+ to functional
+ - gitlab-ci: Remove the avocado tests from the CI pipelines
+ - tests/functional/test_vnc: skip test if no crypto backend available
+ - target/i386: fix stack size when delivering real mode interrupts
+ - target/i386: svm: fix sign extension of exit code
+ - target/i386/tcg: validate segment registers
+ - target/i386: Mark VPERMILPS as not valid with prefix 0
+ - hw/southbridge/lasi: Correct LasiState parent
+ - hw/dma/zynq-devcfg: Fix register memory
+ - tests/functional: handle URLError when fetching assets
+ - tests/functional: fix formatting of exception args
+ - block/io: Take reqs_lock for tracked_requests
+ - nvme: Fix coroutine waking
+ - nvme: Kick and check completions in BDS context
+ - curl: Fix coroutine waking
+ - nfs: Run co BH CB in the coroutine’s AioContext
+ - rbd: Run co BH CB in the coroutine’s AioContext
+ - tests: move test_virt_gpu to share.linaro.org
+ - tests: move test_kvm_xen to share.linaro.org
+ - tests: move test_netdev_ethtool to share.linaro.org
+ - tests: move test_virt assets to share.linaro.org
+ - tests: move test_xen assets to share.linaro.org
+ - block: add test non-active commit with zeroed data
+ - block: allow commit to unmap zero blocks
+ - block: refactor error handling of commit_iteration
+ - block: move commit_run loop to separate function
+ - block: get type of block allocation in commit_run
+ - hw/misc/npcm_clk: Don't divide by zero when calculating frequency
+ - hw/display/xlnx_dp: Don't abort for unsupported graphics formats
+ - hw/display/xlnx_dp.c: Don't abort on AUX FIFO overrun/underrun
+ - net: pad packets to minimum length in qemu_receive_packet()
+ Closes: #1119917, CVE-2025-12464 (buffer overflow in e1000_receive_iov)
+ - hw/net/e1000e_core: Adjust
+ e1000e_write_payload_frag_to_rx_buffers() assert
+ - hw/net/e1000e_core: Correct rx oversize packet checks
+ - hw/net/e1000e_core: Don't advance desc_offset for NULL buffer
+ RX descriptors
+ - qio: Protect NetListener callback with mutex
+ - qio: Remember context of qio_net_listener_set_client_func_full
+ - qio: Unwatch before notify in QIONetListener
+ - qio: Add trace points to net_listener
+ - tests/qemu-iotest: fix iotest 024 with qed images
+ - qemu-img rebase: don't exceed IO_BUF_SIZE in one operation
+ - qemu-img: Fix amend option parse error handling
+ - tests/qtest/bios-tables-test: Update DSDT blobs after GPEX _DSM change
+ - hw/pci-host/gpex-acpi: Fix _DSM function 0 support return value
+ - tests/qtest/bios-tables-test: Prepare for _DSM change in the DSDT table
+ - vhost-user: fix shared object lookup handler logic
+ - target/x86: Correctly handle invalid 0x0f 0xc7 0xxx insns
+ - hostmem/shm: Allow shm memory backend serve as shared memory for coco-VMs
+ - tests/tcg/s390x: Test SET CLOCK COMPARATOR
+ - target/s390x: Use address generation for register branch targets
+ - target/s390x: Fix missing clock-comparator interrupts after reset
+ - target/s390x: Fix missing interrupts for small CKC values
+ - target/microblaze: Handle signed division overflows
+ - target/microblaze: div: Break out raise_divzero()
+ - target/microblaze: Remove unused arg from check_divz()
+ - gdbstub: Fix %s formatting
+ - block/curl.c: Fix CURLOPT_VERBOSE parameter type
+ - block: fix luks 'amend' when run in coroutine
+ - block: remove 'detached-header' option from opts after use
+ - i386/kvm/cpu: Init SMM cpu address space for hotplugged CPUs
+ - hw/i386/pc: Avoid overlap between CXL window and PCI 64bit BARs
+ in QEMU 10.0.x
+ - target/i386: clear CPU_INTERRUPT_SIPI for all accelerators
+ - linux-user: permit sendto() with NULL buf and 0 len
+ - linux-user: Use correct type for FIBMAP and FIGETBSZ emulation
+ - qtest/am53c974-test: add additional test for cmdfifo overflow
+ - esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
+ - hw/hppa: Fix interrupt of LASI parallel port
+ - nw/nvram/ds1225y: Fix nvram MemoryRegion owner
+ - target/hppa: Set FPCR exception flag bits for non-trapped exceptions
+ - hw/scsi: avoid deadlock upon TMF request cancelling with VirtIO
+ - crypto: stop requiring "key encipherment" usage in x509 certs
+ - io: fix use after free in websocket handshake code
+ Closes: #1117153, CVE-2025-11234 (UAF in websocket handshake code)
+ - io: move websock resource release to close method
+ - io: release active GSource in TLS channel finalizer
+ - target/riscv: fix riscv_cpu_sirq_pending() mask
+ - target/riscv/kvm: fix env->priv setting in reset_regs_csr()
+ - target/riscv/kvm: add scounteren CSR
+ - target/riscv/kvm: read/write KVM regs via env size
+ - target/riscv/kvm: add senvcfg CSR
+ - aplic: fix mask for smsiaddrcfgh
+ - hw/riscv: Correct mmu-type property of sifive_u harts in device tree
+ - target/arm: Fix reads of CNTFRQ_EL0 in linux-user mode
+ - hw/ppc/e500: Check for compatible CPU type instead of
+ aborting ungracefully
+ - ui/gtk-gl-area: Remove extra draw call in refresh
+ - tests/tcg/multiarch/linux/linux-test: Don't try to test atime update
+ * linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch:
+ remove, applied upstream
+ * d/control: qemu-system-xen: add the forgotten ipxe-qemu dependency
+ qemu-system binaries require pxe boot roms for the network adaptors.
+ When splitting qemu-system-xen into its own package, this dependency
+ has been forgotten initally, but has been enabled for bookworm (#1035676).
+ However, this change were lost when uploading the next version of qemu
+ aimed for trixie. So trixie has this issue too, despite it's been fixed
+ in bookworm already. (Closes: #1035676, #1120146)
+
+ -- Michael Tokarev <mjt@tls.msk.ru> Tue, 16 Dec 2025 10:01:50 +0300
+
qemu (1:10.0.6+ds-0+deb13u2) trixie; urgency=medium
- * d/changelog: remove wrong closes: #1095935 from the previous changelog
+ * d/changelog: remove wrong closes #1095935 from the previous changelog
entry (and reopen the bug): I confused it with another bug
* linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch - add a patch
from upstream stable series (before next stable release) - fix wrong
diff -Nru qemu-10.0.6+ds/debian/control qemu-10.0.7+ds/debian/control
--- qemu-10.0.6+ds/debian/control 2025-11-04 16:40:44.000000000 +0300
+++ qemu-10.0.7+ds/debian/control 2025-12-16 10:01:50.000000000 +0300
@@ -575,7 +575,7 @@
Build-Profiles: <!pkg.qemu.omit-system-xen>
# do we really need qemu-system-data? keymaps only?
Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-data (>> ${source:Upstream-Version}~),
- seabios
+ seabios, ipxe-qemu
Recommends: qemu-utils,
ovmf,
Description: QEMU full system emulation (Xen helper package)
diff -Nru qemu-10.0.6+ds/debian/control-in qemu-10.0.7+ds/debian/control-in
--- qemu-10.0.6+ds/debian/control-in 2025-11-04 15:45:12.000000000 +0300
+++ qemu-10.0.7+ds/debian/control-in 2025-12-16 09:52:25.000000000 +0300
@@ -625,7 +625,7 @@
Build-Profiles: <!pkg.qemu.omit-system-xen>
# do we really need qemu-system-data? keymaps only?
Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-data (>> ${source:Upstream-Version}~),
- seabios
+ seabios, ipxe-qemu
Recommends: qemu-utils,
ovmf,
:ubuntu:# For the transition from the former qemu-system-x86-xen name
diff -Nru qemu-10.0.6+ds/debian/control.mk qemu-10.0.7+ds/debian/control.mk
--- qemu-10.0.6+ds/debian/control.mk 2025-11-04 15:45:12.000000000 +0300
+++ qemu-10.0.7+ds/debian/control.mk 2025-12-16 10:01:50.000000000 +0300
@@ -9,7 +9,7 @@
# since some files and/or lists differ from version to version,
# ensure we have the expected qemu version, or else scream loudly
-checked-version := 10.0.6+ds
+checked-version := 10.0.7+ds
# version of last vdso change for d/control Depends field:
vdso-version := 1:9.2.0~rc3+ds-1~
diff -Nru qemu-10.0.6+ds/debian/patches/linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch qemu-10.0.7+ds/debian/patches/linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch
--- qemu-10.0.6+ds/debian/patches/linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch 2025-11-04 15:42:33.000000000 +0300
+++ qemu-10.0.7+ds/debian/patches/linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch 1970-01-01 03:00:00.000000000 +0300
@@ -1,49 +0,0 @@
-From: Bastian Blank <bblank@thinkmo.de>
-Date: Tue, 28 Oct 2025 13:16:12 +0100
-Subject: linux-user: Use correct type for FIBMAP and FIGETBSZ emulation
-Origin: upstream, https://gitlab.com/qemu-project/qemu/-/commit/7c7089321670fb51022a1c4493cbcc69aa288a0f
-Forwarded: not-needed
-Bug-Debian: https://bugs.debian.org/1119257
-
-Both the FIBMAP and FIGETBSZ ioctl get "int *" (pointer to 32bit
-integer) as argument, not "long *" as specified in qemu. Using the
-correct type makes the emulation work in cross endian context.
-
-Both ioctl does not seem to be documented. However the kernel
-implementation has always used "int *".
-
-Signed-off-by: Bastian Blank <waldi@debian.org>
-Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3185
-Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
-Reviewed-by: Helge Deller <deller@gmx.de>
-Reviwed-by: Michael Tokarev <mjt@tls.msk.ru>
-Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
----
- linux-user/ioctls.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
-index 3b41128fd7..2f62fd2cb9 100644
---- a/linux-user/ioctls.h
-+++ b/linux-user/ioctls.h
-@@ -130,7 +130,7 @@
- IOCTL(FDTWADDLE, 0, TYPE_NULL)
- IOCTL(FDEJECT, 0, TYPE_NULL)
-
-- IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
-+ IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_INT))
- #ifdef FICLONE
- IOCTL(FICLONE, IOC_W, TYPE_INT)
- IOCTL(FICLONERANGE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_file_clone_range)))
-@@ -145,7 +145,7 @@
- IOCTL(FITRIM, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_fstrim_range)))
- #endif
-
-- IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
-+ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_INT))
- #ifdef CONFIG_FIEMAP
- IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap,
- MK_PTR(MK_STRUCT(STRUCT_fiemap)))
---
-2.47.3
-
diff -Nru qemu-10.0.6+ds/debian/patches/series qemu-10.0.7+ds/debian/patches/series
--- qemu-10.0.6+ds/debian/patches/series 2025-11-04 15:45:12.000000000 +0300
+++ qemu-10.0.7+ds/debian/patches/series 2025-12-16 09:59:50.000000000 +0300
@@ -15,4 +15,3 @@
slof-ensure-ld-is-called-with-C-locale.patch
qemu-img-options.patch
disable-pycotap.patch
-linux-user-use-correct-type-for-FIBMAP-and-FIGETBSZ.patch
diff -Nru qemu-10.0.6+ds/.gitlab-ci.d/base.yml qemu-10.0.7+ds/.gitlab-ci.d/base.yml
--- qemu-10.0.6+ds/.gitlab-ci.d/base.yml 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/.gitlab-ci.d/base.yml 2025-12-06 17:54:23.000000000 +0300
@@ -69,10 +69,6 @@
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: never
- # Avocado jobs don't run in forks unless $QEMU_CI_AVOCADO_TESTING is set
- - if: '$QEMU_JOB_AVOCADO && $QEMU_CI_AVOCADO_TESTING != "1" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
- when: never
-
#############################################################
# Stage 2: fine tune execution of jobs in specific scenarios
@@ -101,8 +97,8 @@
when: manual
allow_failure: true
- # Avocado jobs can be manually start in forks if $QEMU_CI_AVOCADO_TESTING is unset
- - if: '$QEMU_JOB_AVOCADO && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
+ # Functional jobs can be manually started in forks
+ - if: '$QEMU_JOB_FUNCTIONAL && $QEMU_CI_FUNCTIONAL != "1" && $CI_PROJECT_NAMESPACE != $QEMU_CI_UPSTREAM'
when: manual
allow_failure: true
diff -Nru qemu-10.0.6+ds/.gitlab-ci.d/buildtest-template.yml qemu-10.0.7+ds/.gitlab-ci.d/buildtest-template.yml
--- qemu-10.0.6+ds/.gitlab-ci.d/buildtest-template.yml 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/.gitlab-ci.d/buildtest-template.yml 2025-12-06 17:54:23.000000000 +0300
@@ -95,7 +95,6 @@
cache:
key: "${CI_JOB_NAME}-cache"
paths:
- - ${CI_PROJECT_DIR}/avocado-cache
- ${CI_PROJECT_DIR}/functional-cache
policy: pull-push
artifacts:
@@ -109,20 +108,10 @@
reports:
junit: build/tests/results/latest/results.xml
before_script:
- - mkdir -p ~/.config/avocado
- - echo "[datadir.paths]" > ~/.config/avocado/avocado.conf
- - echo "cache_dirs = ['${CI_PROJECT_DIR}/avocado-cache']"
- >> ~/.config/avocado/avocado.conf
- - echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]'
- >> ~/.config/avocado/avocado.conf
- - if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then
- du -chs ${CI_PROJECT_DIR}/*-cache ;
- fi
- - export AVOCADO_ALLOW_UNTRUSTED_CODE=1
- export QEMU_TEST_ALLOW_UNTRUSTED_CODE=1
- export QEMU_TEST_CACHE_DIR=${CI_PROJECT_DIR}/functional-cache
after_script:
- cd build
- du -chs ${CI_PROJECT_DIR}/*-cache
variables:
- QEMU_JOB_AVOCADO: 1
+ QEMU_JOB_FUNCTIONAL: 1
diff -Nru qemu-10.0.6+ds/.gitlab-ci.d/buildtest.yml qemu-10.0.7+ds/.gitlab-ci.d/buildtest.yml
--- qemu-10.0.6+ds/.gitlab-ci.d/buildtest.yml 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/.gitlab-ci.d/buildtest.yml 2025-12-06 17:54:23.000000000 +0300
@@ -29,8 +29,7 @@
artifacts: true
variables:
IMAGE: alpine
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
+ MAKE_CHECK_ARGS: check-functional
build-system-ubuntu:
extends:
@@ -60,8 +59,7 @@
artifacts: true
variables:
IMAGE: ubuntu2204
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el
+ MAKE_CHECK_ARGS: check-functional
build-system-debian:
extends:
@@ -92,8 +90,7 @@
artifacts: true
variables:
IMAGE: debian
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
+ MAKE_CHECK_ARGS: check-functional
crash-test-debian:
extends: .native_test_job_template
@@ -155,9 +152,7 @@
artifacts: true
variables:
IMAGE: fedora
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
- arch:riscv32 arch:ppc arch:sparc64
+ MAKE_CHECK_ARGS: check-functional
crash-test-fedora:
extends: .native_test_job_template
@@ -278,9 +273,7 @@
artifacts: true
variables:
IMAGE: centos9
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx
- arch:sh4
+ MAKE_CHECK_ARGS: check-functional
build-system-opensuse:
extends:
@@ -309,8 +302,7 @@
artifacts: true
variables:
IMAGE: opensuse-leap
- MAKE_CHECK_ARGS: check-avocado check-functional
- AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
+ MAKE_CHECK_ARGS: check-functional
#
# Flaky tests. We don't run these by default and they are allow fail
@@ -338,10 +330,9 @@
allow_failure: true
variables:
IMAGE: debian
- MAKE_CHECK_ARGS: check-avocado check-functional
+ MAKE_CHECK_ARGS: check-functional
QEMU_JOB_OPTIONAL: 1
QEMU_TEST_FLAKY_TESTS: 1
- AVOCADO_TAGS: flaky
# This jobs explicitly disable TCG (--disable-tcg), KVM is detected by
# the configure script. The container doesn't contain Xen headers so
@@ -482,8 +473,8 @@
# Since slirp callbacks are used in QEMU Timers, we cannot use libslirp with
# CFI builds, and thus have to disable it here.
#
-# Split in three sets of build/check/avocado to limit the execution time of each
-# job
+# Split in three sets of build/check/functional to limit the execution time
+# of each job
build-cfi-aarch64:
extends:
- .native_build_job_template
@@ -520,7 +511,7 @@
artifacts: true
variables:
IMAGE: fedora
- MAKE_CHECK_ARGS: check-avocado check-functional
+ MAKE_CHECK_ARGS: check-functional
build-cfi-ppc64-s390x:
extends:
@@ -558,7 +549,7 @@
artifacts: true
variables:
IMAGE: fedora
- MAKE_CHECK_ARGS: check-avocado check-functional
+ MAKE_CHECK_ARGS: check-functional
build-cfi-x86_64:
extends:
@@ -592,7 +583,7 @@
artifacts: true
variables:
IMAGE: fedora
- MAKE_CHECK_ARGS: check-avocado check-functional
+ MAKE_CHECK_ARGS: check-functional
tsan-build:
extends: .native_build_job_template
diff -Nru qemu-10.0.6+ds/MAINTAINERS qemu-10.0.7+ds/MAINTAINERS
--- qemu-10.0.6+ds/MAINTAINERS 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/MAINTAINERS 2025-12-06 17:54:23.000000000 +0300
@@ -211,7 +211,7 @@
S: Maintained
F: hw/arm/smmu*
F: include/hw/arm/smmu*
-F: tests/avocado/smmu.py
+F: tests/functional/test_aarch64_smmu.py
AVR TCG CPUs
M: Michael Rolnik <mrolnik@gmail.com>
@@ -475,6 +475,7 @@
F: target/i386/kvm/
F: target/i386/sev*
F: scripts/kvm/vmxcap
+F: tests/functional/test_x86_64_hotplug_cpu.py
Xen emulation on X86 KVM CPUs
M: David Woodhouse <dwmw2@infradead.org>
@@ -626,6 +627,7 @@
F: hw/alpha/
F: hw/isa/smc37c669-superio.c
F: tests/tcg/alpha/system/
+F: tests/functional/test_alpha_clipper.py
ARM Machines
------------
@@ -950,7 +952,7 @@
F: hw/watchdog/sbsa_gwdt.c
F: include/hw/watchdog/sbsa_gwdt.h
F: docs/system/arm/sbsa.rst
-F: tests/functional/test_aarch64_sbsaref*.py
+F: tests/functional/test_aarch64_*sbsaref*.py
Sharp SL-5500 (Collie) PDA
M: Peter Maydell <peter.maydell@linaro.org>
@@ -1019,9 +1021,10 @@
F: hw/arm/virt*
F: include/hw/arm/virt.h
F: docs/system/arm/virt.rst
-F: tests/functional/test_aarch64_virt*.py
+F: tests/functional/test_aarch64_*virt*.py
F: tests/functional/test_aarch64_tuxrun.py
F: tests/functional/test_arm_tuxrun.py
+F: tests/functional/test_arm_virt.py
Xilinx Zynq
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@@ -1262,6 +1265,7 @@
F: hw/char/mcf_uart.c
F: hw/net/mcf_fec.c
F: include/hw/m68k/mcf*.h
+F: tests/functional/test_m68k_mcf5208evb.py
NeXTcube
M: Thomas Huth <huth@tuxfamily.org>
@@ -1355,7 +1359,6 @@
F: hw/mips/malta.c
F: hw/pci-host/gt64120.c
F: include/hw/southbridge/piix.h
-F: tests/avocado/linux_ssh_mips_malta.py
F: tests/functional/test_mips*_malta.py
F: tests/functional/test_mips*_tuxrun.py
@@ -1407,6 +1410,7 @@
F: docs/system/openrisc/or1k-sim.rst
F: hw/intc/ompic.c
F: hw/openrisc/openrisc_sim.c
+F: tests/functional/test_or1k_sim.py
PowerPC Machines
----------------
@@ -1828,6 +1832,7 @@
F: tests/unit/test-x86-topo.c
F: tests/qtest/test-x86-cpuid-compat.c
F: tests/functional/test_i386_tuxrun.py
+F: tests/functional/test_linux_initrd.py
F: tests/functional/test_mem_addr_space.py
F: tests/functional/test_pc_cpu_hotplug_props.py
F: tests/functional/test_x86_64_tuxrun.py
@@ -2074,7 +2079,7 @@
F: hw/acpi/viot.c
F: hw/acpi/viot.h
-ACPI/AVOCADO/BIOSBITS
+ACPI/FUNCTIONAL/BIOSBITS
M: Ani Sinha <anisinha@redhat.com>
M: Michael S. Tsirkin <mst@redhat.com>
S: Supported
@@ -3151,6 +3156,7 @@
F: qapi/ui.json
F: util/drm.c
F: docs/devel/ui.rst
+F: tests/functional/test_vnc.py
Cocoa graphics
M: Peter Maydell <peter.maydell@linaro.org>
@@ -3669,9 +3675,7 @@
F: docs/devel/replay.rst
F: docs/system/replay.rst
F: stubs/replay.c
-F: tests/avocado/replay_kernel.py
-F: tests/avocado/replay_linux.py
-F: tests/avocado/reverse_debugging.py
+F: tests/functional/*reverse_debug*.py
F: tests/functional/*replay*.py
F: qapi/replay.json
@@ -3818,6 +3822,7 @@
F: scripts/qemu-binfmt-conf.sh
F: scripts/update-syscalltbl.sh
F: scripts/update-mips-syscall-args.sh
+F: tests/functional/test_arm_bflt.py
Tiny Code Generator (TCG)
-------------------------
@@ -4190,6 +4195,7 @@
F: include/hw/remote/vfio-user-obj.h
F: hw/remote/iommu.c
F: include/hw/remote/iommu.h
+F: tests/functional/test_multiprocess.py
EBPF:
M: Jason Wang <jasowang@redhat.com>
@@ -4249,12 +4255,6 @@
S: Maintained
F: tests/tcg/Makefile.target
-Integration Testing with the Avocado framework
-W: https://trello.com/b/6Qi1pxVn/avocado-qemu
-R: Cleber Rosa <crosa@redhat.com>
-S: Odd Fixes
-F: tests/avocado/
-
GitLab custom runner (Works On Arm Sponsored)
M: Alex Bennée <alex.bennee@linaro.org>
M: Philippe Mathieu-Daudé <philmd@linaro.org>
diff -Nru qemu-10.0.6+ds/VERSION qemu-10.0.7+ds/VERSION
--- qemu-10.0.6+ds/VERSION 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/VERSION 2025-12-06 17:54:23.000000000 +0300
@@ -1 +1 @@
-10.0.6
+10.0.7
diff -Nru qemu-10.0.6+ds/accel/kvm/kvm-all.c qemu-10.0.7+ds/accel/kvm/kvm-all.c
--- qemu-10.0.6+ds/accel/kvm/kvm-all.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/accel/kvm/kvm-all.c 2025-12-06 17:54:23.000000000 +0300
@@ -3322,10 +3322,10 @@
trace_kvm_vm_ioctl(type, arg);
accel_ioctl_begin();
ret = ioctl(s->vmfd, type, arg);
- accel_ioctl_end();
if (ret == -1) {
ret = -errno;
}
+ accel_ioctl_end();
return ret;
}
@@ -3362,10 +3362,10 @@
trace_kvm_device_ioctl(fd, type, arg);
accel_ioctl_begin();
ret = ioctl(fd, type, arg);
- accel_ioctl_end();
if (ret == -1) {
ret = -errno;
}
+ accel_ioctl_end();
return ret;
}
diff -Nru qemu-10.0.6+ds/backends/hostmem-shm.c qemu-10.0.7+ds/backends/hostmem-shm.c
--- qemu-10.0.6+ds/backends/hostmem-shm.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/backends/hostmem-shm.c 2025-12-06 17:54:23.000000000 +0300
@@ -54,6 +54,7 @@
/* Let's do the same as memory-backend-ram,share=on would do. */
ram_flags = RAM_SHARED;
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
backend_name, backend->size,
diff -Nru qemu-10.0.6+ds/block/block-backend.c qemu-10.0.7+ds/block/block-backend.c
--- qemu-10.0.6+ds/block/block-backend.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/block-backend.c 2025-12-06 17:54:23.000000000 +0300
@@ -1318,9 +1318,9 @@
* section.
*/
qemu_mutex_lock(&blk->queued_requests_lock);
+ /* blk_root_drained_end() has the corresponding blk_inc_in_flight() */
blk_dec_in_flight(blk);
qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
- blk_inc_in_flight(blk);
qemu_mutex_unlock(&blk->queued_requests_lock);
}
}
@@ -2767,9 +2767,11 @@
blk->dev_ops->drained_end(blk->dev_opaque);
}
qemu_mutex_lock(&blk->queued_requests_lock);
- while (qemu_co_enter_next(&blk->queued_requests,
- &blk->queued_requests_lock)) {
+ while (!qemu_co_queue_empty(&blk->queued_requests)) {
/* Resume all queued requests */
+ blk_inc_in_flight(blk);
+ qemu_co_enter_next(&blk->queued_requests,
+ &blk->queued_requests_lock);
}
qemu_mutex_unlock(&blk->queued_requests_lock);
}
diff -Nru qemu-10.0.6+ds/block/commit.c qemu-10.0.7+ds/block/commit.c
--- qemu-10.0.6+ds/block/commit.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/commit.c 2025-12-06 17:54:23.000000000 +0300
@@ -15,6 +15,8 @@
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "trace.h"
+#include "block/block-common.h"
+#include "block/coroutines.h"
#include "block/block_int.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
@@ -126,6 +128,84 @@
blk_unref(s->top);
}
+static int commit_iteration(CommitBlockJob *s, int64_t offset,
+ int64_t *requested_bytes, void *buf)
+{
+ BlockErrorAction action;
+ int64_t bytes = *requested_bytes;
+ int ret = 0;
+ bool error_in_source = true;
+
+ /* Copy if allocated above the base */
+ WITH_GRAPH_RDLOCK_GUARD() {
+ ret = bdrv_co_common_block_status_above(blk_bs(s->top),
+ s->base_overlay, true, true, offset, COMMIT_BUFFER_SIZE,
+ &bytes, NULL, NULL, NULL);
+ }
+
+ trace_commit_one_iteration(s, offset, bytes, ret);
+
+ if (ret < 0) {
+ goto fail;
+ }
+
+ if (ret & BDRV_BLOCK_ALLOCATED) {
+ if (ret & BDRV_BLOCK_ZERO) {
+ /*
+ * If the top (sub)clusters are smaller than the base
+ * (sub)clusters, this will not unmap unless the underlying device
+ * does some tracking of these requests. Ideally, we would find
+ * the maximal extent of the zero clusters.
+ */
+ ret = blk_co_pwrite_zeroes(s->base, offset, bytes,
+ BDRV_REQ_MAY_UNMAP);
+ if (ret < 0) {
+ error_in_source = false;
+ goto fail;
+ }
+ } else {
+ assert(bytes < SIZE_MAX);
+
+ ret = blk_co_pread(s->top, offset, bytes, buf, 0);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ ret = blk_co_pwrite(s->base, offset, bytes, buf, 0);
+ if (ret < 0) {
+ error_in_source = false;
+ goto fail;
+ }
+ }
+
+ /*
+ * Whether zeroes actually end up on disk depends on the details of
+ * the underlying driver. Therefore, this might rate limit more than
+ * is necessary.
+ */
+ block_job_ratelimit_processed_bytes(&s->common, bytes);
+ }
+
+ /* Publish progress */
+
+ job_progress_update(&s->common.job, bytes);
+
+ *requested_bytes = bytes;
+
+ return 0;
+
+fail:
+ action = block_job_error_action(&s->common, s->on_error,
+ error_in_source, -ret);
+ if (action == BLOCK_ERROR_ACTION_REPORT) {
+ return ret;
+ }
+
+ *requested_bytes = 0;
+
+ return 0;
+}
+
static int coroutine_fn commit_run(Job *job, Error **errp)
{
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
@@ -156,9 +236,6 @@
buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
for (offset = 0; offset < len; offset += n) {
- bool copy;
- bool error_in_source = true;
-
/* Note that even when no rate limit is applied we need to yield
* with no pending I/O here so that bdrv_drain_all() returns.
*/
@@ -166,38 +243,11 @@
if (job_is_cancelled(&s->common.job)) {
break;
}
- /* Copy if allocated above the base */
- ret = blk_co_is_allocated_above(s->top, s->base_overlay, true,
- offset, COMMIT_BUFFER_SIZE, &n);
- copy = (ret > 0);
- trace_commit_one_iteration(s, offset, n, ret);
- if (copy) {
- assert(n < SIZE_MAX);
-
- ret = blk_co_pread(s->top, offset, n, buf, 0);
- if (ret >= 0) {
- ret = blk_co_pwrite(s->base, offset, n, buf, 0);
- if (ret < 0) {
- error_in_source = false;
- }
- }
- }
- if (ret < 0) {
- BlockErrorAction action =
- block_job_error_action(&s->common, s->on_error,
- error_in_source, -ret);
- if (action == BLOCK_ERROR_ACTION_REPORT) {
- return ret;
- } else {
- n = 0;
- continue;
- }
- }
- /* Publish progress */
- job_progress_update(&s->common.job, n);
- if (copy) {
- block_job_ratelimit_processed_bytes(&s->common, n);
+ ret = commit_iteration(s, offset, &n, buf);
+
+ if (ret < 0) {
+ return ret;
}
}
diff -Nru qemu-10.0.6+ds/block/crypto.c qemu-10.0.7+ds/block/crypto.c
--- qemu-10.0.6+ds/block/crypto.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/crypto.c 2025-12-06 17:54:23.000000000 +0300
@@ -67,11 +67,18 @@
BlockCrypto *crypto = bs->opaque;
ssize_t ret;
- GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ if (qemu_in_coroutine()) {
+ GRAPH_RDLOCK_GUARD();
- ret = bdrv_pread(crypto->header ? crypto->header : bs->file,
- offset, buflen, buf, 0);
+ ret = bdrv_co_pread(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
+ } else {
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ ret = bdrv_pread(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
+ }
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read encryption header");
return ret;
@@ -90,11 +97,18 @@
BlockCrypto *crypto = bs->opaque;
ssize_t ret;
- GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ if (qemu_in_coroutine()) {
+ GRAPH_RDLOCK_GUARD();
- ret = bdrv_pwrite(crypto->header ? crypto->header : bs->file,
- offset, buflen, buf, 0);
+ ret = bdrv_co_pwrite(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
+ } else {
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ ret = bdrv_pwrite(crypto->header ? crypto->header : bs->file,
+ offset, buflen, buf, 0);
+ }
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not write encryption header");
return ret;
@@ -792,7 +806,7 @@
char *buf = NULL;
int64_t size;
bool detached_hdr =
- qemu_opt_get_bool(opts, "detached-header", false);
+ qemu_opt_get_bool_del(opts, "detached-header", false);
unsigned int cflags = 0;
int ret;
Error *local_err = NULL;
diff -Nru qemu-10.0.6+ds/block/curl.c qemu-10.0.7+ds/block/curl.c
--- qemu-10.0.6+ds/block/curl.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/curl.c 2025-12-06 17:54:23.000000000 +0300
@@ -258,8 +258,8 @@
}
/* Called with s->mutex held. */
-static bool curl_find_buf(BDRVCURLState *s, uint64_t start, uint64_t len,
- CURLAIOCB *acb)
+static bool coroutine_fn
+curl_find_buf(BDRVCURLState *s, uint64_t start, uint64_t len, CURLAIOCB *acb)
{
int i;
uint64_t end = start + len;
@@ -307,6 +307,10 @@
for (j=0; j<CURL_NUM_ACB; j++) {
if (!state->acb[j]) {
state->acb[j] = acb;
+ /* Await ongoing request */
+ qemu_mutex_unlock(&s->mutex);
+ qemu_coroutine_yield();
+ qemu_mutex_lock(&s->mutex);
return true;
}
}
@@ -378,6 +382,16 @@
acb->ret = error ? -EIO : 0;
state->acb[i] = NULL;
qemu_mutex_unlock(&s->mutex);
+ /*
+ * Current AioContext is the BDS context, which may or may not
+ * be the request (coroutine) context.
+ * - If it is, the coroutine must have yielded or the FD handler
+ * (curl_multi_do()/curl_multi_timeout_do()) could not have
+ * been called and we would not be here
+ * - If it is not, it doesn't matter whether it has already
+ * yielded or not; it will be scheduled once it does yield
+ * So aio_co_wake() is safe to call.
+ */
aio_co_wake(acb->co);
qemu_mutex_lock(&s->mutex);
}
@@ -524,7 +538,7 @@
#endif
#ifdef DEBUG_VERBOSE
- if (curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1)) {
+ if (curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1L)) {
goto err;
}
#endif
@@ -879,7 +893,7 @@
return -EINVAL;
}
-static void coroutine_fn curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb)
+static void coroutine_fn curl_do_preadv(BlockDriverState *bs, CURLAIOCB *acb)
{
CURLState *state;
int running;
@@ -891,10 +905,13 @@
qemu_mutex_lock(&s->mutex);
- // In case we have the requested data already (e.g. read-ahead),
- // we can just call the callback and be done.
+ /*
+ * In case we have the requested data already (e.g. read-ahead),
+ * we can just call the callback and be done. This may have to
+ * await an ongoing request, in which case it itself will yield.
+ */
if (curl_find_buf(s, start, acb->bytes, acb)) {
- goto out;
+ goto dont_yield;
}
// No cache found, so let's start a new request
@@ -909,7 +926,7 @@
if (curl_init_state(s, state) < 0) {
curl_clean_state(state);
acb->ret = -EIO;
- goto out;
+ goto dont_yield;
}
acb->start = 0;
@@ -924,7 +941,7 @@
if (state->buf_len && state->orig_buf == NULL) {
curl_clean_state(state);
acb->ret = -ENOMEM;
- goto out;
+ goto dont_yield;
}
state->acb[0] = acb;
@@ -936,13 +953,16 @@
acb->ret = -EIO;
curl_clean_state(state);
- goto out;
+ goto dont_yield;
}
/* Tell curl it needs to kick things off */
curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
+ qemu_mutex_unlock(&s->mutex);
+ qemu_coroutine_yield();
+ return;
-out:
+dont_yield:
qemu_mutex_unlock(&s->mutex);
}
@@ -958,10 +978,7 @@
.bytes = bytes
};
- curl_setup_preadv(bs, &acb);
- while (acb.ret == -EINPROGRESS) {
- qemu_coroutine_yield();
- }
+ curl_do_preadv(bs, &acb);
return acb.ret;
}
diff -Nru qemu-10.0.6+ds/block/io.c qemu-10.0.7+ds/block/io.c
--- qemu-10.0.6+ds/block/io.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/io.c 2025-12-06 17:54:23.000000000 +0300
@@ -721,11 +721,14 @@
Coroutine *self = qemu_coroutine_self();
IO_CODE();
+ qemu_mutex_lock(&bs->reqs_lock);
QLIST_FOREACH(req, &bs->tracked_requests, list) {
if (req->co == self) {
+ qemu_mutex_unlock(&bs->reqs_lock);
return req;
}
}
+ qemu_mutex_unlock(&bs->reqs_lock);
return NULL;
}
diff -Nru qemu-10.0.6+ds/block/io_uring.c qemu-10.0.7+ds/block/io_uring.c
--- qemu-10.0.6+ds/block/io_uring.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/io_uring.c 2025-12-06 17:54:23.000000000 +0300
@@ -120,11 +120,14 @@
* event loop. When there are no events left to complete the BH is being
* canceled.
*
+ * Returns whether ioq_submit() must be called again afterwards since requests
+ * were resubmitted via luring_resubmit().
*/
-static void luring_process_completions(LuringState *s)
+static bool luring_process_completions(LuringState *s)
{
struct io_uring_cqe *cqes;
int total_bytes;
+ bool resubmit = false;
defer_call_begin();
@@ -182,6 +185,7 @@
*/
if (ret == -EINTR || ret == -EAGAIN) {
luring_resubmit(s, luringcb);
+ resubmit = true;
continue;
}
} else if (!luringcb->qiov) {
@@ -194,6 +198,7 @@
if (luringcb->is_read) {
if (ret > 0) {
luring_resubmit_short_read(s, luringcb, ret);
+ resubmit = true;
continue;
} else {
/* Pad with zeroes */
@@ -224,6 +229,8 @@
qemu_bh_cancel(s->completion_bh);
defer_call_end();
+
+ return resubmit;
}
static int ioq_submit(LuringState *s)
@@ -231,6 +238,7 @@
int ret = 0;
LuringAIOCB *luringcb, *luringcb_next;
+resubmit:
while (s->io_q.in_queue > 0) {
/*
* Try to fetch sqes from the ring for requests waiting in
@@ -260,12 +268,14 @@
}
s->io_q.blocked = (s->io_q.in_queue > 0);
- if (s->io_q.in_flight) {
+ if (ret >= 0 && s->io_q.in_flight) {
/*
* We can try to complete something just right away if there are
* still requests in-flight.
*/
- luring_process_completions(s);
+ if (luring_process_completions(s)) {
+ goto resubmit;
+ }
}
return ret;
}
diff -Nru qemu-10.0.6+ds/block/nfs.c qemu-10.0.7+ds/block/nfs.c
--- qemu-10.0.6+ds/block/nfs.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/nfs.c 2025-12-06 17:54:23.000000000 +0300
@@ -69,7 +69,6 @@
typedef struct NFSRPC {
BlockDriverState *bs;
int ret;
- int complete;
QEMUIOVector *iov;
struct stat *st;
Coroutine *co;
@@ -230,14 +229,6 @@
};
}
-static void nfs_co_generic_bh_cb(void *opaque)
-{
- NFSRPC *task = opaque;
-
- task->complete = 1;
- aio_co_wake(task->co);
-}
-
/* Called (via nfs_service) with QemuMutex held. */
static void
nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
@@ -256,8 +247,16 @@
if (task->ret < 0) {
error_report("NFS Error: %s", nfs_get_error(nfs));
}
- replay_bh_schedule_oneshot_event(task->client->aio_context,
- nfs_co_generic_bh_cb, task);
+
+ /*
+ * Safe to call: nfs_service(), which called us, is only run from the FD
+ * handlers, never from the request coroutine. The request coroutine in
+ * turn will yield unconditionally.
+ * No need to release the lock, even if we directly enter the coroutine, as
+ * the lock is never re-taken after yielding. (Note: If we do enter the
+ * coroutine, @task will probably be dangling once aio_co_wake() returns.)
+ */
+ aio_co_wake(task->co);
}
static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset,
@@ -278,9 +277,7 @@
nfs_set_events(client);
}
- while (!task.complete) {
- qemu_coroutine_yield();
- }
+ qemu_coroutine_yield();
if (task.ret < 0) {
return task.ret;
@@ -328,9 +325,7 @@
nfs_set_events(client);
}
- while (!task.complete) {
- qemu_coroutine_yield();
- }
+ qemu_coroutine_yield();
if (my_buffer) {
g_free(buf);
@@ -358,9 +353,7 @@
nfs_set_events(client);
}
- while (!task.complete) {
- qemu_coroutine_yield();
- }
+ qemu_coroutine_yield();
return task.ret;
}
@@ -723,8 +716,8 @@
if (task->ret < 0) {
error_report("NFS Error: %s", nfs_get_error(nfs));
}
- replay_bh_schedule_oneshot_event(task->client->aio_context,
- nfs_co_generic_bh_cb, task);
+ /* Safe to call, see nfs_co_generic_cb() */
+ aio_co_wake(task->co);
}
static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)
@@ -748,9 +741,7 @@
nfs_set_events(client);
}
- while (!task.complete) {
- qemu_coroutine_yield();
- }
+ qemu_coroutine_yield();
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
diff -Nru qemu-10.0.6+ds/block/nvme.c qemu-10.0.7+ds/block/nvme.c
--- qemu-10.0.6+ds/block/nvme.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/nvme.c 2025-12-06 17:54:23.000000000 +0300
@@ -480,7 +480,7 @@
}
}
-static void nvme_deferred_fn(void *opaque)
+static void nvme_kick_and_check_completions(void *opaque)
{
NVMeQueuePair *q = opaque;
@@ -489,6 +489,18 @@
nvme_process_completion(q);
}
+static void nvme_deferred_fn(void *opaque)
+{
+ NVMeQueuePair *q = opaque;
+
+ if (qemu_get_current_aio_context() == q->s->aio_context) {
+ nvme_kick_and_check_completions(q);
+ } else {
+ aio_bh_schedule_oneshot(q->s->aio_context,
+ nvme_kick_and_check_completions, q);
+ }
+}
+
static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req,
NvmeCmd *cmd, BlockCompletionFunc cb,
void *opaque)
@@ -1159,25 +1171,35 @@
typedef struct {
Coroutine *co;
+ bool skip_yield;
int ret;
- AioContext *ctx;
} NVMeCoData;
-static void nvme_rw_cb_bh(void *opaque)
-{
- NVMeCoData *data = opaque;
- qemu_coroutine_enter(data->co);
-}
-
static void nvme_rw_cb(void *opaque, int ret)
{
NVMeCoData *data = opaque;
+
data->ret = ret;
- if (!data->co) {
- /* The rw coroutine hasn't yielded, don't try to enter. */
- return;
+
+ if (data->co == qemu_coroutine_self()) {
+ /*
+ * Fast path: We are inside of the request coroutine (through
+ * nvme_submit_command, nvme_deferred_fn, nvme_process_completion).
+ * We can set data->skip_yield here to keep the coroutine from
+ * yielding, and then we don't need to schedule a BH to wake it.
+ */
+ data->skip_yield = true;
+ } else {
+ /*
+ * Safe to call: The case where we run in the request coroutine is
+ * handled above, so we must be independent of it; and without
+ * skip_yield set, the coroutine will yield.
+ * No need to release NVMeQueuePair.lock (we are called without it
+ * held). (Note: If we enter the coroutine here, @data will
+ * probably be dangling once aio_co_wake() returns.)
+ */
+ aio_co_wake(data->co);
}
- replay_bh_schedule_oneshot_event(data->ctx, nvme_rw_cb_bh, data);
}
static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs,
@@ -1201,7 +1223,7 @@
.cdw12 = cpu_to_le32(cdw12),
};
NVMeCoData data = {
- .ctx = bdrv_get_aio_context(bs),
+ .co = qemu_coroutine_self(),
.ret = -EINPROGRESS,
};
@@ -1218,9 +1240,7 @@
return r;
}
nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);
-
- data.co = qemu_coroutine_self();
- while (data.ret == -EINPROGRESS) {
+ if (!data.skip_yield) {
qemu_coroutine_yield();
}
@@ -1316,7 +1336,7 @@
.nsid = cpu_to_le32(s->nsid),
};
NVMeCoData data = {
- .ctx = bdrv_get_aio_context(bs),
+ .co = qemu_coroutine_self(),
.ret = -EINPROGRESS,
};
@@ -1324,9 +1344,7 @@
req = nvme_get_free_req(ioq);
assert(req);
nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);
-
- data.co = qemu_coroutine_self();
- if (data.ret == -EINPROGRESS) {
+ if (!data.skip_yield) {
qemu_coroutine_yield();
}
@@ -1367,7 +1385,7 @@
};
NVMeCoData data = {
- .ctx = bdrv_get_aio_context(bs),
+ .co = qemu_coroutine_self(),
.ret = -EINPROGRESS,
};
@@ -1387,9 +1405,7 @@
assert(req);
nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);
-
- data.co = qemu_coroutine_self();
- while (data.ret == -EINPROGRESS) {
+ if (!data.skip_yield) {
qemu_coroutine_yield();
}
@@ -1417,7 +1433,7 @@
};
NVMeCoData data = {
- .ctx = bdrv_get_aio_context(bs),
+ .co = qemu_coroutine_self(),
.ret = -EINPROGRESS,
};
@@ -1462,9 +1478,7 @@
trace_nvme_dsm(s, offset, bytes);
nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);
-
- data.co = qemu_coroutine_self();
- while (data.ret == -EINPROGRESS) {
+ if (!data.skip_yield) {
qemu_coroutine_yield();
}
diff -Nru qemu-10.0.6+ds/block/rbd.c qemu-10.0.7+ds/block/rbd.c
--- qemu-10.0.6+ds/block/rbd.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/block/rbd.c 2025-12-06 17:54:23.000000000 +0300
@@ -110,9 +110,7 @@
} BDRVRBDState;
typedef struct RBDTask {
- BlockDriverState *bs;
Coroutine *co;
- bool complete;
int64_t ret;
} RBDTask;
@@ -1310,7 +1308,6 @@
static void qemu_rbd_finish_bh(void *opaque)
{
RBDTask *task = opaque;
- task->complete = true;
aio_co_wake(task->co);
}
@@ -1327,7 +1324,7 @@
{
task->ret = rbd_aio_get_return_value(c);
rbd_aio_release(c);
- aio_bh_schedule_oneshot(bdrv_get_aio_context(task->bs),
+ aio_bh_schedule_oneshot(qemu_coroutine_get_aio_context(task->co),
qemu_rbd_finish_bh, task);
}
@@ -1339,7 +1336,7 @@
RBDAIOCmd cmd)
{
BDRVRBDState *s = bs->opaque;
- RBDTask task = { .bs = bs, .co = qemu_coroutine_self() };
+ RBDTask task = { .co = qemu_coroutine_self() };
rbd_completion_t c;
int r;
@@ -1402,9 +1399,8 @@
return r;
}
- while (!task.complete) {
- qemu_coroutine_yield();
- }
+ /* Expect exactly a single wake from qemu_rbd_finish_bh() */
+ qemu_coroutine_yield();
if (task.ret < 0) {
error_report("rbd request failed: cmd %d offset %" PRIu64 " bytes %"
diff -Nru qemu-10.0.6+ds/chardev/char-pty.c qemu-10.0.7+ds/chardev/char-pty.c
--- qemu-10.0.6+ds/chardev/char-pty.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/chardev/char-pty.c 2025-12-06 17:54:23.000000000 +0300
@@ -125,7 +125,7 @@
rc = RETRY_ON_EINTR(g_poll(&pfd, 1, 0));
g_assert(rc >= 0);
if (!(pfd.revents & G_IO_HUP) && (pfd.revents & G_IO_OUT)) {
- io_channel_send(s->ioc, buf, len);
+ return io_channel_send(s->ioc, buf, len);
}
return len;
diff -Nru qemu-10.0.6+ds/configure qemu-10.0.7+ds/configure
--- qemu-10.0.6+ds/configure 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/configure 2025-12-06 17:54:23.000000000 +0300
@@ -1685,7 +1685,7 @@
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
LINKS="$LINKS pc-bios/vof/Makefile"
LINKS="$LINKS .gdbinit scripts" # scripts needed by relative path in .gdbinit
-LINKS="$LINKS tests/avocado tests/data"
+LINKS="$LINKS tests/data"
LINKS="$LINKS tests/qemu-iotests/check tests/qemu-iotests/Makefile"
LINKS="$LINKS python"
for f in $LINKS ; do
diff -Nru qemu-10.0.6+ds/crypto/tlscredsx509.c qemu-10.0.7+ds/crypto/tlscredsx509.c
--- qemu-10.0.6+ds/crypto/tlscredsx509.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/crypto/tlscredsx509.c 2025-12-06 17:54:23.000000000 +0300
@@ -144,7 +144,7 @@
if (status < 0) {
if (status == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
usage = isCA ? GNUTLS_KEY_KEY_CERT_SIGN :
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT;
+ GNUTLS_KEY_DIGITAL_SIGNATURE;
} else {
error_setg(errp,
"Unable to query certificate %s key usage: %s",
@@ -171,14 +171,6 @@
return -1;
}
}
- if (!(usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) {
- if (critical) {
- error_setg(errp,
- "Certificate %s usage does not permit key "
- "encipherment", certFile);
- return -1;
- }
- }
}
return 0;
diff -Nru qemu-10.0.6+ds/docs/about/build-platforms.rst qemu-10.0.7+ds/docs/about/build-platforms.rst
--- qemu-10.0.6+ds/docs/about/build-platforms.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/about/build-platforms.rst 2025-12-06 17:54:23.000000000 +0300
@@ -123,11 +123,11 @@
to build QEMU.
Optional build dependencies
- Build components whose absence does not affect the ability to build
- QEMU may not be available in distros, or may be too old for QEMU's
- requirements. Many of these, such as the Avocado testing framework
- or various linters, are written in Python and therefore can also
- be installed using ``pip``. Cross compilers are another example
+ Build components whose absence does not affect the ability to build QEMU
+ may not be available in distros, or may be too old for our requirements.
+ Many of these, such as additional modules for the functional testing
+ framework or various linters, are written in Python and therefore can
+ also be installed using ``pip``. Cross compilers are another example
of optional build-time dependency; in this case it is possible to
download them from repositories such as EPEL, to use container-based
cross compilation using ``docker`` or ``podman``, or to use pre-built
diff -Nru qemu-10.0.6+ds/docs/devel/build-system.rst qemu-10.0.7+ds/docs/devel/build-system.rst
--- qemu-10.0.6+ds/docs/devel/build-system.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/build-system.rst 2025-12-06 17:54:23.000000000 +0300
@@ -134,7 +134,7 @@
At this stage, ``configure`` also queries the chosen Python interpreter
about QEMU's build dependencies. Note that the build process does *not*
-look for ``meson``, ``sphinx-build`` or ``avocado`` binaries in the PATH;
+look for ``meson`` or ``sphinx-build`` binaries in the PATH;
likewise, there are no options such as ``--meson`` or ``--sphinx-build``.
This avoids a potential mismatch, where Meson and Sphinx binaries on the
PATH might operate in a different Python environment than the one chosen
@@ -151,7 +151,7 @@
or by downloading the package with PyPI. Downloading can be disabled with
``--disable-download``; and anyway, it only happens when a ``configure``
option (currently, only ``--enable-docs``) is explicitly enabled but
-the dependencies are not present\ [#pip]_.
+the dependencies are not present.
.. [#distlib] The scripts are created based on the package's metadata,
specifically the ``console_script`` entry points. This is the
@@ -164,10 +164,6 @@
because the Python Packaging Authority provides a package
``distlib.scripts`` to perform this task.
-.. [#pip] ``pip`` might also be used when running ``make check-avocado``
- if downloading is enabled, to ensure that Avocado is
- available.
-
The required versions of the packages are stored in a configuration file
``pythondeps.toml``. The format is custom to QEMU, but it is documented
at the top of the file itself and it should be easy to understand. The
@@ -497,8 +493,7 @@
``pyvenv/bin``, and calling ``pip`` to install dependencies.
``tests/Makefile.include``
- Rules for external test harnesses. These include the TCG tests
- and the Avocado-based integration tests.
+ Rules for external test harnesses like the TCG tests.
``tests/docker/Makefile.include``
Rules for Docker tests. Like ``tests/Makefile.include``, this file is
diff -Nru qemu-10.0.6+ds/docs/devel/codebase.rst qemu-10.0.7+ds/docs/devel/codebase.rst
--- qemu-10.0.6+ds/docs/devel/codebase.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/codebase.rst 2025-12-06 17:54:23.000000000 +0300
@@ -175,11 +175,6 @@
* `tests <https://gitlab.com/qemu-project/qemu/-/tree/master/tests>`_:
QEMU `test <testing>` suite
- - `avocado <https://gitlab.com/qemu-project/qemu/-/tree/master/tests/avocado>`_:
- Functional tests booting full VM using `Avocado framework <checkavocado-ref>`.
- Those tests will be transformed and moved into
- `tests/functional <https://gitlab.com/qemu-project/qemu/-/tree/master/tests/functional>`_
- in the future.
- `data <https://gitlab.com/qemu-project/qemu/-/tree/master/tests/data>`_:
Data for various tests.
- `decode <https://gitlab.com/qemu-project/qemu/-/tree/master/tests/decode>`_:
diff -Nru qemu-10.0.6+ds/docs/devel/submitting-a-pull-request.rst qemu-10.0.7+ds/docs/devel/submitting-a-pull-request.rst
--- qemu-10.0.6+ds/docs/devel/submitting-a-pull-request.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/submitting-a-pull-request.rst 2025-12-06 17:54:23.000000000 +0300
@@ -67,7 +67,7 @@
pull requests that should be applied to master.
You might be interested in the `make-pullreq
-<https://git.linaro.org/people/peter.maydell/misc-scripts.git/tree/make-pullreq>`__
+<https://gitlab.com/pm215/misc-scripts/-/blob/master/make-pullreq>`__
script which automates some of this process for you and includes a few
sanity checks. Note that you must edit it to configure it suitably for
your local situation!
diff -Nru qemu-10.0.6+ds/docs/devel/testing/avocado.rst qemu-10.0.7+ds/docs/devel/testing/avocado.rst
--- qemu-10.0.6+ds/docs/devel/testing/avocado.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/avocado.rst 1970-01-01 03:00:00.000000000 +0300
@@ -1,581 +0,0 @@
-.. _checkavocado-ref:
-
-
-Integration testing with Avocado
-================================
-
-The ``tests/avocado`` directory hosts integration tests. They're usually
-higher level tests, and may interact with external resources and with
-various guest operating systems.
-
-These tests are written using the Avocado Testing Framework (which must be
-installed separately) in conjunction with a the ``avocado_qemu.QemuSystemTest``
-class, implemented at ``tests/avocado/avocado_qemu``.
-
-Tests based on ``avocado_qemu.QemuSystemTest`` can easily:
-
- * Customize the command line arguments given to the convenience
- ``self.vm`` attribute (a QEMUMachine instance)
-
- * Interact with the QEMU monitor, send QMP commands and check
- their results
-
- * Interact with the guest OS, using the convenience console device
- (which may be useful to assert the effectiveness and correctness of
- command line arguments or QMP commands)
-
- * Interact with external data files that accompany the test itself
- (see ``self.get_data()``)
-
- * Download (and cache) remote data files, such as firmware and kernel
- images
-
- * Have access to a library of guest OS images (by means of the
- ``avocado.utils.vmimage`` library)
-
- * Make use of various other test related utilities available at the
- test class itself and at the utility library:
-
- - http://avocado-framework.readthedocs.io/en/latest/api/test/avocado.html#avocado.Test
- - http://avocado-framework.readthedocs.io/en/latest/api/utils/avocado.utils.html
-
-Running tests
--------------
-
-You can run the avocado tests simply by executing:
-
-.. code::
-
- make check-avocado
-
-This involves the automatic installation, from PyPI, of all the
-necessary avocado-framework dependencies into the QEMU venv within the
-build tree (at ``./pyvenv``). Test results are also saved within the
-build tree (at ``tests/results``).
-
-Note: the build environment must be using a Python 3 stack, and have
-the ``venv`` and ``pip`` packages installed. If necessary, make sure
-``configure`` is called with ``--python=`` and that those modules are
-available. On Debian and Ubuntu based systems, depending on the
-specific version, they may be on packages named ``python3-venv`` and
-``python3-pip``.
-
-It is also possible to run tests based on tags using the
-``make check-avocado`` command and the ``AVOCADO_TAGS`` environment
-variable:
-
-.. code::
-
- make check-avocado AVOCADO_TAGS=quick
-
-Note that tags separated with commas have an AND behavior, while tags
-separated by spaces have an OR behavior. For more information on Avocado
-tags, see:
-
- https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/tags.html
-
-To run a single test file, a couple of them, or a test within a file
-using the ``make check-avocado`` command, set the ``AVOCADO_TESTS``
-environment variable with the test files or test names. To run all
-tests from a single file, use:
-
- .. code::
-
- make check-avocado AVOCADO_TESTS=$FILEPATH
-
-The same is valid to run tests from multiple test files:
-
- .. code::
-
- make check-avocado AVOCADO_TESTS='$FILEPATH1 $FILEPATH2'
-
-To run a single test within a file, use:
-
- .. code::
-
- make check-avocado AVOCADO_TESTS=$FILEPATH:$TESTCLASS.$TESTNAME
-
-The same is valid to run single tests from multiple test files:
-
- .. code::
-
- make check-avocado AVOCADO_TESTS='$FILEPATH1:$TESTCLASS1.$TESTNAME1 $FILEPATH2:$TESTCLASS2.$TESTNAME2'
-
-The scripts installed inside the virtual environment may be used
-without an "activation". For instance, the Avocado test runner
-may be invoked by running:
-
- .. code::
-
- pyvenv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
-
-Note that if ``make check-avocado`` was not executed before, it is
-possible to create the Python virtual environment with the dependencies
-needed running:
-
- .. code::
-
- make check-venv
-
-It is also possible to run tests from a single file or a single test within
-a test file. To run tests from a single file within the build tree, use:
-
- .. code::
-
- pyvenv/bin/avocado run tests/avocado/$TESTFILE
-
-To run a single test within a test file, use:
-
- .. code::
-
- pyvenv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
-
-Valid test names are visible in the output from any previous execution
-of Avocado or ``make check-avocado``, and can also be queried using:
-
- .. code::
-
- pyvenv/bin/avocado list tests/avocado
-
-Manual Installation
--------------------
-
-To manually install Avocado and its dependencies, run:
-
-.. code::
-
- pip install --user avocado-framework
-
-Alternatively, follow the instructions on this link:
-
- https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/installing.html
-
-Overview
---------
-
-The ``tests/avocado/avocado_qemu`` directory provides the
-``avocado_qemu`` Python module, containing the ``avocado_qemu.QemuSystemTest``
-class. Here's a simple usage example:
-
-.. code::
-
- from avocado_qemu import QemuSystemTest
-
-
- class Version(QemuSystemTest):
- """
- :avocado: tags=quick
- """
- def test_qmp_human_info_version(self):
- self.vm.launch()
- res = self.vm.cmd('human-monitor-command',
- command_line='info version')
- self.assertRegex(res, r'^(\d+\.\d+\.\d)')
-
-To execute your test, run:
-
-.. code::
-
- avocado run version.py
-
-Tests may be classified according to a convention by using docstring
-directives such as ``:avocado: tags=TAG1,TAG2``. To run all tests
-in the current directory, tagged as "quick", run:
-
-.. code::
-
- avocado run -t quick .
-
-The ``avocado_qemu.QemuSystemTest`` base test class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``avocado_qemu.QemuSystemTest`` class has a number of characteristics
-that are worth being mentioned right away.
-
-First of all, it attempts to give each test a ready to use QEMUMachine
-instance, available at ``self.vm``. Because many tests will tweak the
-QEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``)
-is left to the test writer.
-
-The base test class has also support for tests with more than one
-QEMUMachine. The way to get machines is through the ``self.get_vm()``
-method which will return a QEMUMachine instance. The ``self.get_vm()``
-method accepts arguments that will be passed to the QEMUMachine creation
-and also an optional ``name`` attribute so you can identify a specific
-machine and get it more than once through the tests methods. A simple
-and hypothetical example follows:
-
-.. code::
-
- from avocado_qemu import QemuSystemTest
-
-
- class MultipleMachines(QemuSystemTest):
- def test_multiple_machines(self):
- first_machine = self.get_vm()
- second_machine = self.get_vm()
- self.get_vm(name='third_machine').launch()
-
- first_machine.launch()
- second_machine.launch()
-
- first_res = first_machine.cmd(
- 'human-monitor-command',
- command_line='info version')
-
- second_res = second_machine.cmd(
- 'human-monitor-command',
- command_line='info version')
-
- third_res = self.get_vm(name='third_machine').cmd(
- 'human-monitor-command',
- command_line='info version')
-
- self.assertEqual(first_res, second_res, third_res)
-
-At test "tear down", ``avocado_qemu.QemuSystemTest`` handles all the
-QEMUMachines shutdown.
-
-The ``avocado_qemu.LinuxTest`` base test class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``avocado_qemu.LinuxTest`` is further specialization of the
-``avocado_qemu.QemuSystemTest`` class, so it contains all the characteristics
-of the later plus some extra features.
-
-First of all, this base class is intended for tests that need to
-interact with a fully booted and operational Linux guest. At this
-time, it uses a Fedora 31 guest image. The most basic example looks
-like this:
-
-.. code::
-
- from avocado_qemu import LinuxTest
-
-
- class SomeTest(LinuxTest):
-
- def test(self):
- self.launch_and_wait()
- self.ssh_command('some_command_to_be_run_in_the_guest')
-
-Please refer to tests that use ``avocado_qemu.LinuxTest`` under
-``tests/avocado`` for more examples.
-
-QEMUMachine
------------
-
-The QEMUMachine API is already widely used in the Python iotests,
-device-crash-test and other Python scripts. It's a wrapper around the
-execution of a QEMU binary, giving its users:
-
- * the ability to set command line arguments to be given to the QEMU
- binary
-
- * a ready to use QMP connection and interface, which can be used to
- send commands and inspect its results, as well as asynchronous
- events
-
- * convenience methods to set commonly used command line arguments in
- a more succinct and intuitive way
-
-QEMU binary selection
-^^^^^^^^^^^^^^^^^^^^^
-
-The QEMU binary used for the ``self.vm`` QEMUMachine instance will
-primarily depend on the value of the ``qemu_bin`` parameter. If it's
-not explicitly set, its default value will be the result of a dynamic
-probe in the same source tree. A suitable binary will be one that
-targets the architecture matching host machine.
-
-Based on this description, test writers will usually rely on one of
-the following approaches:
-
-1) Set ``qemu_bin``, and use the given binary
-
-2) Do not set ``qemu_bin``, and use a QEMU binary named like
- "qemu-system-${arch}", either in the current
- working directory, or in the current source tree.
-
-The resulting ``qemu_bin`` value will be preserved in the
-``avocado_qemu.QemuSystemTest`` as an attribute with the same name.
-
-Attribute reference
--------------------
-
-Test
-^^^^
-
-Besides the attributes and methods that are part of the base
-``avocado.Test`` class, the following attributes are available on any
-``avocado_qemu.QemuSystemTest`` instance.
-
-vm
-""
-
-A QEMUMachine instance, initially configured according to the given
-``qemu_bin`` parameter.
-
-arch
-""""
-
-The architecture can be used on different levels of the stack, e.g. by
-the framework or by the test itself. At the framework level, it will
-currently influence the selection of a QEMU binary (when one is not
-explicitly given).
-
-Tests are also free to use this attribute value, for their own needs.
-A test may, for instance, use the same value when selecting the
-architecture of a kernel or disk image to boot a VM with.
-
-The ``arch`` attribute will be set to the test parameter of the same
-name. If one is not given explicitly, it will either be set to
-``None``, or, if the test is tagged with one (and only one)
-``:avocado: tags=arch:VALUE`` tag, it will be set to ``VALUE``.
-
-cpu
-"""
-
-The cpu model that will be set to all QEMUMachine instances created
-by the test.
-
-The ``cpu`` attribute will be set to the test parameter of the same
-name. If one is not given explicitly, it will either be set to
-``None ``, or, if the test is tagged with one (and only one)
-``:avocado: tags=cpu:VALUE`` tag, it will be set to ``VALUE``.
-
-machine
-"""""""
-
-The machine type that will be set to all QEMUMachine instances created
-by the test.
-
-The ``machine`` attribute will be set to the test parameter of the same
-name. If one is not given explicitly, it will either be set to
-``None``, or, if the test is tagged with one (and only one)
-``:avocado: tags=machine:VALUE`` tag, it will be set to ``VALUE``.
-
-qemu_bin
-""""""""
-
-The preserved value of the ``qemu_bin`` parameter or the result of the
-dynamic probe for a QEMU binary in the current working directory or
-source tree.
-
-LinuxTest
-^^^^^^^^^
-
-Besides the attributes present on the ``avocado_qemu.QemuSystemTest`` base
-class, the ``avocado_qemu.LinuxTest`` adds the following attributes:
-
-distro
-""""""
-
-The name of the Linux distribution used as the guest image for the
-test. The name should match the **Provider** column on the list
-of images supported by the avocado.utils.vmimage library:
-
-https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
-
-distro_version
-""""""""""""""
-
-The version of the Linux distribution as the guest image for the
-test. The name should match the **Version** column on the list
-of images supported by the avocado.utils.vmimage library:
-
-https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
-
-distro_checksum
-"""""""""""""""
-
-The sha256 hash of the guest image file used for the test.
-
-If this value is not set in the code or by a test parameter (with the
-same name), no validation on the integrity of the image will be
-performed.
-
-Parameter reference
--------------------
-
-To understand how Avocado parameters are accessed by tests, and how
-they can be passed to tests, please refer to::
-
- https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#accessing-test-parameters
-
-Parameter values can be easily seen in the log files, and will look
-like the following:
-
-.. code::
-
- PARAMS (key=qemu_bin, path=*, default=./qemu-system-x86_64) => './qemu-system-x86_64
-
-Test
-^^^^
-
-arch
-""""
-
-The architecture that will influence the selection of a QEMU binary
-(when one is not explicitly given).
-
-Tests are also free to use this parameter value, for their own needs.
-A test may, for instance, use the same value when selecting the
-architecture of a kernel or disk image to boot a VM with.
-
-This parameter has a direct relation with the ``arch`` attribute. If
-not given, it will default to None.
-
-cpu
-"""
-
-The cpu model that will be set to all QEMUMachine instances created
-by the test.
-
-machine
-"""""""
-
-The machine type that will be set to all QEMUMachine instances created
-by the test.
-
-qemu_bin
-""""""""
-
-The exact QEMU binary to be used on QEMUMachine.
-
-LinuxTest
-^^^^^^^^^
-
-Besides the parameters present on the ``avocado_qemu.QemuSystemTest`` base
-class, the ``avocado_qemu.LinuxTest`` adds the following parameters:
-
-distro
-""""""
-
-The name of the Linux distribution used as the guest image for the
-test. The name should match the **Provider** column on the list
-of images supported by the avocado.utils.vmimage library:
-
-https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
-
-distro_version
-""""""""""""""
-
-The version of the Linux distribution as the guest image for the
-test. The name should match the **Version** column on the list
-of images supported by the avocado.utils.vmimage library:
-
-https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
-
-distro_checksum
-"""""""""""""""
-
-The sha256 hash of the guest image file used for the test.
-
-If this value is not set in the code or by this parameter no
-validation on the integrity of the image will be performed.
-
-Skipping tests
---------------
-
-The Avocado framework provides Python decorators which allow for easily skip
-tests running under certain conditions. For example, on the lack of a binary
-on the test system or when the running environment is a CI system. For further
-information about those decorators, please refer to::
-
- https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#skipping-tests
-
-While the conditions for skipping tests are often specifics of each one, there
-are recurring scenarios identified by the QEMU developers and the use of
-environment variables became a kind of standard way to enable/disable tests.
-
-Here is a list of the most used variables:
-
-AVOCADO_ALLOW_LARGE_STORAGE
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Tests which are going to fetch or produce assets considered *large* are not
-going to run unless that ``AVOCADO_ALLOW_LARGE_STORAGE=1`` is exported on
-the environment.
-
-The definition of *large* is a bit arbitrary here, but it usually means an
-asset which occupies at least 1GB of size on disk when uncompressed.
-
-SPEED
-^^^^^
-Tests which have a long runtime will not be run unless ``SPEED=slow`` is
-exported on the environment.
-
-The definition of *long* is a bit arbitrary here, and it depends on the
-usefulness of the test too. A unique test is worth spending more time on,
-small variations on existing tests perhaps less so. As a rough guide,
-a test or set of similar tests which take more than 100 seconds to
-complete.
-
-AVOCADO_ALLOW_UNTRUSTED_CODE
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-There are tests which will boot a kernel image or firmware that can be
-considered not safe to run on the developer's workstation, thus they are
-skipped by default. The definition of *not safe* is also arbitrary but
-usually it means a blob which either its source or build process aren't
-public available.
-
-You should export ``AVOCADO_ALLOW_UNTRUSTED_CODE=1`` on the environment in
-order to allow tests which make use of those kind of assets.
-
-AVOCADO_TIMEOUT_EXPECTED
-^^^^^^^^^^^^^^^^^^^^^^^^
-The Avocado framework has a timeout mechanism which interrupts tests to avoid the
-test suite of getting stuck. The timeout value can be set via test parameter or
-property defined in the test class, for further details::
-
- https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#setting-a-test-timeout
-
-Even though the timeout can be set by the test developer, there are some tests
-that may not have a well-defined limit of time to finish under certain
-conditions. For example, tests that take longer to execute when QEMU is
-compiled with debug flags. Therefore, the ``AVOCADO_TIMEOUT_EXPECTED`` variable
-has been used to determine whether those tests should run or not.
-
-QEMU_TEST_FLAKY_TESTS
-^^^^^^^^^^^^^^^^^^^^^
-Some tests are not working reliably and thus are disabled by default.
-This includes tests that don't run reliably on GitLab's CI which
-usually expose real issues that are rarely seen on developer machines
-due to the constraints of the CI environment. If you encounter a
-similar situation then raise a bug and then mark the test as shown on
-the code snippet below:
-
-.. code::
-
- # See https://gitlab.com/qemu-project/qemu/-/issues/nnnn
- @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
- def test(self):
- do_something()
-
-You can also add ``:avocado: tags=flaky`` to the test meta-data so
-only the flaky tests can be run as a group:
-
-.. code::
-
- env QEMU_TEST_FLAKY_TESTS=1 ./pyvenv/bin/avocado \
- run tests/avocado -filter-by-tags=flaky
-
-Tests should not live in this state forever and should either be fixed
-or eventually removed.
-
-
-Uninstalling Avocado
---------------------
-
-If you've followed the manual installation instructions above, you can
-easily uninstall Avocado. Start by listing the packages you have
-installed::
-
- pip list --user
-
-And remove any package you want with::
-
- pip uninstall <package_name>
-
-If you've used ``make check-avocado``, the Python virtual environment where
-Avocado is installed will be cleaned up as part of ``make check-clean``.
diff -Nru qemu-10.0.6+ds/docs/devel/testing/ci-definitions.rst.inc qemu-10.0.7+ds/docs/devel/testing/ci-definitions.rst.inc
--- qemu-10.0.6+ds/docs/devel/testing/ci-definitions.rst.inc 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/ci-definitions.rst.inc 1970-01-01 03:00:00.000000000 +0300
@@ -1,121 +0,0 @@
-Definition of terms
-===================
-
-This section defines the terms used in this document and correlates them with
-what is currently used on QEMU.
-
-Automated tests
----------------
-
-An automated test is written on a test framework using its generic test
-functions/classes. The test framework can run the tests and report their
-success or failure [1]_.
-
-An automated test has essentially three parts:
-
-1. The test initialization of the parameters, where the expected parameters,
- like inputs and expected results, are set up;
-2. The call to the code that should be tested;
-3. An assertion, comparing the result from the previous call with the expected
- result set during the initialization of the parameters. If the result
- matches the expected result, the test has been successful; otherwise, it has
- failed.
-
-Unit testing
-------------
-
-A unit test is responsible for exercising individual software components as a
-unit, like interfaces, data structures, and functionality, uncovering errors
-within the boundaries of a component. The verification effort is in the
-smallest software unit and focuses on the internal processing logic and data
-structures. A test case of unit tests should be designed to uncover errors due
-to erroneous computations, incorrect comparisons, or improper control flow [2]_.
-
-On QEMU, unit testing is represented by the 'check-unit' target from 'make'.
-
-Functional testing
-------------------
-
-A functional test focuses on the functional requirement of the software.
-Deriving sets of input conditions, the functional tests should fully exercise
-all the functional requirements for a program. Functional testing is
-complementary to other testing techniques, attempting to find errors like
-incorrect or missing functions, interface errors, behavior errors, and
-initialization and termination errors [3]_.
-
-On QEMU, functional testing is represented by the 'check-qtest' target from
-'make'.
-
-System testing
---------------
-
-System tests ensure all application elements mesh properly while the overall
-functionality and performance are achieved [4]_. Some or all system components
-are integrated to create a complete system to be tested as a whole. System
-testing ensures that components are compatible, interact correctly, and
-transfer the right data at the right time across their interfaces. As system
-testing focuses on interactions, use case-based testing is a practical approach
-to system testing [5]_. Note that, in some cases, system testing may require
-interaction with third-party software, like operating system images, databases,
-networks, and so on.
-
-On QEMU, system testing is represented by the 'check-avocado' target from
-'make'.
-
-Flaky tests
------------
-
-A flaky test is defined as a test that exhibits both a passing and a failing
-result with the same code on different runs. Some usual reasons for an
-intermittent/flaky test are async wait, concurrency, and test order dependency
-[6]_.
-
-Gating
-------
-
-A gate restricts the move of code from one stage to another on a
-test/deployment pipeline. The step move is granted with approval. The approval
-can be a manual intervention or a set of tests succeeding [7]_.
-
-On QEMU, the gating process happens during the pull request. The approval is
-done by the project leader running its own set of tests. The pull request gets
-merged when the tests succeed.
-
-Continuous Integration (CI)
----------------------------
-
-Continuous integration (CI) requires the builds of the entire application and
-the execution of a comprehensive set of automated tests every time there is a
-need to commit any set of changes [8]_. The automated tests can be composed of
-the unit, functional, system, and other tests.
-
-Keynotes about continuous integration (CI) [9]_:
-
-1. System tests may depend on external software (operating system images,
- firmware, database, network).
-2. It may take a long time to build and test. It may be impractical to build
- the system being developed several times per day.
-3. If the development platform is different from the target platform, it may
- not be possible to run system tests in the developer’s private workspace.
- There may be differences in hardware, operating system, or installed
- software. Therefore, more time is required for testing the system.
-
-References
-----------
-
-.. [1] Sommerville, Ian (2016). Software Engineering. p. 233.
-.. [2] Pressman, Roger S. & Maxim, Bruce R. (2020). Software Engineering,
- A Practitioner’s Approach. p. 48, 376, 378, 381.
-.. [3] Pressman, Roger S. & Maxim, Bruce R. (2020). Software Engineering,
- A Practitioner’s Approach. p. 388.
-.. [4] Pressman, Roger S. & Maxim, Bruce R. (2020). Software Engineering,
- A Practitioner’s Approach. Software Engineering, p. 377.
-.. [5] Sommerville, Ian (2016). Software Engineering. p. 59, 232, 240.
-.. [6] Luo, Qingzhou, et al. An empirical analysis of flaky tests.
- Proceedings of the 22nd ACM SIGSOFT International Symposium on
- Foundations of Software Engineering. 2014.
-.. [7] Humble, Jez & Farley, David (2010). Continuous Delivery:
- Reliable Software Releases Through Build, Test, and Deployment, p. 122.
-.. [8] Humble, Jez & Farley, David (2010). Continuous Delivery:
- Reliable Software Releases Through Build, Test, and Deployment, p. 55.
-.. [9] Sommerville, Ian (2016). Software Engineering. p. 743.
diff -Nru qemu-10.0.6+ds/docs/devel/testing/ci-jobs.rst.inc qemu-10.0.7+ds/docs/devel/testing/ci-jobs.rst.inc
--- qemu-10.0.6+ds/docs/devel/testing/ci-jobs.rst.inc 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/ci-jobs.rst.inc 2025-12-06 17:54:23.000000000 +0300
@@ -126,10 +126,10 @@
The job is for publishing content after a branch has been
merged into the upstream default branch.
-QEMU_JOB_AVOCADO
-~~~~~~~~~~~~~~~~
+QEMU_JOB_FUNCTIONAL
+~~~~~~~~~~~~~~~~~~~
-The job runs the Avocado integration test suite
+The job runs the functional test suite
Contributor controlled runtime variables
----------------------------------------
@@ -149,13 +149,12 @@
Set this variable to 2 to create the pipelines and run all
the jobs immediately, as was the historical behaviour
-QEMU_CI_AVOCADO_TESTING
-~~~~~~~~~~~~~~~~~~~~~~~
-By default, tests using the Avocado framework are not run automatically in
-the pipelines (because multiple artifacts have to be downloaded, and if
-these artifacts are not already cached, downloading them make the jobs
-reach the timeout limit). Set this variable to have the tests using the
-Avocado framework run automatically.
+QEMU_CI_FUNCTIONAL
+~~~~~~~~~~~~~~~~~~
+By default, tests using the functional framework are not run automatically
+in the pipelines (because multiple artifacts have to be downloaded, which
+might cause a lot of network traffic). Set this variable to have the tests
+using the functional framework run automatically.
Other misc variables
--------------------
diff -Nru qemu-10.0.6+ds/docs/devel/testing/ci.rst qemu-10.0.7+ds/docs/devel/testing/ci.rst
--- qemu-10.0.6+ds/docs/devel/testing/ci.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/ci.rst 2025-12-06 17:54:23.000000000 +0300
@@ -1,14 +1,34 @@
.. _ci:
-==
-CI
-==
+Continuous Integration (CI)
+===========================
+
+Continuous integration (CI) requires the builds of the entire application and
+the execution of a comprehensive set of automated tests every time there is a
+need to commit any set of changes [1]_. The automated tests are composed
+of unit, functional and other tests.
Most of QEMU's CI is run on GitLab's infrastructure although a number
of other CI services are used for specialised purposes. The most up to
date information about them and their status can be found on the
`project wiki testing page <https://wiki.qemu.org/Testing/CI>`_.
-.. include:: ci-definitions.rst.inc
+These tests are also used as gating tests before merging pull requests.
+A gating test restricts the move of code from one stage to another on a
+test/deployment pipeline. The step move is granted with approval. The approval
+can be a manual intervention or a set of tests succeeding [2]_.
+
+On QEMU, the gating process happens during the pull request. The approval is
+done by the project leader running its own set of tests. The pull request gets
+merged when the tests succeed.
+
.. include:: ci-jobs.rst.inc
.. include:: ci-runners.rst.inc
+
+References
+----------
+
+.. [1] Humble, Jez & Farley, David (2010). Continuous Delivery:
+ Reliable Software Releases Through Build, Test, and Deployment, p. 55.
+.. [2] Humble, Jez & Farley, David (2010). Continuous Delivery:
+ Reliable Software Releases Through Build, Test, and Deployment, p. 122.
diff -Nru qemu-10.0.6+ds/docs/devel/testing/functional.rst qemu-10.0.7+ds/docs/devel/testing/functional.rst
--- qemu-10.0.6+ds/docs/devel/testing/functional.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/functional.rst 2025-12-06 17:54:23.000000000 +0300
@@ -6,9 +6,6 @@
The ``tests/functional`` directory hosts functional tests written in
Python. They are usually higher level tests, and may interact with
external resources and with various guest operating systems.
-The functional tests have initially evolved from the Avocado tests, so there
-is a lot of similarity to those tests here (see :ref:`checkavocado-ref` for
-details about the Avocado tests).
The tests should be written in the style of the Python `unittest`_ framework,
using stdio for the TAP protocol. The folder ``tests/functional/qemu_test``
diff -Nru qemu-10.0.6+ds/docs/devel/testing/index.rst qemu-10.0.7+ds/docs/devel/testing/index.rst
--- qemu-10.0.6+ds/docs/devel/testing/index.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/index.rst 2025-12-06 17:54:23.000000000 +0300
@@ -10,7 +10,6 @@
main
qtest
functional
- avocado
acpi-bits
ci
fuzzing
diff -Nru qemu-10.0.6+ds/docs/devel/testing/main.rst qemu-10.0.7+ds/docs/devel/testing/main.rst
--- qemu-10.0.6+ds/docs/devel/testing/main.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/devel/testing/main.rst 2025-12-06 17:54:23.000000000 +0300
@@ -5,19 +5,32 @@
QEMU's testing infrastructure is fairly complex as it covers
everything from unit testing and exercising specific sub-systems all
-the way to full blown acceptance tests. To get an overview of the
+the way to full blown functional tests. To get an overview of the
tests you can run ``make check-help`` from either the source or build
tree.
-Most (but not all) tests are also integrated into the meson build
-system so can be run directly from the build tree, for example:
-
-.. code::
+Most (but not all) tests are also integrated as an automated test into
+the meson build system so can be run directly from the build tree,
+for example::
[./pyvenv/bin/]meson test --suite qemu:softfloat
will run just the softfloat tests.
+An automated test is written with one of the test frameworks using its
+generic test functions/classes. The test framework can run the tests and
+report their success or failure [1]_.
+
+An automated test has essentially three parts:
+
+1. The test initialization of the parameters, where the expected parameters,
+ like inputs and expected results, are set up;
+2. The call to the code that should be tested;
+3. An assertion, comparing the result from the previous call with the expected
+ result set during the initialization of the parameters. If the result
+ matches the expected result, the test has been successful; otherwise, it has
+ failed.
+
The rest of this document will cover the details for specific test
groups.
@@ -44,9 +57,17 @@
Unit tests
~~~~~~~~~~
-Unit tests, which can be invoked with ``make check-unit``, are simple C tests
-that typically link to individual QEMU object files and exercise them by
-calling exported functions.
+A unit test is responsible for exercising individual software components as a
+unit, like interfaces, data structures, and functionality, uncovering errors
+within the boundaries of a component. The verification effort is in the
+smallest software unit and focuses on the internal processing logic and data
+structures. A test case of unit tests should be designed to uncover errors
+due to erroneous computations, incorrect comparisons, or improper control
+flow [2]_.
+
+In QEMU, unit tests can be invoked with ``make check-unit``. They are
+simple C tests that typically link to individual QEMU object files and
+exercise them by calling exported functions.
If you are writing new code in QEMU, consider adding a unit test, especially
for utility modules that are relatively stateless or have few dependencies. To
@@ -885,6 +906,10 @@
Functional tests using Python
-----------------------------
+A functional test focuses on the functional requirement of the software,
+attempting to find errors like incorrect functions, interface errors,
+behavior errors, and initialization and termination errors [3]_.
+
The ``tests/functional`` directory hosts functional tests written in
Python. You can run the functional tests simply by executing:
@@ -894,21 +919,6 @@
See :ref:`checkfunctional-ref` for more details.
-Integration tests using the Avocado Framework
----------------------------------------------
-
-The ``tests/avocado`` directory hosts integration tests. They're usually
-higher level tests, and may interact with external resources and with
-various guest operating systems.
-
-You can run the avocado tests simply by executing:
-
-.. code::
-
- make check-avocado
-
-See :ref:`checkavocado-ref` for more details.
-
.. _checktcg-ref:
Testing with "make check-tcg"
@@ -1023,3 +1033,27 @@
Further analysis can be conducted by running the ``gcov`` command
directly on the various .gcda output files. Please read the ``gcov``
documentation for more information.
+
+Flaky tests
+-----------
+
+A flaky test is defined as a test that exhibits both a passing and a failing
+result with the same code on different runs. Some usual reasons for an
+intermittent/flaky test are async wait, concurrency, and test order dependency
+[4]_.
+
+In QEMU, tests that are identified to be flaky are normally disabled by
+default. Set the QEMU_TEST_FLAKY_TESTS environment variable before running
+the tests to enable them.
+
+References
+----------
+
+.. [1] Sommerville, Ian (2016). Software Engineering. p. 233.
+.. [2] Pressman, Roger S. & Maxim, Bruce R. (2020). Software Engineering,
+ A Practitioner’s Approach. p. 48, 376, 378, 381.
+.. [3] Pressman, Roger S. & Maxim, Bruce R. (2020). Software Engineering,
+ A Practitioner’s Approach. p. 388.
+.. [4] Luo, Qingzhou, et al. An empirical analysis of flaky tests.
+ Proceedings of the 22nd ACM SIGSOFT International Symposium on
+ Foundations of Software Engineering. 2014.
diff -Nru qemu-10.0.6+ds/docs/system/tls.rst qemu-10.0.7+ds/docs/system/tls.rst
--- qemu-10.0.6+ds/docs/system/tls.rst 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/docs/system/tls.rst 2025-12-06 17:54:23.000000000 +0300
@@ -118,7 +118,6 @@
ip_address = 2620:0:cafe::87
ip_address = 2001:24::92
tls_www_server
- encryption_key
signing_key
EOF
# certtool --generate-privkey > server-hostNNN-key.pem
@@ -134,9 +133,8 @@
the key purpose extension to indicate this certificate is intended for
usage in a web server. Although QEMU network services are not in fact
HTTP servers (except for VNC websockets), setting this key purpose is
-still recommended. The ``encryption_key`` and ``signing_key`` keyword is
-the key usage extension to indicate this certificate is intended for
-usage in the data session.
+still recommended. The ``signing_key`` keyword is the key usage extension
+to indicate this certificate is intended for usage in the data session.
The ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files
should now be securely copied to the server for which they were
@@ -171,7 +169,6 @@
organization = Name of your organization
cn = hostNNN.foo.example.com
tls_www_client
- encryption_key
signing_key
EOF
# certtool --generate-privkey > client-hostNNN-key.pem
@@ -187,9 +184,8 @@
``tls_www_client`` keyword is the key purpose extension to indicate this
certificate is intended for usage in a web client. Although QEMU network
clients are not in fact HTTP clients, setting this key purpose is still
-recommended. The ``encryption_key`` and ``signing_key`` keyword is the
-key usage extension to indicate this certificate is intended for usage
-in the data session.
+recommended. The ``signing_key`` keyword is the key usage extension to
+indicate this certificate is intended for usage in the data session.
The ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files
should now be securely copied to the client for which they were
@@ -222,7 +218,6 @@
ip_address = 2001:24::92
tls_www_server
tls_www_client
- encryption_key
signing_key
EOF
# certtool --generate-privkey > both-hostNNN-key.pem
diff -Nru qemu-10.0.6+ds/gdbstub/syscalls.c qemu-10.0.7+ds/gdbstub/syscalls.c
--- qemu-10.0.6+ds/gdbstub/syscalls.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/gdbstub/syscalls.c 2025-12-06 17:54:24.000000000 +0300
@@ -127,7 +127,7 @@
case 's':
i64 = va_arg(va, uint64_t);
i32 = va_arg(va, uint32_t);
- p += snprintf(p, p_end - p, "%" PRIx64 "/%x" PRIx32, i64, i32);
+ p += snprintf(p, p_end - p, "%" PRIx64 "/%" PRIx32, i64, i32);
break;
default:
bad_format:
diff -Nru qemu-10.0.6+ds/hw/arm/armv7m.c qemu-10.0.7+ds/hw/arm/armv7m.c
--- qemu-10.0.6+ds/hw/arm/armv7m.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/arm/armv7m.c 2025-12-06 17:54:24.000000000 +0300
@@ -442,6 +442,12 @@
&v7m_sysreg_ns_ops,
sysbus_mmio_get_region(sbd, 0),
"nvic_sysregs_ns", 0x1000);
+ /*
+ * This MR calls memory_region_dispatch_read/write to access the
+ * real region for the NVIC sysregs (which is also owned by this
+ * device), so reentrancy through here is expected and safe.
+ */
+ s->sysreg_ns_mem.disable_reentrancy_guard = true;
memory_region_add_subregion(&s->container, 0xe002e000,
&s->sysreg_ns_mem);
}
@@ -499,6 +505,12 @@
memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
&v7m_sysreg_ns_ops, &s->systickmem,
"v7m_systick_ns", 0xe0);
+ /*
+ * This MR calls memory_region_dispatch_read/write to access the
+ * real region for the systick regs (which is also owned by this
+ * device), so reentrancy through here is expected and safe.
+ */
+ s->systick_ns_mem.disable_reentrancy_guard = true;
memory_region_add_subregion_overlap(&s->container, 0xe002e010,
&s->systick_ns_mem, 1);
}
diff -Nru qemu-10.0.6+ds/hw/arm/aspeed_ast10x0.c qemu-10.0.7+ds/hw/arm/aspeed_ast10x0.c
--- qemu-10.0.6+ds/hw/arm/aspeed_ast10x0.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/arm/aspeed_ast10x0.c 2025-12-06 17:54:24.000000000 +0300
@@ -357,6 +357,8 @@
sc->memmap[ASPEED_DEV_SPI1 + i]);
aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ aspeed_soc_ast1030_get_irq(s, ASPEED_DEV_SPI1 + i));
}
/* Secure Boot Controller */
diff -Nru qemu-10.0.6+ds/hw/arm/aspeed_ast2600.c qemu-10.0.7+ds/hw/arm/aspeed_ast2600.c
--- qemu-10.0.6+ds/hw/arm/aspeed_ast2600.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/arm/aspeed_ast2600.c 2025-12-06 17:54:24.000000000 +0300
@@ -467,6 +467,8 @@
sc->memmap[ASPEED_DEV_SPI1 + i]);
aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_SPI1 + i));
}
/* EHCI */
diff -Nru qemu-10.0.6+ds/hw/arm/aspeed_ast27x0.c qemu-10.0.7+ds/hw/arm/aspeed_ast27x0.c
--- qemu-10.0.6+ds/hw/arm/aspeed_ast27x0.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/arm/aspeed_ast27x0.c 2025-12-06 17:54:24.000000000 +0300
@@ -709,6 +709,8 @@
sc->memmap[ASPEED_DEV_SPI0 + i]);
aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ aspeed_soc_ast2700_get_irq(s, ASPEED_DEV_SPI0 + i));
}
/*
diff -Nru qemu-10.0.6+ds/hw/core/machine.c qemu-10.0.7+ds/hw/core/machine.c
--- qemu-10.0.6+ds/hw/core/machine.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/core/machine.c 2025-12-06 17:54:24.000000000 +0300
@@ -1190,6 +1190,8 @@
object_class_property_add_bool(oc, "aux-ram-share",
machine_get_aux_ram_share,
machine_set_aux_ram_share);
+ object_class_property_set_description(oc, "aux-ram-share",
+ "Use anonymous shared memory for auxiliary guest RAMs");
#endif
object_class_property_add_bool(oc, "usb",
diff -Nru qemu-10.0.6+ds/hw/display/exynos4210_fimd.c qemu-10.0.7+ds/hw/display/exynos4210_fimd.c
--- qemu-10.0.6+ds/hw/display/exynos4210_fimd.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/display/exynos4210_fimd.c 2025-12-06 17:54:24.000000000 +0300
@@ -1147,6 +1147,13 @@
if (w->mem_section.mr) {
memory_region_set_log(w->mem_section.mr, false, DIRTY_MEMORY_VGA);
memory_region_unref(w->mem_section.mr);
+ w->mem_section.mr = NULL;
+ }
+
+ if (w->fb_len == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "FIMD: Guest config means framebuffer is zero length\n");
+ goto error_return;
}
w->mem_section = memory_region_find(s->fbmem, fb_start_addr, w->fb_len);
diff -Nru qemu-10.0.6+ds/hw/display/xlnx_dp.c qemu-10.0.7+ds/hw/display/xlnx_dp.c
--- qemu-10.0.6+ds/hw/display/xlnx_dp.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/display/xlnx_dp.c 2025-12-06 17:54:24.000000000 +0300
@@ -435,7 +435,18 @@
static void xlnx_dp_aux_push_rx_fifo(XlnxDPState *s, uint8_t *buf, size_t len)
{
+ size_t avail = fifo8_num_free(&s->rx_fifo);
DPRINTF("Push %u data in rx_fifo\n", (unsigned)len);
+ if (len > avail) {
+ /*
+ * Data sheet doesn't specify behaviour here: we choose to ignore
+ * the excess data.
+ */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: ignoring %zu bytes pushed to full RX_FIFO\n",
+ __func__, len - avail);
+ len = avail;
+ }
fifo8_push_all(&s->rx_fifo, buf, len);
}
@@ -466,7 +477,18 @@
static void xlnx_dp_aux_push_tx_fifo(XlnxDPState *s, uint8_t *buf, size_t len)
{
+ size_t avail = fifo8_num_free(&s->tx_fifo);
DPRINTF("Push %u data in tx_fifo\n", (unsigned)len);
+ if (len > avail) {
+ /*
+ * Data sheet doesn't specify behaviour here: we choose to ignore
+ * the excess data.
+ */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: ignoring %zu bytes pushed to full TX_FIFO\n",
+ __func__, len - avail);
+ len = avail;
+ }
fifo8_push_all(&s->tx_fifo, buf, len);
}
@@ -475,8 +497,10 @@
uint8_t ret;
if (fifo8_is_empty(&s->tx_fifo)) {
- error_report("%s: TX_FIFO underflow", __func__);
- abort();
+ /* Data sheet doesn't specify behaviour here: we choose to return 0 */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: attempt to read empty TX_FIFO\n",
+ __func__);
+ return 0;
}
ret = fifo8_pop(&s->tx_fifo);
DPRINTF("pop 0x%2.2X from tx_fifo.\n", ret);
@@ -641,14 +665,28 @@
case DP_GRAPHIC_BGR888:
s->g_plane.format = PIXMAN_b8g8r8;
break;
+ case DP_GRAPHIC_RGBA5551:
+ case DP_GRAPHIC_RGBA4444:
+ case DP_GRAPHIC_8BPP:
+ case DP_GRAPHIC_4BPP:
+ case DP_GRAPHIC_2BPP:
+ case DP_GRAPHIC_1BPP:
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented graphic format %u",
+ __func__,
+ s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK);
+ s->g_plane.format = PIXMAN_r8g8b8a8;
+ break;
default:
- error_report("%s: unsupported graphic format %u", __func__,
- s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK);
- abort();
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid graphic format %u",
+ __func__,
+ s->avbufm_registers[AV_BUF_FORMAT] & DP_GRAPHIC_MASK);
+ s->g_plane.format = PIXMAN_r8g8b8a8;
+ break;
}
switch (s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK) {
case 0:
+ /* This is DP_NL_VID_CB_Y0_CR_Y1 ??? */
s->v_plane.format = PIXMAN_x8b8g8r8;
break;
case DP_NL_VID_Y0_CB_Y1_CR:
@@ -657,10 +695,39 @@
case DP_NL_VID_RGBA8880:
s->v_plane.format = PIXMAN_x8b8g8r8;
break;
+ case DP_NL_VID_CR_Y0_CB_Y1:
+ case DP_NL_VID_Y0_CR_Y1_CB:
+ case DP_NL_VID_YV16:
+ case DP_NL_VID_YV24:
+ case DP_NL_VID_YV16CL:
+ case DP_NL_VID_MONO:
+ case DP_NL_VID_YV16CL2:
+ case DP_NL_VID_YUV444:
+ case DP_NL_VID_RGB888:
+ case DP_NL_VID_RGB888_10BPC:
+ case DP_NL_VID_YUV444_10BPC:
+ case DP_NL_VID_YV16CL2_10BPC:
+ case DP_NL_VID_YV16CL_10BPC:
+ case DP_NL_VID_YV16_10BPC:
+ case DP_NL_VID_YV24_10BPC:
+ case DP_NL_VID_Y_ONLY_10BPC:
+ case DP_NL_VID_YV16_420:
+ case DP_NL_VID_YV16CL_420:
+ case DP_NL_VID_YV16CL2_420:
+ case DP_NL_VID_YV16_420_10BPC:
+ case DP_NL_VID_YV16CL_420_10BPC:
+ case DP_NL_VID_YV16CL2_420_10BPC:
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented video format %u",
+ __func__,
+ s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK);
+ s->v_plane.format = PIXMAN_x8b8g8r8;
+ break;
default:
- error_report("%s: unsupported video format %u", __func__,
- s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK);
- abort();
+ qemu_log_mask(LOG_UNIMP, "%s: invalid video format %u",
+ __func__,
+ s->avbufm_registers[AV_BUF_FORMAT] & DP_NL_VID_FMT_MASK);
+ s->v_plane.format = PIXMAN_x8b8g8r8;
+ break;
}
xlnx_dp_recreate_surface(s);
diff -Nru qemu-10.0.6+ds/hw/dma/xlnx-zynq-devcfg.c qemu-10.0.7+ds/hw/dma/xlnx-zynq-devcfg.c
--- qemu-10.0.6+ds/hw/dma/xlnx-zynq-devcfg.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/dma/xlnx-zynq-devcfg.c 2025-12-06 17:54:24.000000000 +0300
@@ -372,7 +372,7 @@
s->regs_info, s->regs,
&xlnx_zynq_devcfg_reg_ops,
XLNX_ZYNQ_DEVCFG_ERR_DEBUG,
- XLNX_ZYNQ_DEVCFG_R_MAX);
+ XLNX_ZYNQ_DEVCFG_R_MAX * 4);
memory_region_add_subregion(&s->iomem,
A_CTRL,
®_array->mem);
diff -Nru qemu-10.0.6+ds/hw/hppa/machine.c qemu-10.0.7+ds/hw/hppa/machine.c
--- qemu-10.0.6+ds/hw/hppa/machine.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/hppa/machine.c 2025-12-06 17:54:24.000000000 +0300
@@ -573,7 +573,7 @@
/* Parallel port */
parallel_mm_init(addr_space, translate(NULL, LASI_LPT_HPA + 0x800), 0,
- qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
+ qdev_get_gpio_in(lasi_dev, LASI_IRQ_LPT_HPA),
parallel_hds[0]);
/* PS/2 Keyboard/Mouse */
diff -Nru qemu-10.0.6+ds/hw/i386/pc.c qemu-10.0.7+ds/hw/i386/pc.c
--- qemu-10.0.6+ds/hw/i386/pc.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/i386/pc.c 2025-12-06 17:54:24.000000000 +0300
@@ -840,6 +840,7 @@
hwaddr maxphysaddr, maxusedaddr;
hwaddr cxl_base, cxl_resv_end = 0;
X86CPU *cpu = X86_CPU(first_cpu);
+ uint64_t res_mem_end;
assert(machine->ram_size == x86ms->below_4g_mem_size +
x86ms->above_4g_mem_size);
@@ -993,17 +994,19 @@
rom_set_fw(fw_cfg);
- if (machine->device_memory) {
- uint64_t *val = g_malloc(sizeof(*val));
- uint64_t res_mem_end = machine->device_memory->base;
-
+ if (pcms->cxl_devices_state.is_enabled) {
+ res_mem_end = cxl_resv_end;
+ } else if (machine->device_memory) {
+ res_mem_end = machine->device_memory->base;
if (!pcmc->broken_reserved_end) {
res_mem_end += memory_region_size(&machine->device_memory->mr);
}
+ } else {
+ res_mem_end = 0;
+ }
- if (pcms->cxl_devices_state.is_enabled) {
- res_mem_end = cxl_resv_end;
- }
+ if (res_mem_end) {
+ uint64_t *val = g_malloc(sizeof(*val));
*val = cpu_to_le64(ROUND_UP(res_mem_end, 1 * GiB));
fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
}
diff -Nru qemu-10.0.6+ds/hw/i386/x86-common.c qemu-10.0.7+ds/hw/i386/x86-common.c
--- qemu-10.0.6+ds/hw/i386/x86-common.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/i386/x86-common.c 2025-12-06 17:54:24.000000000 +0300
@@ -182,6 +182,17 @@
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
}
+ /*
+ * Non-hotplugged CPUs get their SMM cpu address space initialized in
+ * machine init done notifier: register_smram_listener().
+ *
+ * We need initialize the SMM cpu address space for the hotplugged CPU
+ * specifically.
+ */
+ if (kvm_enabled() && dev->hotplugged && x86_machine_is_smm_enabled(x86ms)) {
+ kvm_smm_cpu_address_space_init(cpu);
+ }
+
found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL);
found_cpu->cpu = CPU(dev);
out:
diff -Nru qemu-10.0.6+ds/hw/intc/riscv_aplic.c qemu-10.0.7+ds/hw/intc/riscv_aplic.c
--- qemu-10.0.6+ds/hw/intc/riscv_aplic.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/intc/riscv_aplic.c 2025-12-06 17:54:24.000000000 +0300
@@ -96,7 +96,7 @@
(APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \
APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs))
-#define APLIC_xMSICFGADDRH_VALID_MASK \
+#define APLIC_MMSICFGADDRH_VALID_MASK \
(APLIC_xMSICFGADDRH_L | \
(APLIC_xMSICFGADDRH_HHXS_MASK << APLIC_xMSICFGADDRH_HHXS_SHIFT) | \
(APLIC_xMSICFGADDRH_LHXS_MASK << APLIC_xMSICFGADDRH_LHXS_SHIFT) | \
@@ -104,6 +104,10 @@
(APLIC_xMSICFGADDRH_LHXW_MASK << APLIC_xMSICFGADDRH_LHXW_SHIFT) | \
APLIC_xMSICFGADDRH_BAPPN_MASK)
+#define APLIC_SMSICFGADDRH_VALID_MASK \
+ ((APLIC_xMSICFGADDRH_LHXS_MASK << APLIC_xMSICFGADDRH_LHXS_SHIFT) | \
+ APLIC_xMSICFGADDRH_BAPPN_MASK)
+
#define APLIC_SETIP_BASE 0x1c00
#define APLIC_SETIPNUM 0x1cdc
@@ -184,7 +188,7 @@
addr >>= APLIC_xMSICFGADDR_PPN_SHIFT;
aplic->kvm_msicfgaddr = extract64(addr, 0, 32);
aplic->kvm_msicfgaddrH = extract64(addr, 32, 32) &
- APLIC_xMSICFGADDRH_VALID_MASK;
+ APLIC_MMSICFGADDRH_VALID_MASK;
}
#endif
}
@@ -409,13 +413,8 @@
msicfgaddr = aplic->kvm_msicfgaddr;
msicfgaddrH = ((uint64_t)aplic->kvm_msicfgaddrH << 32);
} else {
- if (aplic->mmode) {
- msicfgaddr = aplic_m->mmsicfgaddr;
- msicfgaddrH = aplic_m->mmsicfgaddrH;
- } else {
- msicfgaddr = aplic_m->smsicfgaddr;
- msicfgaddrH = aplic_m->smsicfgaddrH;
- }
+ msicfgaddr = aplic_m->mmsicfgaddr;
+ msicfgaddrH = aplic_m->mmsicfgaddrH;
}
lhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXS_SHIFT) &
@@ -427,6 +426,14 @@
hhxw = (msicfgaddrH >> APLIC_xMSICFGADDRH_HHXW_SHIFT) &
APLIC_xMSICFGADDRH_HHXW_MASK;
+ if (!aplic->kvm_splitmode && !aplic->mmode) {
+ msicfgaddrH = aplic_m->smsicfgaddrH;
+ msicfgaddr = aplic_m->smsicfgaddr;
+
+ lhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXS_SHIFT) &
+ APLIC_xMSICFGADDRH_LHXS_MASK;
+ }
+
group_idx = hart_idx >> lhxw;
addr = msicfgaddr;
@@ -771,7 +778,7 @@
} else if (aplic->mmode && aplic->msimode &&
(addr == APLIC_MMSICFGADDRH)) {
if (!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
- aplic->mmsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
+ aplic->mmsicfgaddrH = value & APLIC_MMSICFGADDRH_VALID_MASK;
}
} else if (aplic->mmode && aplic->msimode &&
(addr == APLIC_SMSICFGADDR)) {
@@ -792,7 +799,7 @@
(addr == APLIC_SMSICFGADDRH)) {
if (aplic->num_children &&
!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
- aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
+ aplic->smsicfgaddrH = value & APLIC_SMSICFGADDRH_VALID_MASK;
}
} else if ((APLIC_SETIP_BASE <= addr) &&
(addr < (APLIC_SETIP_BASE + aplic->bitfield_words * 4))) {
diff -Nru qemu-10.0.6+ds/hw/misc/aspeed_xdma.c qemu-10.0.7+ds/hw/misc/aspeed_xdma.c
--- qemu-10.0.6+ds/hw/misc/aspeed_xdma.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/misc/aspeed_xdma.c 2025-12-06 17:54:24.000000000 +0300
@@ -113,7 +113,7 @@
static const MemoryRegionOps aspeed_xdma_ops = {
.read = aspeed_xdma_read,
.write = aspeed_xdma_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
};
diff -Nru qemu-10.0.6+ds/hw/misc/npcm_clk.c qemu-10.0.7+ds/hw/misc/npcm_clk.c
--- qemu-10.0.6+ds/hw/misc/npcm_clk.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/misc/npcm_clk.c 2025-12-06 17:54:24.000000000 +0300
@@ -212,13 +212,14 @@
{
NPCM7xxClockPLLState *s = opaque;
uint32_t con = s->clk->regs[s->reg];
- uint64_t freq;
+ uint64_t freq, freq_div;
/* The PLL is grounded if it is not locked yet. */
if (con & PLLCON_LOKI) {
freq = clock_get_hz(s->clock_in);
freq *= PLLCON_FBDV(con);
- freq /= PLLCON_INDV(con) * PLLCON_OTDV1(con) * PLLCON_OTDV2(con);
+ freq_div = PLLCON_INDV(con) * PLLCON_OTDV1(con) * PLLCON_OTDV2(con);
+ freq = freq_div ? freq / freq_div : 0;
} else {
freq = 0;
}
diff -Nru qemu-10.0.6+ds/hw/net/e1000e_core.c qemu-10.0.7+ds/hw/net/e1000e_core.c
--- qemu-10.0.6+ds/hw/net/e1000e_core.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/net/e1000e_core.c 2025-12-06 17:54:24.000000000 +0300
@@ -1392,10 +1392,13 @@
dma_addr_t data_len)
{
while (data_len > 0) {
- uint32_t cur_buf_len = core->rxbuf_sizes[bastate->cur_idx];
- uint32_t cur_buf_bytes_left = cur_buf_len -
- bastate->written[bastate->cur_idx];
- uint32_t bytes_to_write = MIN(data_len, cur_buf_bytes_left);
+ uint32_t cur_buf_len, cur_buf_bytes_left, bytes_to_write;
+
+ assert(bastate->cur_idx < MAX_PS_BUFFERS);
+
+ cur_buf_len = core->rxbuf_sizes[bastate->cur_idx];
+ cur_buf_bytes_left = cur_buf_len - bastate->written[bastate->cur_idx];
+ bytes_to_write = MIN(data_len, cur_buf_bytes_left);
trace_e1000e_rx_desc_buff_write(bastate->cur_idx,
ba[bastate->cur_idx],
@@ -1414,8 +1417,6 @@
if (bastate->written[bastate->cur_idx] == cur_buf_len) {
bastate->cur_idx++;
}
-
- assert(bastate->cur_idx < MAX_PS_BUFFERS);
}
}
@@ -1481,7 +1482,6 @@
PCIDevice *d = core->owner;
dma_addr_t base;
union e1000_rx_desc_union desc;
- size_t desc_size;
size_t desc_offset = 0;
size_t iov_ofs = 0;
@@ -1496,16 +1496,17 @@
rxi = rxr->i;
do {
+ /*
+ * Loop processing descriptors while we have packet data to
+ * DMA to the guest. desc_offset tracks how much data we have
+ * sent to the guest in total over all descriptors, and goes
+ * from 0 up to total_size (the size of everything to send to
+ * the guest including possible trailing 4 bytes of CRC data).
+ */
hwaddr ba[MAX_PS_BUFFERS];
E1000EBAState bastate = { { 0 } };
bool is_last = false;
- desc_size = total_size - desc_offset;
-
- if (desc_size > core->rx_desc_buf_size) {
- desc_size = core->rx_desc_buf_size;
- }
-
if (e1000e_ring_empty(core, rxi)) {
return;
}
@@ -1519,17 +1520,27 @@
e1000e_read_rx_descr(core, &desc, ba);
if (ba[0]) {
+ /* Total amount of data DMA'd to the guest in this iteration */
+ size_t desc_size = 0;
+ /*
+ * Total space available in this descriptor (we will update
+ * this as we use it up)
+ */
+ size_t rx_desc_buf_size = core->rx_desc_buf_size;
+
if (desc_offset < size) {
- static const uint32_t fcs_pad;
size_t iov_copy;
+ /* Amount of data to copy from the incoming packet */
size_t copy_size = size - desc_offset;
- if (copy_size > core->rx_desc_buf_size) {
- copy_size = core->rx_desc_buf_size;
- }
/* For PS mode copy the packet header first */
if (do_ps) {
if (is_first) {
+ /*
+ * e1000e_do_ps() guarantees that buffer 0 has enough
+ * space for the header; otherwise we will not split
+ * the packet (i.e. do_ps is false).
+ */
size_t ps_hdr_copied = 0;
do {
iov_copy = MIN(ps_hdr_len - ps_hdr_copied,
@@ -1551,13 +1562,25 @@
} while (ps_hdr_copied < ps_hdr_len);
is_first = false;
+ desc_size += ps_hdr_len;
} else {
/* Leave buffer 0 of each descriptor except first */
/* empty as per spec 7.1.5.1 */
e1000e_write_hdr_frag_to_rx_buffers(core, ba, &bastate,
NULL, 0);
}
+ rx_desc_buf_size -= core->rxbuf_sizes[0];
+ }
+
+ /*
+ * Clamp the amount of packet data we copy into what will fit
+ * into the remaining buffers in the descriptor.
+ */
+ if (copy_size > rx_desc_buf_size) {
+ copy_size = rx_desc_buf_size;
}
+ desc_size += copy_size;
+ rx_desc_buf_size -= copy_size;
/* Copy packet payload */
while (copy_size) {
@@ -1575,20 +1598,30 @@
iov_ofs = 0;
}
}
+ }
- if (desc_offset + desc_size >= total_size) {
- /* Simulate FCS checksum presence in the last descriptor */
- e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
- (const char *) &fcs_pad, e1000x_fcs_len(core->mac));
- }
+ if (rx_desc_buf_size &&
+ desc_offset >= size && desc_offset < total_size) {
+ /*
+ * We are in the last 4 bytes corresponding to the FCS checksum.
+ * We only ever write zeroes here (unlike the hardware).
+ */
+ static const uint32_t fcs_pad;
+ /* Amount of space for the trailing checksum */
+ size_t fcs_len = MIN(rx_desc_buf_size,
+ total_size - desc_offset);
+ e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
+ (const char *)&fcs_pad,
+ fcs_len);
+ desc_size += fcs_len;
+ }
+ desc_offset += desc_size;
+ if (desc_offset >= total_size) {
+ is_last = true;
}
} else { /* as per intel docs; skip descriptors with null buf addr */
trace_e1000e_rx_null_descriptor();
}
- desc_offset += desc_size;
- if (desc_offset >= total_size) {
- is_last = true;
- }
e1000e_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
diff -Nru qemu-10.0.6+ds/hw/nvram/ds1225y.c qemu-10.0.7+ds/hw/nvram/ds1225y.c
--- qemu-10.0.6+ds/hw/nvram/ds1225y.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/nvram/ds1225y.c 2025-12-06 17:54:24.000000000 +0300
@@ -126,7 +126,7 @@
s->contents = g_malloc0(s->chip_size);
- memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s,
+ memory_region_init_io(&s->iomem, OBJECT(dev), &nvram_ops, s,
"nvram", s->chip_size);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
diff -Nru qemu-10.0.6+ds/hw/pci/msix.c qemu-10.0.7+ds/hw/pci/msix.c
--- qemu-10.0.6+ds/hw/pci/msix.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/pci/msix.c 2025-12-06 17:54:24.000000000 +0300
@@ -318,7 +318,7 @@
* also means a programming error, except device assignment, which can check
* if a real HW is broken.
*/
-int msix_init(struct PCIDevice *dev, unsigned short nentries,
+int msix_init(struct PCIDevice *dev, uint32_t nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos,
@@ -392,7 +392,7 @@
return 0;
}
-int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
+int msix_init_exclusive_bar(PCIDevice *dev, uint32_t nentries,
uint8_t bar_nr, Error **errp)
{
int ret;
@@ -401,6 +401,12 @@
uint32_t bar_pba_offset = bar_size / 2;
uint32_t bar_pba_size = QEMU_ALIGN_UP(nentries, 64) / 8;
+ /* Sanity-check nentries before we use it in BAR size calculations */
+ if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) {
+ error_setg(errp, "The number of MSI-X vectors is invalid");
+ return -EINVAL;
+ }
+
/*
* Migration compatibility dictates that this remains a 4k
* BAR with the vector table in the lower half and PBA in
diff -Nru qemu-10.0.6+ds/hw/pci-host/gpex-acpi.c qemu-10.0.7+ds/hw/pci-host/gpex-acpi.c
--- qemu-10.0.6+ds/hw/pci-host/gpex-acpi.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/pci-host/gpex-acpi.c 2025-12-06 17:54:24.000000000 +0300
@@ -114,7 +114,7 @@
UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
ifctx = aml_if(aml_equal(aml_arg(0), UUID));
ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
- uint8_t byte_list[1] = {1};
+ uint8_t byte_list[1] = {0};
buf = aml_buffer(1, byte_list);
aml_append(ifctx1, aml_return(buf));
aml_append(ifctx, ifctx1);
diff -Nru qemu-10.0.6+ds/hw/ppc/e500.c qemu-10.0.7+ds/hw/ppc/e500.c
--- qemu-10.0.6+ds/hw/ppc/e500.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/ppc/e500.c 2025-12-06 17:54:24.000000000 +0300
@@ -19,6 +19,7 @@
#include "qemu/units.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"
+#include "cpu-models.h"
#include "e500.h"
#include "e500-ccsr.h"
#include "net/net.h"
@@ -942,9 +943,8 @@
env = &cpu->env;
cs = CPU(cpu);
- if (env->mmu_model != POWERPC_MMU_BOOKE206) {
- error_report("MMU model %i not supported by this machine",
- env->mmu_model);
+ if (!(POWERPC_CPU_GET_CLASS(cpu)->svr & POWERPC_SVR_E500)) {
+ error_report("This machine needs a CPU from the e500 family");
exit(1);
}
diff -Nru qemu-10.0.6+ds/hw/riscv/sifive_u.c qemu-10.0.7+ds/hw/riscv/sifive_u.c
--- qemu-10.0.6+ds/hw/riscv/sifive_u.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/riscv/sifive_u.c 2025-12-06 17:54:24.000000000 +0300
@@ -176,7 +176,7 @@
if (is_32_bit) {
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
} else {
- qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+ qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv39");
}
riscv_isa_write_fdt(&s->soc.u_cpus.harts[cpu - 1], fdt, nodename);
} else {
diff -Nru qemu-10.0.6+ds/hw/rtc/aspeed_rtc.c qemu-10.0.7+ds/hw/rtc/aspeed_rtc.c
--- qemu-10.0.6+ds/hw/rtc/aspeed_rtc.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/rtc/aspeed_rtc.c 2025-12-06 17:54:24.000000000 +0300
@@ -131,7 +131,7 @@
static const MemoryRegionOps aspeed_rtc_ops = {
.read = aspeed_rtc_read,
.write = aspeed_rtc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static const VMStateDescription vmstate_aspeed_rtc = {
diff -Nru qemu-10.0.6+ds/hw/scsi/esp.c qemu-10.0.7+ds/hw/scsi/esp.c
--- qemu-10.0.6+ds/hw/scsi/esp.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/scsi/esp.c 2025-12-06 17:54:24.000000000 +0300
@@ -447,7 +447,9 @@
static bool esp_cdb_ready(ESPState *s)
{
- int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
+ /* scsi_cdb_length() only reads the first byte */
+ int limit = s->cmdfifo_cdb_offset + 1;
+ int len = fifo8_num_used(&s->cmdfifo);
const uint8_t *pbuf;
uint32_t n;
int cdblen;
@@ -457,7 +459,7 @@
}
pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
- if (n < len) {
+ if (n < limit) {
/*
* In normal use the cmdfifo should never wrap, but include this check
* to prevent a malicious guest from reading past the end of the
diff -Nru qemu-10.0.6+ds/hw/scsi/virtio-scsi.c qemu-10.0.7+ds/hw/scsi/virtio-scsi.c
--- qemu-10.0.6+ds/hw/scsi/virtio-scsi.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/scsi/virtio-scsi.c 2025-12-06 17:54:24.000000000 +0300
@@ -343,6 +343,7 @@
SCSIDevice *d = virtio_scsi_device_get(s, tmf->req.tmf.lun);
SCSIRequest *r;
bool match_tag;
+ g_autoptr(GList) reqs = NULL;
if (!d) {
tmf->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
@@ -378,10 +379,21 @@
if (match_tag && cmd_req->req.cmd.tag != tmf->req.tmf.tag) {
continue;
}
- virtio_scsi_tmf_cancel_req(tmf, r);
+ /*
+ * Cannot cancel directly, because scsi_req_dequeue() would deadlock
+ * when attempting to acquire the request_lock a second time. Taking
+ * a reference here is paired with an unref after cancelling below.
+ */
+ scsi_req_ref(r);
+ reqs = g_list_prepend(reqs, r);
}
}
+ for (GList *elem = g_list_first(reqs); elem; elem = g_list_next(elem)) {
+ virtio_scsi_tmf_cancel_req(tmf, elem->data);
+ scsi_req_unref(elem->data);
+ }
+
/* Incremented by virtio_scsi_do_tmf() */
virtio_scsi_tmf_dec_remaining(tmf);
diff -Nru qemu-10.0.6+ds/hw/sd/aspeed_sdhci.c qemu-10.0.7+ds/hw/sd/aspeed_sdhci.c
--- qemu-10.0.6+ds/hw/sd/aspeed_sdhci.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/sd/aspeed_sdhci.c 2025-12-06 17:54:24.000000000 +0300
@@ -124,7 +124,7 @@
static const MemoryRegionOps aspeed_sdhci_ops = {
.read = aspeed_sdhci_read,
.write = aspeed_sdhci_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
};
diff -Nru qemu-10.0.6+ds/hw/virtio/vhost-user.c qemu-10.0.7+ds/hw/virtio/vhost-user.c
--- qemu-10.0.6+ds/hw/virtio/vhost-user.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/virtio/vhost-user.c 2025-12-06 17:54:24.000000000 +0300
@@ -1670,14 +1670,6 @@
return !qio_channel_writev_all(ioc, iov, ARRAY_SIZE(iov), errp);
}
-static bool
-vhost_user_backend_send_dmabuf_fd(QIOChannel *ioc, VhostUserHeader *hdr,
- VhostUserPayload *payload, Error **errp)
-{
- hdr->size = sizeof(payload->u64);
- return vhost_user_send_resp(ioc, hdr, payload, errp);
-}
-
int vhost_user_get_shared_object(struct vhost_dev *dev, unsigned char *uuid,
int *dmabuf_fd)
{
@@ -1718,19 +1710,15 @@
static int
vhost_user_backend_handle_shared_object_lookup(struct vhost_user *u,
- QIOChannel *ioc,
- VhostUserHeader *hdr,
- VhostUserPayload *payload)
+ VhostUserShared *object)
{
QemuUUID uuid;
CharBackend *chr = u->user->chr;
- Error *local_err = NULL;
int dmabuf_fd = -1;
int fd_num = 0;
- memcpy(uuid.data, payload->object.uuid, sizeof(payload->object.uuid));
+ memcpy(uuid.data, object->uuid, sizeof(object->uuid));
- payload->u64 = 0;
switch (virtio_object_type(&uuid)) {
case TYPE_DMABUF:
dmabuf_fd = virtio_lookup_dmabuf(&uuid);
@@ -1739,18 +1727,16 @@
{
struct vhost_dev *dev = virtio_lookup_vhost_device(&uuid);
if (dev == NULL) {
- payload->u64 = -EINVAL;
- break;
+ return -EINVAL;
}
int ret = vhost_user_get_shared_object(dev, uuid.data, &dmabuf_fd);
if (ret < 0) {
- payload->u64 = ret;
+ return ret;
}
break;
}
case TYPE_INVALID:
- payload->u64 = -EINVAL;
- break;
+ return -EINVAL;
}
if (dmabuf_fd != -1) {
@@ -1759,11 +1745,6 @@
if (qemu_chr_fe_set_msgfds(chr, &dmabuf_fd, fd_num) < 0) {
error_report("Failed to set msg fds.");
- payload->u64 = -EINVAL;
- }
-
- if (!vhost_user_backend_send_dmabuf_fd(ioc, hdr, payload, &local_err)) {
- error_report_err(local_err);
return -EINVAL;
}
@@ -1792,6 +1773,7 @@
struct iovec iov;
g_autofree int *fd = NULL;
size_t fdsize = 0;
+ bool reply_ack;
int i;
/* Read header */
@@ -1810,6 +1792,8 @@
goto err;
}
+ reply_ack = hdr.flags & VHOST_USER_NEED_REPLY_MASK;
+
/* Read payload */
if (qio_channel_read_all(ioc, (char *) &payload, hdr.size, &local_err)) {
error_report_err(local_err);
@@ -1835,8 +1819,10 @@
&payload.object);
break;
case VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP:
- ret = vhost_user_backend_handle_shared_object_lookup(dev->opaque, ioc,
- &hdr, &payload);
+ /* The backend always expects a response */
+ reply_ack = true;
+ ret = vhost_user_backend_handle_shared_object_lookup(dev->opaque,
+ &payload.object);
break;
default:
error_report("Received unexpected msg type: %d.", hdr.request);
@@ -1847,7 +1833,7 @@
* REPLY_ACK feature handling. Other reply types has to be managed
* directly in their request handlers.
*/
- if (hdr.flags & VHOST_USER_NEED_REPLY_MASK) {
+ if (reply_ack) {
payload.u64 = !!ret;
hdr.size = sizeof(payload.u64);
diff -Nru qemu-10.0.6+ds/hw/virtio/virtio-qmp.c qemu-10.0.7+ds/hw/virtio/virtio-qmp.c
--- qemu-10.0.6+ds/hw/virtio/virtio-qmp.c 2025-10-20 21:13:45.000000000 +0300
+++ qemu-10.0.7+ds/hw/virtio/virtio-qmp.c 2025-12-06 17:54:24.000000000 +0300
@@ -299,7 +299,7 @@
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO4, \
"VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv4"),
FEATURE_ENTRY(VIRTIO_NET_F_GUEST_USO6, \
- "VIRTIO_NET_F_GUEST_USO4: Driver can receive USOv6"),
+ "VIRTIO_NET_F_GUEST_USO6: Driver can receive USOv6"),
FEATURE_ENTRY(VIRTIO_NET_F_HOST_USO, \
"VIRTIO_NET_F_HOST_USO: Device can receive USO"),
FEATURE_ENTRY(VIRTIO_NET_F_HASH_REPORT, \
diff -Nru qemu-10.0.6+ds/include/hw/misc/lasi.h qemu-10.0.7+ds/include/hw/misc/lasi.h
--- qemu-10.0.6+ds/include/hw/misc/lasi.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/include/hw/misc/lasi.h 2025-12-06 17:54:24.000000000 +0300
@@ -13,8 +13,8 @@
#define LASI_H
#include "exec/address-spaces.h"
-#include "hw/pci/pci_host.h"
#include "hw/boards.h"
+#include "hw/sysbus.h"
#define TYPE_LASI_CHIP "lasi-chip"
OBJECT_DECLARE_SIMPLE_TYPE(LasiState, LASI_CHIP)
@@ -61,7 +61,7 @@
#define LASI_IRQ_PS2MOU_HPA 26
struct LasiState {
- PCIHostState parent_obj;
+ SysBusDevice parent_obj;
uint32_t irr;
uint32_t imr;
diff -Nru qemu-10.0.6+ds/include/hw/pci/msix.h qemu-10.0.7+ds/include/hw/pci/msix.h
--- qemu-10.0.6+ds/include/hw/pci/msix.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/include/hw/pci/msix.h 2025-12-06 17:54:24.000000000 +0300
@@ -7,12 +7,12 @@
void msix_set_message(PCIDevice *dev, int vector, MSIMessage msg);
MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector);
-int msix_init(PCIDevice *dev, unsigned short nentries,
+int msix_init(PCIDevice *dev, uint32_t nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos,
Error **errp);
-int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
+int msix_init_exclusive_bar(PCIDevice *dev, uint32_t nentries,
uint8_t bar_nr, Error **errp);
void msix_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len);
diff -Nru qemu-10.0.6+ds/include/io/channel-websock.h qemu-10.0.7+ds/include/io/channel-websock.h
--- qemu-10.0.6+ds/include/io/channel-websock.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/include/io/channel-websock.h 2025-12-06 17:54:24.000000000 +0300
@@ -61,7 +61,8 @@
size_t payload_remain;
size_t pong_remain;
QIOChannelWebsockMask mask;
- guint io_tag;
+ guint hs_io_tag; /* tracking handshake task */
+ guint io_tag; /* tracking watch task */
Error *io_err;
gboolean io_eof;
uint8_t opcode;
diff -Nru qemu-10.0.6+ds/include/io/net-listener.h qemu-10.0.7+ds/include/io/net-listener.h
--- qemu-10.0.6+ds/include/io/net-listener.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/include/io/net-listener.h 2025-12-06 17:54:24.000000000 +0300
@@ -50,9 +50,11 @@
QIOChannelSocket **sioc;
GSource **io_source;
size_t nsioc;
+ GMainContext *context;
bool connected;
+ QemuMutex lock; /* Protects remaining fields */
QIONetListenerClientFunc io_func;
gpointer io_data;
GDestroyNotify io_notify;
diff -Nru qemu-10.0.6+ds/io/channel-tls.c qemu-10.0.7+ds/io/channel-tls.c
--- qemu-10.0.6+ds/io/channel-tls.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/io/channel-tls.c 2025-12-06 17:54:24.000000000 +0300
@@ -337,6 +337,16 @@
{
QIOChannelTLS *ioc = QIO_CHANNEL_TLS(obj);
+ if (ioc->hs_ioc_tag) {
+ trace_qio_channel_tls_handshake_cancel(ioc);
+ g_clear_handle_id(&ioc->hs_ioc_tag, g_source_remove);
+ }
+
+ if (ioc->bye_ioc_tag) {
+ trace_qio_channel_tls_bye_cancel(ioc);
+ g_clear_handle_id(&ioc->bye_ioc_tag, g_source_remove);
+ }
+
object_unref(OBJECT(ioc->master));
qcrypto_tls_session_free(ioc->session);
}
diff -Nru qemu-10.0.6+ds/io/channel-websock.c qemu-10.0.7+ds/io/channel-websock.c
--- qemu-10.0.6+ds/io/channel-websock.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/io/channel-websock.c 2025-12-06 17:54:24.000000000 +0300
@@ -545,6 +545,7 @@
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
+ wioc->hs_io_tag = 0;
return FALSE;
}
@@ -560,6 +561,7 @@
trace_qio_channel_websock_handshake_complete(ioc);
qio_task_complete(task);
}
+ wioc->hs_io_tag = 0;
return FALSE;
}
trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);
@@ -586,6 +588,7 @@
trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
qio_task_set_error(task, err);
qio_task_complete(task);
+ wioc->hs_io_tag = 0;
return FALSE;
}
if (ret == 0) {
@@ -597,7 +600,7 @@
error_propagate(&wioc->io_err, err);
trace_qio_channel_websock_handshake_reply(ioc);
- qio_channel_add_watch(
+ wioc->hs_io_tag = qio_channel_add_watch(
wioc->master,
G_IO_OUT,
qio_channel_websock_handshake_send,
@@ -907,11 +910,12 @@
trace_qio_channel_websock_handshake_start(ioc);
trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
- qio_channel_add_watch(ioc->master,
- G_IO_IN,
- qio_channel_websock_handshake_io,
- task,
- NULL);
+ ioc->hs_io_tag = qio_channel_add_watch(
+ ioc->master,
+ G_IO_IN,
+ qio_channel_websock_handshake_io,
+ task,
+ NULL);
}
@@ -922,13 +926,16 @@
buffer_free(&ioc->encinput);
buffer_free(&ioc->encoutput);
buffer_free(&ioc->rawinput);
- object_unref(OBJECT(ioc->master));
+ if (ioc->hs_io_tag) {
+ g_source_remove(ioc->hs_io_tag);
+ }
if (ioc->io_tag) {
g_source_remove(ioc->io_tag);
}
if (ioc->io_err) {
error_free(ioc->io_err);
}
+ object_unref(OBJECT(ioc->master));
}
@@ -1219,6 +1226,18 @@
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
trace_qio_channel_websock_close(ioc);
+ buffer_free(&wioc->encinput);
+ buffer_free(&wioc->encoutput);
+ buffer_free(&wioc->rawinput);
+ if (wioc->hs_io_tag) {
+ g_clear_handle_id(&wioc->hs_io_tag, g_source_remove);
+ }
+ if (wioc->io_tag) {
+ g_clear_handle_id(&wioc->io_tag, g_source_remove);
+ }
+ if (wioc->io_err) {
+ g_clear_pointer(&wioc->io_err, error_free);
+ }
return qio_channel_close(wioc->master, errp);
}
diff -Nru qemu-10.0.6+ds/io/net-listener.c qemu-10.0.7+ds/io/net-listener.c
--- qemu-10.0.6+ds/io/net-listener.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/io/net-listener.c 2025-12-06 17:54:24.000000000 +0300
@@ -23,10 +23,16 @@
#include "io/dns-resolver.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "qemu/lockable.h"
+#include "trace.h"
QIONetListener *qio_net_listener_new(void)
{
- return QIO_NET_LISTENER(object_new(TYPE_QIO_NET_LISTENER));
+ QIONetListener *listener;
+
+ listener = QIO_NET_LISTENER(object_new(TYPE_QIO_NET_LISTENER));
+ qemu_mutex_init(&listener->lock);
+ return listener;
}
void qio_net_listener_set_name(QIONetListener *listener,
@@ -43,6 +49,9 @@
{
QIONetListener *listener = QIO_NET_LISTENER(opaque);
QIOChannelSocket *sioc;
+ QIONetListenerClientFunc io_func;
+ gpointer io_data;
+ GMainContext *context;
sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
NULL);
@@ -50,8 +59,15 @@
return TRUE;
}
- if (listener->io_func) {
- listener->io_func(listener, sioc, listener->io_data);
+ WITH_QEMU_LOCK_GUARD(&listener->lock) {
+ io_func = listener->io_func;
+ io_data = listener->io_data;
+ context = listener->context;
+ }
+
+ trace_qio_net_listener_callback(listener, io_func, context);
+ if (io_func) {
+ io_func(listener, sioc, io_data);
}
object_unref(OBJECT(sioc));
@@ -108,6 +124,9 @@
void qio_net_listener_add(QIONetListener *listener,
QIOChannelSocket *sioc)
{
+ QIONetListenerClientFunc io_func;
+ GMainContext *context;
+
if (listener->name) {
qio_channel_set_name(QIO_CHANNEL(sioc), listener->name);
}
@@ -123,12 +142,18 @@
object_ref(OBJECT(sioc));
listener->connected = true;
- if (listener->io_func != NULL) {
+ WITH_QEMU_LOCK_GUARD(&listener->lock) {
+ io_func = listener->io_func;
+ context = listener->context;
+ }
+
+ trace_qio_net_listener_watch(listener, io_func, context, "add");
+ if (io_func) {
object_ref(OBJECT(listener));
listener->io_source[listener->nsioc] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[listener->nsioc]), G_IO_IN,
qio_net_listener_channel_func,
- listener, (GDestroyNotify)object_unref, NULL);
+ listener, (GDestroyNotify)object_unref, context);
}
listener->nsioc++;
@@ -143,12 +168,9 @@
{
size_t i;
- if (listener->io_notify) {
- listener->io_notify(listener->io_data);
- }
- listener->io_func = func;
- listener->io_data = data;
- listener->io_notify = notify;
+ QEMU_LOCK_GUARD(&listener->lock);
+ trace_qio_net_listener_unwatch(listener, listener->io_func,
+ listener->context, "set_client_func");
for (i = 0; i < listener->nsioc; i++) {
if (listener->io_source[i]) {
@@ -158,6 +180,16 @@
}
}
+ if (listener->io_notify) {
+ listener->io_notify(listener->io_data);
+ }
+ listener->io_func = func;
+ listener->io_data = data;
+ listener->io_notify = notify;
+ listener->context = context;
+
+ trace_qio_net_listener_watch(listener, listener->io_func,
+ listener->context, "set_client_func");
if (listener->io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener));
@@ -217,7 +249,15 @@
.loop = loop
};
size_t i;
+ QIONetListenerClientFunc io_func;
+ GMainContext *context;
+ WITH_QEMU_LOCK_GUARD(&listener->lock) {
+ io_func = listener->io_func;
+ context = listener->context;
+ }
+
+ trace_qio_net_listener_unwatch(listener, io_func, context, "wait_client");
for (i = 0; i < listener->nsioc; i++) {
if (listener->io_source[i]) {
g_source_destroy(listener->io_source[i]);
@@ -247,13 +287,14 @@
g_main_loop_unref(loop);
g_main_context_unref(ctxt);
- if (listener->io_func != NULL) {
+ trace_qio_net_listener_watch(listener, io_func, context, "wait_client");
+ if (io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener));
listener->io_source[i] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
qio_net_listener_channel_func,
- listener, (GDestroyNotify)object_unref, NULL);
+ listener, (GDestroyNotify)object_unref, context);
}
}
@@ -268,6 +309,9 @@
return;
}
+ QEMU_LOCK_GUARD(&listener->lock);
+ trace_qio_net_listener_unwatch(listener, listener->io_func,
+ listener->context, "disconnect");
for (i = 0; i < listener->nsioc; i++) {
if (listener->io_source[i]) {
g_source_destroy(listener->io_source[i]);
@@ -290,10 +334,10 @@
QIONetListener *listener = QIO_NET_LISTENER(obj);
size_t i;
+ qio_net_listener_disconnect(listener);
if (listener->io_notify) {
listener->io_notify(listener->io_data);
}
- qio_net_listener_disconnect(listener);
for (i = 0; i < listener->nsioc; i++) {
object_unref(OBJECT(listener->sioc[i]));
@@ -301,6 +345,7 @@
g_free(listener->io_source);
g_free(listener->sioc);
g_free(listener->name);
+ qemu_mutex_destroy(&listener->lock);
}
static const TypeInfo qio_net_listener_info = {
diff -Nru qemu-10.0.6+ds/io/trace-events qemu-10.0.7+ds/io/trace-events
--- qemu-10.0.6+ds/io/trace-events 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/io/trace-events 2025-12-06 17:54:24.000000000 +0300
@@ -72,3 +72,8 @@
qio_channel_command_new_spawn(void *ioc, const char *binary, int flags) "Command new spawn ioc=%p binary=%s flags=%d"
qio_channel_command_abort(void *ioc, int pid) "Command abort ioc=%p pid=%d"
qio_channel_command_wait(void *ioc, int pid, int ret, int status) "Command abort ioc=%p pid=%d ret=%d status=%d"
+
+# net-listener.c
+qio_net_listener_watch(void *listener, void *func, void *ctx, const char *extra) "Net listener=%p watch enabled func=%p ctx=%p by %s"
+qio_net_listener_unwatch(void *listener, void *func, void *ctx, const char *extra) "Net listener=%p watch disabled func=%p ctx=%p by %s"
+qio_net_listener_callback(void *listener, void *func, void *ctx) "Net listener=%p callback forwarding to func=%p ctx=%p"
diff -Nru qemu-10.0.6+ds/linux-user/ioctls.h qemu-10.0.7+ds/linux-user/ioctls.h
--- qemu-10.0.6+ds/linux-user/ioctls.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/linux-user/ioctls.h 2025-12-06 17:54:24.000000000 +0300
@@ -130,7 +130,7 @@
IOCTL(FDTWADDLE, 0, TYPE_NULL)
IOCTL(FDEJECT, 0, TYPE_NULL)
- IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
+ IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_INT))
#ifdef FICLONE
IOCTL(FICLONE, IOC_W, TYPE_INT)
IOCTL(FICLONERANGE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_file_clone_range)))
@@ -145,7 +145,7 @@
IOCTL(FITRIM, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_fstrim_range)))
#endif
- IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
+ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_INT))
#ifdef CONFIG_FIEMAP
IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap,
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
diff -Nru qemu-10.0.6+ds/linux-user/syscall.c qemu-10.0.7+ds/linux-user/syscall.c
--- qemu-10.0.6+ds/linux-user/syscall.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/linux-user/syscall.c 2025-12-06 17:54:24.000000000 +0300
@@ -3582,7 +3582,7 @@
abi_ulong target_addr, socklen_t addrlen)
{
void *addr;
- void *host_msg;
+ void *host_msg = NULL;
void *copy_msg = NULL;
abi_long ret;
@@ -3590,16 +3590,19 @@
return -TARGET_EINVAL;
}
- host_msg = lock_user(VERIFY_READ, msg, len, 1);
- if (!host_msg)
- return -TARGET_EFAULT;
- if (fd_trans_target_to_host_data(fd)) {
- copy_msg = host_msg;
- host_msg = g_malloc(len);
- memcpy(host_msg, copy_msg, len);
- ret = fd_trans_target_to_host_data(fd)(host_msg, len);
- if (ret < 0) {
- goto fail;
+ if (len != 0) {
+ host_msg = lock_user(VERIFY_READ, msg, len, 1);
+ if (!host_msg) {
+ return -TARGET_EFAULT;
+ }
+ if (fd_trans_target_to_host_data(fd)) {
+ copy_msg = host_msg;
+ host_msg = g_malloc(len);
+ memcpy(host_msg, copy_msg, len);
+ ret = fd_trans_target_to_host_data(fd)(host_msg, len);
+ if (ret < 0) {
+ goto fail;
+ }
}
}
if (target_addr) {
diff -Nru qemu-10.0.6+ds/migration/migration.c qemu-10.0.7+ds/migration/migration.c
--- qemu-10.0.6+ds/migration/migration.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/migration/migration.c 2025-12-06 17:54:24.000000000 +0300
@@ -3021,9 +3021,9 @@
goto fail;
}
- if (migrate_colo() && s->state == MIGRATION_STATUS_ACTIVE) {
+ if (migrate_colo() && s->state == MIGRATION_STATUS_DEVICE) {
/* COLO does not support postcopy */
- migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE,
+ migrate_set_state(&s->state, MIGRATION_STATUS_DEVICE,
MIGRATION_STATUS_COLO);
} else {
migration_completion_end(s);
diff -Nru qemu-10.0.6+ds/net/net.c qemu-10.0.7+ds/net/net.c
--- qemu-10.0.6+ds/net/net.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/net/net.c 2025-12-06 17:54:24.000000000 +0300
@@ -757,10 +757,20 @@
ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size)
{
+ uint8_t min_pkt[ETH_ZLEN];
+ size_t min_pktsz = sizeof(min_pkt);
+
if (!qemu_can_receive_packet(nc)) {
return 0;
}
+ if (net_peer_needs_padding(nc)) {
+ if (eth_pad_short_frame(min_pkt, &min_pktsz, buf, size)) {
+ buf = min_pkt;
+ size = min_pktsz;
+ }
+ }
+
return qemu_net_queue_receive(nc->incoming_queue, buf, size);
}
diff -Nru qemu-10.0.6+ds/pythondeps.toml qemu-10.0.7+ds/pythondeps.toml
--- qemu-10.0.6+ds/pythondeps.toml 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/pythondeps.toml 2025-12-06 17:54:24.000000000 +0300
@@ -27,9 +27,5 @@
sphinx = { accepted = ">=3.4.3", installed = "5.3.0", canary = "sphinx-build" }
sphinx_rtd_theme = { accepted = ">=0.5", installed = "1.1.1" }
-[avocado]
-# Note that qemu.git/python/ is always implicitly installed.
-# Prefer an LTS version when updating the accepted versions of
-# avocado-framework, for example right now the limit is 92.x.
-avocado-framework = { accepted = "(>=103.0, <104.0)", installed = "103.0", canary = "avocado" }
-pycdlib = { accepted = ">=1.11.0" }
+[testdeps]
+qemu.qmp = { accepted = ">=0.0.3", installed = "0.0.3" }
diff -Nru qemu-10.0.6+ds/qemu-img.c qemu-10.0.7+ds/qemu-img.c
--- qemu-10.0.6+ds/qemu-img.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/qemu-img.c 2025-12-06 17:54:24.000000000 +0300
@@ -3910,7 +3910,7 @@
n += offset - QEMU_ALIGN_DOWN(offset, write_align);
offset = QEMU_ALIGN_DOWN(offset, write_align);
n += QEMU_ALIGN_UP(offset + n, write_align) - (offset + n);
- n = MIN(n, size - offset);
+ n = MIN(n, MIN(size - offset, IO_BUF_SIZE));
assert(!bdrv_is_allocated(unfiltered_bs, offset, n, &n_alloc) &&
n_alloc == n);
@@ -4369,9 +4369,9 @@
amend_opts = qemu_opts_append(amend_opts, bs->drv->amend_opts);
opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
if (!qemu_opts_do_parse(opts, options, NULL, &err)) {
+ qemu_opts_del(opts);
/* Try to parse options using the create options */
amend_opts = qemu_opts_append(amend_opts, bs->drv->create_opts);
- qemu_opts_del(opts);
opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
if (qemu_opts_do_parse(opts, options, NULL, NULL)) {
error_append_hint(&err,
diff -Nru qemu-10.0.6+ds/target/arm/helper.c qemu-10.0.7+ds/target/arm/helper.c
--- qemu-10.0.6+ds/target/arm/helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/arm/helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -3420,7 +3420,7 @@
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
{ .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
- .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
+ .access = PL0_R /* no PL1_RW in linux-user */,
.fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
.resetfn = arm_gt_cntfrq_reset,
},
diff -Nru qemu-10.0.6+ds/target/arm/tcg/translate-a64.c qemu-10.0.7+ds/target/arm/tcg/translate-a64.c
--- qemu-10.0.6+ds/target/arm/tcg/translate-a64.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/arm/tcg/translate-a64.c 2025-12-06 17:54:24.000000000 +0300
@@ -1852,8 +1852,8 @@
return false;
}
dst = auth_branch_target(s, cpu_reg(s,a->rn), cpu_reg_sp(s, a->rm), !a->m);
- gen_a64_set_pc(s, dst);
set_btype_for_br(s, a->rn);
+ gen_a64_set_pc(s, dst);
s->base.is_jmp = DISAS_JUMP;
return true;
}
diff -Nru qemu-10.0.6+ds/target/hppa/fpu_helper.c qemu-10.0.7+ds/target/hppa/fpu_helper.c
--- qemu-10.0.6+ds/target/hppa/fpu_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/hppa/fpu_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -95,7 +95,8 @@
{
uint32_t soft_exp = get_float_exception_flags(&env->fp_status);
uint32_t hard_exp = 0;
- uint32_t shadow = env->fr0_shadow & 0x3ffffff;
+ uint32_t shadow = env->fr0_shadow;
+ uint32_t to_flag = 0;
uint32_t fr1 = 0;
if (likely(soft_exp == 0)) {
@@ -123,6 +124,10 @@
fr1 |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
}
}
+ /* Set the Flag bits for every exception that was not enabled */
+ to_flag = hard_exp & ~shadow;
+ shadow |= to_flag << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
+
env->fr0_shadow = shadow;
env->fr[0] = (uint64_t)shadow << 32 | fr1;
diff -Nru qemu-10.0.6+ds/target/i386/hvf/x86hvf.c qemu-10.0.7+ds/target/i386/hvf/x86hvf.c
--- qemu-10.0.6+ds/target/i386/hvf/x86hvf.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/hvf/x86hvf.c 2025-12-06 17:54:24.000000000 +0300
@@ -447,6 +447,7 @@
cs->halted = 0;
}
if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_SIPI);
cpu_synchronize_state(cs);
do_cpu_sipi(cpu);
}
diff -Nru qemu-10.0.6+ds/target/i386/kvm/kvm.c qemu-10.0.7+ds/target/i386/kvm/kvm.c
--- qemu-10.0.6+ds/target/i386/kvm/kvm.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/kvm/kvm.c 2025-12-06 17:54:24.000000000 +0300
@@ -2722,6 +2722,12 @@
}
}
+/* It should only be called in cpu's hotplug callback */
+void kvm_smm_cpu_address_space_init(X86CPU *cpu)
+{
+ cpu_address_space_init(CPU(cpu), X86ASIdx_SMM, "cpu-smm", &smram_as_root);
+}
+
static void *kvm_msr_energy_thread(void *data)
{
KVMState *s = data;
@@ -5637,6 +5643,7 @@
cs->halted = 0;
}
if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_SIPI);
kvm_cpu_synchronize_state(cs);
do_cpu_sipi(cpu);
}
diff -Nru qemu-10.0.6+ds/target/i386/kvm/kvm_i386.h qemu-10.0.7+ds/target/i386/kvm/kvm_i386.h
--- qemu-10.0.6+ds/target/i386/kvm/kvm_i386.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/kvm/kvm_i386.h 2025-12-06 17:54:24.000000000 +0300
@@ -59,6 +59,7 @@
#endif /* CONFIG_KVM */
+void kvm_smm_cpu_address_space_init(X86CPU *cpu);
void kvm_pc_setup_irq_routing(bool pci_enabled);
#endif
diff -Nru qemu-10.0.6+ds/target/i386/nvmm/nvmm-all.c qemu-10.0.7+ds/target/i386/nvmm/nvmm-all.c
--- qemu-10.0.6+ds/target/i386/nvmm/nvmm-all.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/nvmm/nvmm-all.c 2025-12-06 17:54:24.000000000 +0300
@@ -704,6 +704,7 @@
cpu->halted = false;
}
if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_SIPI);
nvmm_cpu_synchronize_state(cpu);
do_cpu_sipi(x86_cpu);
}
diff -Nru qemu-10.0.6+ds/target/i386/tcg/decode-new.c.inc qemu-10.0.7+ds/target/i386/tcg/decode-new.c.inc
--- qemu-10.0.6+ds/target/i386/tcg/decode-new.c.inc 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/tcg/decode-new.c.inc 2025-12-06 17:54:24.000000000 +0300
@@ -335,6 +335,8 @@
*entry = group9_reg;
} else if (op == 1) {
*entry = REX_W(s) ? cmpxchg16b : cmpxchg8b;
+ } else {
+ *entry = UNKNOWN_OPCODE;
}
}
@@ -641,7 +643,7 @@
[0x0a] = X86_OP_ENTRY3(PSIGND, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66),
[0x0b] = X86_OP_ENTRY3(PMULHRSW, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66),
/* Listed incorrectly as type 4 */
- [0x0c] = X86_OP_ENTRY3(VPERMILPS, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_00_66),
+ [0x0c] = X86_OP_ENTRY3(VPERMILPS, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0d] = X86_OP_ENTRY3(VPERMILPD, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0e] = X86_OP_ENTRY3(VTESTPS, None,None, V,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0f] = X86_OP_ENTRY3(VTESTPD, None,None, V,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
@@ -2057,7 +2059,12 @@
case X86_TYPE_S: /* reg selects a segment register */
op->unit = X86_OP_SEG;
- goto get_reg;
+ op->n = (get_modrm(s, env) >> 3) & 7;
+ /* Values outside [CDEFGS]S, as well as storing to CS, are invalid. */
+ if (op->n >= 6 || (op->n == R_CS && op == &decode->op[0])) {
+ return false;
+ }
+ break;
case X86_TYPE_P:
op->unit = X86_OP_MMX;
diff -Nru qemu-10.0.6+ds/target/i386/tcg/helper-tcg.h qemu-10.0.7+ds/target/i386/tcg/helper-tcg.h
--- qemu-10.0.6+ds/target/i386/tcg/helper-tcg.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/tcg/helper-tcg.h 2025-12-06 17:54:24.000000000 +0300
@@ -100,7 +100,7 @@
/* sysemu/svm_helper.c */
#ifndef CONFIG_USER_ONLY
-G_NORETURN void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code,
+G_NORETURN void cpu_vmexit(CPUX86State *nenv, uint64_t exit_code,
uint64_t exit_info_1, uintptr_t retaddr);
void do_vmexit(CPUX86State *env);
#endif
diff -Nru qemu-10.0.6+ds/target/i386/tcg/seg_helper.c qemu-10.0.7+ds/target/i386/tcg/seg_helper.c
--- qemu-10.0.6+ds/target/i386/tcg/seg_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/tcg/seg_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -1135,7 +1135,7 @@
sa.env = env;
sa.ra = 0;
sa.sp = env->regs[R_ESP];
- sa.sp_mask = 0xffff;
+ sa.sp_mask = get_sp_mask(env->segs[R_SS].flags);
sa.ss_base = env->segs[R_SS].base;
sa.mmu_index = x86_mmu_index_pl(env, 0);
@@ -1933,7 +1933,7 @@
sa.env = env;
sa.ra = GETPC();
sa.mmu_index = x86_mmu_index_pl(env, 0);
- sa.sp_mask = 0xffff; /* XXXX: use SS segment size? */
+ sa.sp_mask = get_sp_mask(env->segs[R_SS].flags);
sa.sp = env->regs[R_ESP];
sa.ss_base = env->segs[R_SS].base;
diff -Nru qemu-10.0.6+ds/target/i386/tcg/system/svm_helper.c qemu-10.0.7+ds/target/i386/tcg/system/svm_helper.c
--- qemu-10.0.6+ds/target/i386/tcg/system/svm_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/tcg/system/svm_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -128,7 +128,7 @@
return false;
}
-static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint32_t exit_code, uintptr_t retaddr)
+static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint64_t exit_code, uintptr_t retaddr)
{
uint64_t lbr_ctl;
@@ -723,7 +723,7 @@
}
}
-void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
+void cpu_vmexit(CPUX86State *env, uint64_t exit_code, uint64_t exit_info_1,
uintptr_t retaddr)
{
CPUState *cs = env_cpu(env);
@@ -732,7 +732,7 @@
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
PRIx64 ", " TARGET_FMT_lx ")!\n",
- exit_code, exit_info_1,
+ (uint32_t)exit_code, exit_info_1,
x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
control.exit_info_2)),
env->eip);
diff -Nru qemu-10.0.6+ds/target/i386/whpx/whpx-all.c qemu-10.0.7+ds/target/i386/whpx/whpx-all.c
--- qemu-10.0.6+ds/target/i386/whpx/whpx-all.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/i386/whpx/whpx-all.c 2025-12-06 17:54:24.000000000 +0300
@@ -1624,6 +1624,7 @@
}
if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_SIPI);
whpx_cpu_synchronize_state(cpu);
do_cpu_sipi(x86_cpu);
}
diff -Nru qemu-10.0.6+ds/target/microblaze/cpu.h qemu-10.0.7+ds/target/microblaze/cpu.h
--- qemu-10.0.6+ds/target/microblaze/cpu.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/microblaze/cpu.h 2025-12-06 17:54:24.000000000 +0300
@@ -85,6 +85,7 @@
#define ESR_ESS_FSL_OFFSET 5
#define ESR_ESS_MASK (0x7f << 5)
+#define ESR_ESS_DEC_OF (1 << 11) /* DEC: 0=DBZ, 1=OF */
#define ESR_EC_FSL 0
#define ESR_EC_UNALIGNED_DATA 1
diff -Nru qemu-10.0.6+ds/target/microblaze/op_helper.c qemu-10.0.7+ds/target/microblaze/op_helper.c
--- qemu-10.0.6+ds/target/microblaze/op_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/microblaze/op_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -70,38 +70,51 @@
cpu_loop_exit(cs);
}
-static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra)
+/* Raises ESR_EC_DIVZERO if exceptions are enabled. */
+static void raise_divzero(CPUMBState *env, uint32_t esr, uintptr_t unwind_pc)
{
- if (unlikely(b == 0)) {
- env->msr |= MSR_DZ;
+ env->msr |= MSR_DZ;
- if ((env->msr & MSR_EE) &&
- env_archcpu(env)->cfg.div_zero_exception) {
- CPUState *cs = env_cpu(env);
-
- env->esr = ESR_EC_DIVZERO;
- cs->exception_index = EXCP_HW_EXCP;
- cpu_loop_exit_restore(cs, ra);
- }
- return false;
+ if ((env->msr & MSR_EE) && env_archcpu(env)->cfg.div_zero_exception) {
+ CPUState *cs = env_cpu(env);
+
+ env->esr = esr;
+ cs->exception_index = EXCP_HW_EXCP;
+ cpu_loop_exit_restore(cs, unwind_pc);
}
- return true;
}
-uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divs(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, a, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return (int32_t)a / (int32_t)b;
+
+ /*
+ * Check for division overflows.
+ *
+ * Spec: https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv
+ * UG984, Chapter 5 MicroBlaze Instruction Set Architecture, idiv.
+ *
+ * If the U bit is clear, the value of rA is -1, and the value of rB is
+ * -2147483648 (divide overflow), the DZO bit in MSR will be set and
+ * the value in rD will be -2147483648, unless an exception is generated.
+ */
+ if ((int32_t)ra == -1 && (int32_t)rb == INT32_MIN) {
+ raise_divzero(env, ESR_EC_DIVZERO | ESR_ESS_DEC_OF, GETPC());
+ return INT32_MIN;
+ }
+ return (int32_t)rb / (int32_t)ra;
}
-uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divu(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, a, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return a / b;
+ return rb / ra;
}
/* raise FPU exception. */
diff -Nru qemu-10.0.6+ds/target/microblaze/translate.c qemu-10.0.7+ds/target/microblaze/translate.c
--- qemu-10.0.6+ds/target/microblaze/translate.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/microblaze/translate.c 2025-12-06 17:54:24.000000000 +0300
@@ -467,16 +467,8 @@
DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
-/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
-static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divs(out, tcg_env, inb, ina);
-}
-
-static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divu(out, tcg_env, inb, ina);
-}
+ENV_WRAPPER3(gen_idiv, gen_helper_divs)
+ENV_WRAPPER3(gen_idivu, gen_helper_divu)
DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
diff -Nru qemu-10.0.6+ds/target/riscv/cpu_helper.c qemu-10.0.7+ds/target/riscv/cpu_helper.c
--- qemu-10.0.6+ds/target/riscv/cpu_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/riscv/cpu_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -539,8 +539,7 @@
int riscv_cpu_sirq_pending(CPURISCVState *env)
{
- uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg &
- ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
+ uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg;
uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie;
return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
diff -Nru qemu-10.0.6+ds/target/riscv/kvm/kvm-cpu.c qemu-10.0.7+ds/target/riscv/kvm/kvm-cpu.c
--- qemu-10.0.6+ds/target/riscv/kvm/kvm-cpu.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/riscv/kvm/kvm-cpu.c 2025-12-06 17:54:24.000000000 +0300
@@ -135,6 +135,7 @@
const char *description;
target_ulong offset;
uint64_t kvm_reg_id;
+ uint32_t prop_size;
bool user_set;
bool supported;
} KVMCPUConfig;
@@ -237,6 +238,7 @@
#define KVM_CSR_CFG(_name, _env_prop, reg_id) \
{.name = _name, .offset = ENV_CSR_OFFSET(_env_prop), \
+ .prop_size = sizeof(((CPURISCVState *)0)->_env_prop), \
.kvm_reg_id = reg_id}
static KVMCPUConfig kvm_csr_cfgs[] = {
@@ -249,6 +251,8 @@
KVM_CSR_CFG("stval", stval, RISCV_CSR_REG(stval)),
KVM_CSR_CFG("sip", mip, RISCV_CSR_REG(sip)),
KVM_CSR_CFG("satp", satp, RISCV_CSR_REG(satp)),
+ KVM_CSR_CFG("scounteren", scounteren, RISCV_CSR_REG(scounteren)),
+ KVM_CSR_CFG("senvcfg", senvcfg, RISCV_CSR_REG(senvcfg)),
};
static void *kvmconfig_get_env_addr(RISCVCPU *cpu, KVMCPUConfig *csr_cfg)
@@ -645,9 +649,9 @@
return ret;
}
- if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint32_t)) {
- kvm_cpu_csr_set_u32(cpu, csr_cfg, reg);
- } else if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint64_t)) {
+ if (csr_cfg->prop_size == sizeof(uint32_t)) {
+ kvm_cpu_csr_set_u32(cpu, csr_cfg, (uint32_t)reg);
+ } else if (csr_cfg->prop_size == sizeof(uint64_t)) {
kvm_cpu_csr_set_u64(cpu, csr_cfg, reg);
} else {
g_assert_not_reached();
@@ -670,9 +674,9 @@
continue;
}
- if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint32_t)) {
+ if (csr_cfg->prop_size == sizeof(uint32_t)) {
reg = kvm_cpu_csr_get_u32(cpu, csr_cfg);
- } else if (KVM_REG_SIZE(csr_cfg->kvm_reg_id) == sizeof(uint64_t)) {
+ } else if (csr_cfg->prop_size == sizeof(uint64_t)) {
reg = kvm_cpu_csr_get_u64(cpu, csr_cfg);
} else {
g_assert_not_reached();
@@ -698,6 +702,9 @@
env->stval = 0;
env->mip = 0;
env->satp = 0;
+ env->scounteren = 0;
+ env->senvcfg = 0;
+ env->priv = PRV_S;
}
static int kvm_riscv_get_regs_fp(CPUState *cs)
diff -Nru qemu-10.0.6+ds/target/s390x/tcg/mem_helper.c qemu-10.0.7+ds/target/s390x/tcg/mem_helper.c
--- qemu-10.0.6+ds/target/s390x/tcg/mem_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/s390x/tcg/mem_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -1956,6 +1956,10 @@
if (env->cregs[i] != val && i >= 9 && i <= 11) {
PERchanged = true;
}
+ if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val & CR0_CKC_SC)) {
+ BQL_LOCK_GUARD();
+ tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
+ }
env->cregs[i] = val;
HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
i, src, val);
@@ -1986,10 +1990,15 @@
for (i = r1;; i = (i + 1) % 16) {
uint32_t val = cpu_ldl_data_ra(env, src, ra);
+ uint64_t val64 = deposit64(env->cregs[i], 0, 32, val);
if ((uint32_t)env->cregs[i] != val && i >= 9 && i <= 11) {
PERchanged = true;
}
- env->cregs[i] = deposit64(env->cregs[i], 0, 32, val);
+ if (i == 0 && !(env->cregs[i] & CR0_CKC_SC) && (val64 & CR0_CKC_SC)) {
+ BQL_LOCK_GUARD();
+ tcg_s390_tod_updated(env_cpu(env), RUN_ON_CPU_NULL);
+ }
+ env->cregs[i] = val64;
HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%x\n", i, src, val);
src += sizeof(uint32_t);
diff -Nru qemu-10.0.6+ds/target/s390x/tcg/misc_helper.c qemu-10.0.7+ds/target/s390x/tcg/misc_helper.c
--- qemu-10.0.6+ds/target/s390x/tcg/misc_helper.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/s390x/tcg/misc_helper.c 2025-12-06 17:54:24.000000000 +0300
@@ -199,11 +199,15 @@
return;
}
- /* difference between origins */
- time = env->ckc - td->base.low;
+ if (env->ckc < td->base.low) {
+ time = 0;
+ } else {
+ /* difference between origins */
+ time = env->ckc - td->base.low;
- /* nanoseconds */
- time = tod2time(time);
+ /* nanoseconds */
+ time = tod2time(time);
+ }
timer_mod(env->tod_timer, time);
}
diff -Nru qemu-10.0.6+ds/target/s390x/tcg/translate.c qemu-10.0.7+ds/target/s390x/tcg/translate.c
--- qemu-10.0.6+ds/target/s390x/tcg/translate.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/target/s390x/tcg/translate.c 2025-12-06 17:54:24.000000000 +0300
@@ -5618,6 +5618,7 @@
int r2 = get_field(s, r2);
if (r2 != 0) {
o->in2 = load_reg(r2);
+ gen_addi_and_wrap_i64(s, o->in2, o->in2, 0);
}
}
#define SPEC_in2_r2_nz 0
@@ -6384,10 +6385,12 @@
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
- /* 31-bit mode */
- if (!(dc->base.tb->flags & FLAG_MASK_64)) {
- dc->base.pc_first &= 0x7fffffff;
- dc->base.pc_next = dc->base.pc_first;
+ if (dc->base.tb->flags & FLAG_MASK_32) {
+ if (!(dc->base.tb->flags & FLAG_MASK_64)) {
+ assert(!(dc->base.pc_first & ~((1ULL << 31) - 1)));
+ }
+ } else {
+ assert(!(dc->base.pc_first & ~((1ULL << 24) - 1)));
}
dc->cc_op = CC_OP_DYNAMIC;
diff -Nru qemu-10.0.6+ds/tests/Makefile.include qemu-10.0.7+ds/tests/Makefile.include
--- qemu-10.0.6+ds/tests/Makefile.include 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/Makefile.include 2025-12-06 17:54:24.000000000 +0300
@@ -18,7 +18,6 @@
@echo " $(MAKE) check-tcg Run TCG tests"
@echo " $(MAKE) check-softfloat Run FPU emulation tests"
endif
- @echo " $(MAKE) check-avocado Run avocado (integration) tests for currently configured targets"
@echo
@echo " $(MAKE) check-report.junit.xml Generates an aggregated XML test report"
@echo " $(MAKE) check-venv Creates a Python venv for tests"
@@ -26,7 +25,6 @@
@echo
@echo "The following are useful for CI builds"
@echo " $(MAKE) check-build Build most test binaries"
- @echo " $(MAKE) get-vm-images Downloads all images used by avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
@echo
@echo
@echo "The variable SPEED can be set to control the gtester speed setting."
@@ -86,26 +84,12 @@
# Python venv for running tests
-.PHONY: check-venv check-avocado check-acceptance check-acceptance-deprecated-warning
+.PHONY: check-venv
# Build up our target list from the filtered list of ninja targets
TARGETS=$(patsubst libqemu-%.a, %, $(filter libqemu-%.a, $(ninja-targets)))
TESTS_VENV_TOKEN=$(BUILD_DIR)/pyvenv/tests.group
-TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
-ifndef AVOCADO_TESTS
- AVOCADO_TESTS=tests/avocado
-endif
-# Controls the output generated by Avocado when running tests.
-# Any number of command separated loggers are accepted. For more
-# information please refer to "avocado --help".
-AVOCADO_SHOW?=app
-ifndef AVOCADO_TAGS
- AVOCADO_CMDLINE_TAGS=$(patsubst %-softmmu,-t arch:%, \
- $(filter %-softmmu,$(TARGETS)))
-else
- AVOCADO_CMDLINE_TAGS=$(addprefix -t , $(AVOCADO_TAGS))
-endif
quiet-venv-pip = $(quiet-@)$(call quiet-command-run, \
$(PYTHON) -m pip -q --disable-pip-version-check $1, \
@@ -113,47 +97,11 @@
$(TESTS_VENV_TOKEN): $(SRC_PATH)/pythondeps.toml
$(call quiet-venv-pip,install -e "$(SRC_PATH)/python/")
- $(MKVENV_ENSUREGROUP) $< avocado
+ $(MKVENV_ENSUREGROUP) $< testdeps
$(call quiet-command, touch $@)
-$(TESTS_RESULTS_DIR):
- $(call quiet-command, mkdir -p $@, \
- MKDIR, $@)
-
check-venv: $(TESTS_VENV_TOKEN)
-FEDORA_31_ARCHES_TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGETS)))
-FEDORA_31_ARCHES_CANDIDATES=$(patsubst ppc64,ppc64le,$(FEDORA_31_ARCHES_TARGETS))
-FEDORA_31_ARCHES := x86_64 aarch64 ppc64le s390x
-FEDORA_31_DOWNLOAD=$(filter $(FEDORA_31_ARCHES),$(FEDORA_31_ARCHES_CANDIDATES))
-
-# download one specific Fedora 31 image
-get-vm-image-fedora-31-%: check-venv
- $(call quiet-command, \
- $(PYTHON) -m avocado vmimage get \
- --distro=fedora --distro-version=31 --arch=$*, \
- "AVOCADO", "Downloading avocado tests VM image for $*")
-
-# download all vm images, according to defined targets
-get-vm-images: check-venv $(patsubst %,get-vm-image-fedora-31-%, $(FEDORA_31_DOWNLOAD))
-
-check-avocado: check-venv $(TESTS_RESULTS_DIR) get-vm-images
- $(call quiet-command, \
- $(PYTHON) -m avocado \
- --show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
- $(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
- --filter-by-tags-include-empty-key) \
- $(AVOCADO_CMDLINE_TAGS) --max-parallel-tasks=1 \
- $(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \
- "AVOCADO", "tests/avocado")
-
-check-acceptance-deprecated-warning:
- @echo
- @echo "Note '$(MAKE) check-acceptance' is deprecated, use '$(MAKE) check-avocado' instead."
- @echo
-
-check-acceptance: check-acceptance-deprecated-warning | check-avocado
-
FUNCTIONAL_TARGETS=$(patsubst %-softmmu,check-functional-%, $(filter %-softmmu,$(TARGETS)))
.PHONY: $(FUNCTIONAL_TARGETS)
$(FUNCTIONAL_TARGETS):
@@ -169,13 +117,13 @@
# Consolidated targets
-.PHONY: check check-clean get-vm-images
+.PHONY: check check-clean
check:
check-build: run-ninja
check-clean:
- rm -rf $(TESTS_RESULTS_DIR)
+ rm -rf $(BUILD_DIR)/tests/functional
clean: check-clean clean-tcg
distclean: distclean-tcg
diff -Nru qemu-10.0.6+ds/tests/avocado/README.rst qemu-10.0.7+ds/tests/avocado/README.rst
--- qemu-10.0.6+ds/tests/avocado/README.rst 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/README.rst 1970-01-01 03:00:00.000000000 +0300
@@ -1,10 +0,0 @@
-=============================================
-Integration tests using the Avocado Framework
-=============================================
-
-This directory contains integration tests. They're usually higher
-level, and may interact with external resources and with various
-guest operating systems.
-
-For more information, please refer to ``docs/devel/testing.rst``,
-section "Integration tests using the Avocado Framework".
diff -Nru qemu-10.0.6+ds/tests/avocado/avocado_qemu/__init__.py qemu-10.0.7+ds/tests/avocado/avocado_qemu/__init__.py
--- qemu-10.0.6+ds/tests/avocado/avocado_qemu/__init__.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/avocado_qemu/__init__.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,424 +0,0 @@
-# Test class and utilities for functional tests
-#
-# Copyright (c) 2018 Red Hat, Inc.
-#
-# Author:
-# Cleber Rosa <crosa@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import logging
-import os
-import subprocess
-import sys
-import tempfile
-import time
-import uuid
-
-import avocado
-from avocado.utils import ssh
-from avocado.utils.path import find_command
-
-from qemu.machine import QEMUMachine
-from qemu.utils import (get_info_usernet_hostfwd_port, kvm_available,
- tcg_available)
-
-
-#: The QEMU build root directory. It may also be the source directory
-#: if building from the source dir, but it's safer to use BUILD_DIR for
-#: that purpose. Be aware that if this code is moved outside of a source
-#: and build tree, it will not be accurate.
-BUILD_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
-
-
-def has_cmd(name, args=None):
- """
- This function is for use in a @avocado.skipUnless decorator, e.g.:
-
- @skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
- def test_something_that_needs_sudo(self):
- ...
- """
-
- if args is None:
- args = ('which', name)
-
- try:
- _, stderr, exitcode = run_cmd(args)
- except Exception as e:
- exitcode = -1
- stderr = str(e)
-
- if exitcode != 0:
- cmd_line = ' '.join(args)
- err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
- return (False, err)
- else:
- return (True, '')
-
-def has_cmds(*cmds):
- """
- This function is for use in a @avocado.skipUnless decorator and
- allows checking for the availability of multiple commands, e.g.:
-
- @skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
- 'cmd2', 'cmd3'))
- def test_something_that_needs_cmd1_and_cmd2(self):
- ...
- """
-
- for cmd in cmds:
- if isinstance(cmd, str):
- cmd = (cmd,)
-
- ok, errstr = has_cmd(*cmd)
- if not ok:
- return (False, errstr)
-
- return (True, '')
-
-def run_cmd(args):
- subp = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True)
- stdout, stderr = subp.communicate()
- ret = subp.returncode
-
- return (stdout, stderr, ret)
-
-def is_readable_executable_file(path):
- return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
-
-
-def pick_default_qemu_bin(bin_prefix='qemu-system-', arch=None):
- """
- Picks the path of a QEMU binary, starting either in the current working
- directory or in the source tree root directory.
-
- :param arch: the arch to use when looking for a QEMU binary (the target
- will match the arch given). If None (the default), arch
- will be the current host system arch (as given by
- :func:`os.uname`).
- :type arch: str
- :returns: the path to the default QEMU binary or None if one could not
- be found
- :rtype: str or None
- """
- if arch is None:
- arch = os.uname()[4]
- # qemu binary path does not match arch for powerpc, handle it
- if 'ppc64le' in arch:
- arch = 'ppc64'
- qemu_bin_name = bin_prefix + arch
- qemu_bin_paths = [
- os.path.join(".", qemu_bin_name),
- os.path.join(BUILD_DIR, qemu_bin_name),
- os.path.join(BUILD_DIR, "build", qemu_bin_name),
- ]
- for path in qemu_bin_paths:
- if is_readable_executable_file(path):
- return path
- return None
-
-
-def _console_interaction(test, success_message, failure_message,
- send_string, keep_sending=False, vm=None):
- assert not keep_sending or send_string
- if vm is None:
- vm = test.vm
- console = vm.console_file
- console_logger = logging.getLogger('console')
- while True:
- if send_string:
- vm.console_socket.sendall(send_string.encode())
- if not keep_sending:
- send_string = None # send only once
-
- # Only consume console output if waiting for something
- if success_message is None and failure_message is None:
- if send_string is None:
- break
- continue
-
- try:
- msg = console.readline().decode().strip()
- except UnicodeDecodeError:
- msg = None
- if not msg:
- continue
- console_logger.debug(msg)
- if success_message is None or success_message in msg:
- break
- if failure_message and failure_message in msg:
- console.close()
- fail = 'Failure message found in console: "%s". Expected: "%s"' % \
- (failure_message, success_message)
- test.fail(fail)
-
-def interrupt_interactive_console_until_pattern(test, success_message,
- failure_message=None,
- interrupt_string='\r'):
- """
- Keep sending a string to interrupt a console prompt, while logging the
- console output. Typical use case is to break a boot loader prompt, such:
-
- Press a key within 5 seconds to interrupt boot process.
- 5
- 4
- 3
- 2
- 1
- Booting default image...
-
- :param test: an Avocado test containing a VM that will have its console
- read and probed for a success or failure message
- :type test: :class:`avocado_qemu.QemuSystemTest`
- :param success_message: if this message appears, test succeeds
- :param failure_message: if this message appears, test fails
- :param interrupt_string: a string to send to the console before trying
- to read a new line
- """
- _console_interaction(test, success_message, failure_message,
- interrupt_string, True)
-
-def wait_for_console_pattern(test, success_message, failure_message=None,
- vm=None):
- """
- Waits for messages to appear on the console, while logging the content
-
- :param test: an Avocado test containing a VM that will have its console
- read and probed for a success or failure message
- :type test: :class:`avocado_qemu.QemuSystemTest`
- :param success_message: if this message appears, test succeeds
- :param failure_message: if this message appears, test fails
- """
- _console_interaction(test, success_message, failure_message, None, vm=vm)
-
-def exec_command(test, command):
- """
- Send a command to a console (appending CRLF characters), while logging
- the content.
-
- :param test: an Avocado test containing a VM.
- :type test: :class:`avocado_qemu.QemuSystemTest`
- :param command: the command to send
- :type command: str
- """
- _console_interaction(test, None, None, command + '\r')
-
-def exec_command_and_wait_for_pattern(test, command,
- success_message, failure_message=None):
- """
- Send a command to a console (appending CRLF characters), then wait
- for success_message to appear on the console, while logging the.
- content. Mark the test as failed if failure_message is found instead.
-
- :param test: an Avocado test containing a VM that will have its console
- read and probed for a success or failure message
- :type test: :class:`avocado_qemu.QemuSystemTest`
- :param command: the command to send
- :param success_message: if this message appears, test succeeds
- :param failure_message: if this message appears, test fails
- """
- _console_interaction(test, success_message, failure_message, command + '\r')
-
-class QemuBaseTest(avocado.Test):
-
- # default timeout for all tests, can be overridden
- timeout = 120
-
- def _get_unique_tag_val(self, tag_name):
- """
- Gets a tag value, if unique for a key
- """
- vals = self.tags.get(tag_name, [])
- if len(vals) == 1:
- return vals.pop()
- return None
-
- def setUp(self, bin_prefix):
- self.arch = self.params.get('arch',
- default=self._get_unique_tag_val('arch'))
-
- self.cpu = self.params.get('cpu',
- default=self._get_unique_tag_val('cpu'))
-
- default_qemu_bin = pick_default_qemu_bin(bin_prefix, arch=self.arch)
- self.qemu_bin = self.params.get('qemu_bin',
- default=default_qemu_bin)
- if self.qemu_bin is None:
- self.cancel("No QEMU binary defined or found in the build tree")
-
- def fetch_asset(self, name,
- asset_hash, algorithm=None,
- locations=None, expire=None,
- find_only=False, cancel_on_missing=True):
- return super().fetch_asset(name,
- asset_hash=asset_hash,
- algorithm=algorithm,
- locations=locations,
- expire=expire,
- find_only=find_only,
- cancel_on_missing=cancel_on_missing)
-
-
-class QemuSystemTest(QemuBaseTest):
- """Facilitates system emulation tests."""
-
- def setUp(self):
- self._vms = {}
-
- super().setUp('qemu-system-')
-
- accel_required = self._get_unique_tag_val('accel')
- if accel_required:
- self.require_accelerator(accel_required)
-
- self.machine = self.params.get('machine',
- default=self._get_unique_tag_val('machine'))
-
- def require_accelerator(self, accelerator):
- """
- Requires an accelerator to be available for the test to continue
-
- It takes into account the currently set qemu binary.
-
- If the check fails, the test is canceled. If the check itself
- for the given accelerator is not available, the test is also
- canceled.
-
- :param accelerator: name of the accelerator, such as "kvm" or "tcg"
- :type accelerator: str
- """
- checker = {'tcg': tcg_available,
- 'kvm': kvm_available}.get(accelerator)
- if checker is None:
- self.cancel("Don't know how to check for the presence "
- "of accelerator %s" % accelerator)
- if not checker(qemu_bin=self.qemu_bin):
- self.cancel("%s accelerator does not seem to be "
- "available" % accelerator)
-
- def require_netdev(self, netdevname):
- netdevhelp = run_cmd([self.qemu_bin,
- '-M', 'none', '-netdev', 'help'])[0];
- if netdevhelp.find('\n' + netdevname + '\n') < 0:
- self.cancel('no support for user networking')
-
- def _new_vm(self, name, *args):
- self._sd = tempfile.TemporaryDirectory(prefix="qemu_")
- vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
- log_dir=self.logdir)
- self.log.debug('QEMUMachine "%s" created', name)
- self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir)
- self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir)
- if args:
- vm.add_args(*args)
- return vm
-
- def get_qemu_img(self):
- self.log.debug('Looking for and selecting a qemu-img binary')
-
- # If qemu-img has been built, use it, otherwise the system wide one
- # will be used.
- qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
- if not os.path.exists(qemu_img):
- qemu_img = find_command('qemu-img', False)
- if qemu_img is False:
- self.cancel('Could not find "qemu-img"')
-
- return qemu_img
-
- @property
- def vm(self):
- return self.get_vm(name='default')
-
- def get_vm(self, *args, name=None):
- if not name:
- name = str(uuid.uuid4())
- if self._vms.get(name) is None:
- self._vms[name] = self._new_vm(name, *args)
- if self.cpu is not None:
- self._vms[name].add_args('-cpu', self.cpu)
- if self.machine is not None:
- self._vms[name].set_machine(self.machine)
- return self._vms[name]
-
- def set_vm_arg(self, arg, value):
- """
- Set an argument to list of extra arguments to be given to the QEMU
- binary. If the argument already exists then its value is replaced.
-
- :param arg: the QEMU argument, such as "-cpu" in "-cpu host"
- :type arg: str
- :param value: the argument value, such as "host" in "-cpu host"
- :type value: str
- """
- if not arg or not value:
- return
- if arg not in self.vm.args:
- self.vm.args.extend([arg, value])
- else:
- idx = self.vm.args.index(arg) + 1
- if idx < len(self.vm.args):
- self.vm.args[idx] = value
- else:
- self.vm.args.append(value)
-
- def tearDown(self):
- for vm in self._vms.values():
- vm.shutdown()
- self._sd = None
- super().tearDown()
-
-
-class LinuxSSHMixIn:
- """Contains utility methods for interacting with a guest via SSH."""
-
- def ssh_connect(self, username, credential, credential_is_key=True):
- self.ssh_logger = logging.getLogger('ssh')
- res = self.vm.cmd('human-monitor-command',
- command_line='info usernet')
- port = get_info_usernet_hostfwd_port(res)
- self.assertIsNotNone(port)
- self.assertGreater(port, 0)
- self.log.debug('sshd listening on port: %d', port)
- if credential_is_key:
- self.ssh_session = ssh.Session('127.0.0.1', port=port,
- user=username, key=credential)
- else:
- self.ssh_session = ssh.Session('127.0.0.1', port=port,
- user=username, password=credential)
- for i in range(10):
- try:
- self.ssh_session.connect()
- return
- except:
- time.sleep(i)
- self.fail('ssh connection timeout')
-
- def ssh_command(self, command):
- self.ssh_logger.info(command)
- result = self.ssh_session.cmd(command)
- stdout_lines = [line.rstrip() for line
- in result.stdout_text.splitlines()]
- for line in stdout_lines:
- self.ssh_logger.info(line)
- stderr_lines = [line.rstrip() for line
- in result.stderr_text.splitlines()]
- for line in stderr_lines:
- self.ssh_logger.warning(line)
-
- self.assertEqual(result.exit_status, 0,
- f'Guest command failed: {command}')
- return stdout_lines, stderr_lines
-
- def ssh_command_output_contains(self, cmd, exp):
- stdout, _ = self.ssh_command(cmd)
- for line in stdout:
- if exp in line:
- break
- else:
- self.fail('"%s" output does not contain "%s"' % (cmd, exp))
diff -Nru qemu-10.0.6+ds/tests/avocado/avocado_qemu/linuxtest.py qemu-10.0.7+ds/tests/avocado/avocado_qemu/linuxtest.py
--- qemu-10.0.6+ds/tests/avocado/avocado_qemu/linuxtest.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/avocado_qemu/linuxtest.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,253 +0,0 @@
-# Test class and utilities for functional Linux-based tests
-#
-# Copyright (c) 2018 Red Hat, Inc.
-#
-# Author:
-# Cleber Rosa <crosa@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-import shutil
-
-from avocado.utils import cloudinit, datadrainer, process, vmimage
-
-from avocado_qemu import LinuxSSHMixIn
-from avocado_qemu import QemuSystemTest
-
-if os.path.islink(os.path.dirname(os.path.dirname(__file__))):
- # The link to the avocado tests dir in the source code directory
- lnk = os.path.dirname(os.path.dirname(__file__))
- #: The QEMU root source directory
- SOURCE_DIR = os.path.dirname(os.path.dirname(os.readlink(lnk)))
-else:
- SOURCE_DIR = BUILD_DIR
-
-class LinuxDistro:
- """Represents a Linux distribution
-
- Holds information of known distros.
- """
- #: A collection of known distros and their respective image checksum
- KNOWN_DISTROS = {
- 'fedora': {
- '31': {
- 'x86_64':
- {'checksum': ('e3c1b309d9203604922d6e255c2c5d09'
- '8a309c2d46215d8fc026954f3c5c27a0'),
- 'pxeboot_url': ('https://archives.fedoraproject.org/'
- 'pub/archive/fedora/linux/releases/31/'
- 'Everything/x86_64/os/images/pxeboot/'),
- 'kernel_params': ('root=UUID=b1438b9b-2cab-4065-a99a-'
- '08a96687f73c ro no_timer_check '
- 'net.ifnames=0 console=tty1 '
- 'console=ttyS0,115200n8'),
- },
- 'aarch64':
- {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae'
- 'd2af0ad0329383d5639c997fdf16fe49'),
- 'pxeboot_url': 'https://archives.fedoraproject.org/'
- 'pub/archive/fedora/linux/releases/31/'
- 'Everything/aarch64/os/images/pxeboot/',
- 'kernel_params': ('root=UUID=b6950a44-9f3c-4076-a9c2-'
- '355e8475b0a7 ro earlyprintk=pl011,0x9000000'
- ' ignore_loglevel no_timer_check'
- ' printk.time=1 rd_NO_PLYMOUTH'
- ' console=ttyAMA0'),
- },
- 'ppc64':
- {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4'
- '3f991c506f2cc390dc4efa2026ad2f58')},
- 's390x':
- {'checksum': ('4caaab5a434fd4d1079149a072fdc789'
- '1e354f834d355069ca982fdcaf5a122d')},
- },
- '32': {
- 'aarch64':
- {'checksum': ('b367755c664a2d7a26955bbfff985855'
- 'adfa2ca15e908baf15b4b176d68d3967'),
- 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/'
- 'releases/32/Server/aarch64/os/images/'
- 'pxeboot/'),
- 'kernel_params': ('root=UUID=3df75b65-be8d-4db4-8655-'
- '14d95c0e90c5 ro no_timer_check net.ifnames=0'
- ' console=tty1 console=ttyS0,115200n8'),
- },
- },
- '33': {
- 'aarch64':
- {'checksum': ('e7f75cdfd523fe5ac2ca9eeece68edc1'
- 'a81f386a17f969c1d1c7c87031008a6b'),
- 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/linux/'
- 'releases/33/Server/aarch64/os/images/'
- 'pxeboot/'),
- 'kernel_params': ('root=UUID=d20b3ffa-6397-4a63-a734-'
- '1126a0208f8a ro no_timer_check net.ifnames=0'
- ' console=tty1 console=ttyS0,115200n8'
- ' console=tty0'),
- },
- },
- }
- }
-
- def __init__(self, name, version, arch):
- self.name = name
- self.version = version
- self.arch = arch
- try:
- info = self.KNOWN_DISTROS.get(name).get(version).get(arch)
- except AttributeError:
- # Unknown distro
- info = None
- self._info = info or {}
-
- @property
- def checksum(self):
- """Gets the cloud-image file checksum"""
- return self._info.get('checksum', None)
-
- @checksum.setter
- def checksum(self, value):
- self._info['checksum'] = value
-
- @property
- def pxeboot_url(self):
- """Gets the repository url where pxeboot files can be found"""
- return self._info.get('pxeboot_url', None)
-
- @property
- def default_kernel_params(self):
- """Gets the default kernel parameters"""
- return self._info.get('kernel_params', None)
-
-
-class LinuxTest(LinuxSSHMixIn, QemuSystemTest):
- """Facilitates having a cloud-image Linux based available.
-
- For tests that intend to interact with guests, this is a better choice
- to start with than the more vanilla `QemuSystemTest` class.
- """
-
- distro = None
- username = 'root'
- password = 'password'
- smp = '2'
- memory = '1024'
-
- def _set_distro(self):
- distro_name = self.params.get(
- 'distro',
- default=self._get_unique_tag_val('distro'))
- if not distro_name:
- distro_name = 'fedora'
-
- distro_version = self.params.get(
- 'distro_version',
- default=self._get_unique_tag_val('distro_version'))
- if not distro_version:
- distro_version = '31'
-
- self.distro = LinuxDistro(distro_name, distro_version, self.arch)
-
- # The distro checksum behaves differently than distro name and
- # version. First, it does not respect a tag with the same
- # name, given that it's not expected to be used for filtering
- # (distro name versions are the natural choice). Second, the
- # order of precedence is: parameter, attribute and then value
- # from KNOWN_DISTROS.
- distro_checksum = self.params.get('distro_checksum',
- default=None)
- if distro_checksum:
- self.distro.checksum = distro_checksum
-
- def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'):
- super().setUp()
- self.require_netdev('user')
- self._set_distro()
- self.vm.add_args('-smp', self.smp)
- self.vm.add_args('-m', self.memory)
- # The following network device allows for SSH connections
- self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
- '-device', '%s,netdev=vnet' % network_device_type)
- self.set_up_boot()
- if ssh_pubkey is None:
- ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys()
- self.set_up_cloudinit(ssh_pubkey)
-
- def set_up_existing_ssh_keys(self):
- ssh_public_key = os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_rsa.pub')
- source_private_key = os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_rsa')
- ssh_dir = os.path.join(self.workdir, '.ssh')
- os.mkdir(ssh_dir, mode=0o700)
- ssh_private_key = os.path.join(ssh_dir,
- os.path.basename(source_private_key))
- shutil.copyfile(source_private_key, ssh_private_key)
- os.chmod(ssh_private_key, 0o600)
- return (ssh_public_key, ssh_private_key)
-
- def download_boot(self):
- # Set the qemu-img binary.
- # If none is available, the test will cancel.
- vmimage.QEMU_IMG = super().get_qemu_img()
-
- self.log.info('Downloading/preparing boot image')
- # Fedora 31 only provides ppc64le images
- image_arch = self.arch
- if self.distro.name == 'fedora':
- if image_arch == 'ppc64':
- image_arch = 'ppc64le'
-
- try:
- boot = vmimage.get(
- self.distro.name, arch=image_arch, version=self.distro.version,
- checksum=self.distro.checksum,
- algorithm='sha256',
- cache_dir=self.cache_dirs[0],
- snapshot_dir=self.workdir)
- except:
- self.cancel('Failed to download/prepare boot image')
- return boot.path
-
- def prepare_cloudinit(self, ssh_pubkey=None):
- self.log.info('Preparing cloudinit image')
- try:
- cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
- pubkey_content = None
- if ssh_pubkey:
- with open(ssh_pubkey) as pubkey:
- pubkey_content = pubkey.read()
- cloudinit.iso(cloudinit_iso, self.name,
- username=self.username,
- password=self.password,
- # QEMU's hard coded usermode router address
- phone_home_host='10.0.2.2',
- phone_home_port=self.phone_server.server_port,
- authorized_key=pubkey_content)
- except Exception:
- self.cancel('Failed to prepare the cloudinit image')
- return cloudinit_iso
-
- def set_up_boot(self):
- path = self.download_boot()
- self.vm.add_args('-drive', 'file=%s' % path)
-
- def set_up_cloudinit(self, ssh_pubkey=None):
- self.phone_server = cloudinit.PhoneHomeServer(('0.0.0.0', 0),
- self.name)
- cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
- self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
-
- def launch_and_wait(self, set_up_ssh_connection=True):
- self.vm.set_console()
- self.vm.launch()
- console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
- logger=self.log.getChild('console'))
- console_drainer.start()
- self.log.info('VM launched, waiting for boot confirmation from guest')
- while not self.phone_server.instance_phoned_back:
- self.phone_server.handle_request()
-
- if set_up_ssh_connection:
- self.log.info('Setting up the SSH connection')
- self.ssh_connect(self.username, self.ssh_key)
diff -Nru qemu-10.0.6+ds/tests/avocado/boot_linux.py qemu-10.0.7+ds/tests/avocado/boot_linux.py
--- qemu-10.0.6+ds/tests/avocado/boot_linux.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/boot_linux.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,132 +0,0 @@
-# Functional test that boots a complete Linux system via a cloud image
-#
-# Copyright (c) 2018-2020 Red Hat, Inc.
-#
-# Author:
-# Cleber Rosa <crosa@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-
-from avocado_qemu.linuxtest import LinuxTest
-from avocado_qemu import BUILD_DIR
-
-from avocado import skipUnless
-
-
-class BootLinuxX8664(LinuxTest):
- """
- :avocado: tags=arch:x86_64
- """
- timeout = 480
-
- def test_pc_i440fx_tcg(self):
- """
- :avocado: tags=machine:pc
- :avocado: tags=accel:tcg
- """
- self.require_accelerator("tcg")
- self.vm.add_args("-accel", "tcg")
- self.launch_and_wait(set_up_ssh_connection=False)
-
- def test_pc_i440fx_kvm(self):
- """
- :avocado: tags=machine:pc
- :avocado: tags=accel:kvm
- """
- self.require_accelerator("kvm")
- self.vm.add_args("-accel", "kvm")
- self.launch_and_wait(set_up_ssh_connection=False)
-
- def test_pc_q35_tcg(self):
- """
- :avocado: tags=machine:q35
- :avocado: tags=accel:tcg
- """
- self.require_accelerator("tcg")
- self.vm.add_args("-accel", "tcg")
- self.launch_and_wait(set_up_ssh_connection=False)
-
- def test_pc_q35_kvm(self):
- """
- :avocado: tags=machine:q35
- :avocado: tags=accel:kvm
- """
- self.require_accelerator("kvm")
- self.vm.add_args("-accel", "kvm")
- self.launch_and_wait(set_up_ssh_connection=False)
-
-
-# For Aarch64 we only boot KVM tests in CI as booting the current
-# Fedora OS in TCG tests is very heavyweight. There are lighter weight
-# distros which we use in the machine_aarch64_virt.py tests.
-class BootLinuxAarch64(LinuxTest):
- """
- :avocado: tags=arch:aarch64
- :avocado: tags=machine:virt
- """
- timeout = 720
-
- def test_virt_kvm(self):
- """
- :avocado: tags=accel:kvm
- :avocado: tags=cpu:host
- """
- self.require_accelerator("kvm")
- self.vm.add_args("-accel", "kvm")
- self.vm.add_args("-machine", "virt,gic-version=host")
- self.vm.add_args('-bios',
- os.path.join(BUILD_DIR, 'pc-bios',
- 'edk2-aarch64-code.fd'))
- self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
- self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
- self.launch_and_wait(set_up_ssh_connection=False)
-
-
-# See the tux_baseline.py tests for almost the same coverage in a lot
-# less time.
-class BootLinuxPPC64(LinuxTest):
- """
- :avocado: tags=arch:ppc64
- """
-
- timeout = 360
-
- @skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited')
- def test_pseries_tcg(self):
- """
- :avocado: tags=machine:pseries
- :avocado: tags=accel:tcg
- """
- self.require_accelerator("tcg")
- self.vm.add_args("-accel", "tcg")
- self.launch_and_wait(set_up_ssh_connection=False)
-
- def test_pseries_kvm(self):
- """
- :avocado: tags=machine:pseries
- :avocado: tags=accel:kvm
- """
- self.require_accelerator("kvm")
- self.vm.add_args("-accel", "kvm")
- self.vm.add_args("-machine", "cap-ccf-assist=off")
- self.launch_and_wait(set_up_ssh_connection=False)
-
-class BootLinuxS390X(LinuxTest):
- """
- :avocado: tags=arch:s390x
- """
-
- timeout = 240
-
- @skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited')
- def test_s390_ccw_virtio_tcg(self):
- """
- :avocado: tags=machine:s390-ccw-virtio
- :avocado: tags=accel:tcg
- """
- self.require_accelerator("tcg")
- self.vm.add_args("-accel", "tcg")
- self.launch_and_wait(set_up_ssh_connection=False)
diff -Nru qemu-10.0.6+ds/tests/avocado/boot_linux_console.py qemu-10.0.7+ds/tests/avocado/boot_linux_console.py
--- qemu-10.0.6+ds/tests/avocado/boot_linux_console.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/boot_linux_console.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,96 +0,0 @@
-# Functional test that boots a Linux kernel and checks the console
-#
-# Copyright (c) 2018 Red Hat, Inc.
-#
-# Author:
-# Cleber Rosa <crosa@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-import lzma
-import gzip
-import shutil
-
-from avocado import skip
-from avocado import skipUnless
-from avocado import skipUnless
-from avocado_qemu import QemuSystemTest
-from avocado_qemu import exec_command
-from avocado_qemu import exec_command_and_wait_for_pattern
-from avocado_qemu import interrupt_interactive_console_until_pattern
-from avocado_qemu import wait_for_console_pattern
-from avocado.utils import process
-from avocado.utils import archive
-
-class LinuxKernelTest(QemuSystemTest):
- KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
-
- def wait_for_console_pattern(self, success_message, vm=None):
- wait_for_console_pattern(self, success_message,
- failure_message='Kernel panic - not syncing',
- vm=vm)
-
- def extract_from_deb(self, deb, path):
- """
- Extracts a file from a deb package into the test workdir
-
- :param deb: path to the deb archive
- :param path: path within the deb archive of the file to be extracted
- :returns: path of the extracted file
- """
- cwd = os.getcwd()
- os.chdir(self.workdir)
- file_path = process.run("ar t %s" % deb).stdout_text.split()[2]
- process.run("ar x %s %s" % (deb, file_path))
- archive.extract(file_path, self.workdir)
- os.chdir(cwd)
- # Return complete path to extracted file. Because callers to
- # extract_from_deb() specify 'path' with a leading slash, it is
- # necessary to use os.path.relpath() as otherwise os.path.join()
- # interprets it as an absolute path and drops the self.workdir part.
- return os.path.normpath(os.path.join(self.workdir,
- os.path.relpath(path, '/')))
-
- def extract_from_rpm(self, rpm, path):
- """
- Extracts a file from an RPM package into the test workdir.
-
- :param rpm: path to the rpm archive
- :param path: path within the rpm archive of the file to be extracted
- needs to be a relative path (starting with './') because
- cpio(1), which is used to extract the file, expects that.
- :returns: path of the extracted file
- """
- cwd = os.getcwd()
- os.chdir(self.workdir)
- process.run("rpm2cpio %s | cpio -id %s" % (rpm, path), shell=True)
- os.chdir(cwd)
- return os.path.normpath(os.path.join(self.workdir, path))
-
-class BootLinuxConsole(LinuxKernelTest):
- """
- Boots a Linux kernel and checks that the console is operational and the
- kernel command line is properly passed from QEMU to the kernel
- """
- timeout = 90
-
- def test_x86_64_pc(self):
- """
- :avocado: tags=arch:x86_64
- :avocado: tags=machine:pc
- """
- kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
- '/linux/releases/29/Everything/x86_64/os/images/pxeboot'
- '/vmlinuz')
- kernel_hash = '23bebd2680757891cf7adedb033532163a792495'
- kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
-
- self.vm.set_console()
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- self.vm.add_args('-kernel', kernel_path,
- '-append', kernel_command_line)
- self.vm.launch()
- console_pattern = 'Kernel command line: %s' % kernel_command_line
- self.wait_for_console_pattern(console_pattern)
diff -Nru qemu-10.0.6+ds/tests/avocado/linux_ssh_mips_malta.py qemu-10.0.7+ds/tests/avocado/linux_ssh_mips_malta.py
--- qemu-10.0.6+ds/tests/avocado/linux_ssh_mips_malta.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/linux_ssh_mips_malta.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,205 +0,0 @@
-# Functional test that boots a VM and run commands via a SSH session
-#
-# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-import re
-import base64
-import logging
-import time
-
-from avocado import skipUnless
-from avocado_qemu import LinuxSSHMixIn
-from avocado_qemu import QemuSystemTest
-from avocado_qemu import wait_for_console_pattern
-from avocado.utils import process
-from avocado.utils import archive
-from avocado.utils import ssh
-
-
-@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
-@skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available')
-class LinuxSSH(QemuSystemTest, LinuxSSHMixIn):
- """
- :avocado: tags=accel:tcg
- """
-
- timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
-
- KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
- VM_IP = '127.0.0.1'
-
- BASE_URL = 'https://people.debian.org/~aurel32/qemu/'
- IMAGE_INFO = {
- 'be': {'base_url': 'mips',
- 'image_name': 'debian_wheezy_mips_standard.qcow2',
- 'image_hash': '8987a63270df67345b2135a6b7a4885a35e392d5',
- 'kernel_hash': {
- 32: '592e384a4edc16dade52a6cd5c785c637bcbc9ad',
- 64: 'db6eea7de35d36c77d8c165b6bcb222e16eb91db'}
- },
- 'le': {'base_url': 'mipsel',
- 'image_name': 'debian_wheezy_mipsel_standard.qcow2',
- 'image_hash': '7866764d9de3ef536ffca24c9fb9f04ffdb45802',
- 'kernel_hash': {
- 32: 'a66bea5a8adaa2cb3d36a1d4e0ccdb01be8f6c2a',
- 64: '6a7f77245acf231415a0e8b725d91ed2f3487794'}
- }
- }
- CPU_INFO = {
- 32: {'cpu': 'MIPS 24Kc', 'kernel_release': '3.2.0-4-4kc-malta'},
- 64: {'cpu': 'MIPS 20Kc', 'kernel_release': '3.2.0-4-5kc-malta'}
- }
-
- def get_url(self, endianess, path=''):
- qkey = {'le': 'el', 'be': ''}
- return '%s/mips%s/%s' % (self.BASE_URL, qkey[endianess], path)
-
- def get_image_info(self, endianess):
- dinfo = self.IMAGE_INFO[endianess]
- image_url = self.get_url(endianess, dinfo['image_name'])
- image_hash = dinfo['image_hash']
- return (image_url, image_hash)
-
- def get_kernel_info(self, endianess, wordsize):
- minfo = self.CPU_INFO[wordsize]
- kernel_url = self.get_url(endianess,
- 'vmlinux-%s' % minfo['kernel_release'])
- kernel_hash = self.IMAGE_INFO[endianess]['kernel_hash'][wordsize]
- return kernel_url, kernel_hash
-
- def ssh_disconnect_vm(self):
- self.ssh_session.quit()
-
- def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
- image_url, image_hash = self.get_image_info(endianess)
- image_path = self.fetch_asset(image_url, asset_hash=image_hash)
-
- self.vm.set_console()
- kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
- + 'console=ttyS0 root=/dev/sda1')
- self.vm.add_args('-no-reboot',
- '-kernel', kernel_path,
- '-append', kernel_command_line,
- '-drive', 'file=%s,snapshot=on' % image_path,
- '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
- '-device', 'pcnet,netdev=vnet')
- self.vm.launch()
-
- self.log.info('VM launched, waiting for sshd')
- console_pattern = 'Starting OpenBSD Secure Shell server: sshd'
- wait_for_console_pattern(self, console_pattern, 'Oops')
- self.log.info('sshd ready')
-
- self.ssh_connect('root', 'root', False)
-
- def shutdown_via_ssh(self):
- self.ssh_command('poweroff')
- self.ssh_disconnect_vm()
- wait_for_console_pattern(self, 'Power down', 'Oops')
-
- def run_common_commands(self, wordsize):
- self.ssh_command_output_contains(
- 'cat /proc/cpuinfo',
- self.CPU_INFO[wordsize]['cpu'])
- self.ssh_command_output_contains(
- 'uname -m',
- 'mips')
- self.ssh_command_output_contains(
- 'uname -r',
- self.CPU_INFO[wordsize]['kernel_release'])
- self.ssh_command_output_contains(
- 'cat /proc/interrupts',
- 'XT-PIC timer')
- self.ssh_command_output_contains(
- 'cat /proc/interrupts',
- 'XT-PIC i8042')
- self.ssh_command_output_contains(
- 'cat /proc/interrupts',
- 'XT-PIC serial')
- self.ssh_command_output_contains(
- 'cat /proc/interrupts',
- 'XT-PIC ata_piix')
- self.ssh_command_output_contains(
- 'cat /proc/interrupts',
- 'XT-PIC eth0')
- self.ssh_command_output_contains(
- 'cat /proc/devices',
- 'input')
- self.ssh_command_output_contains(
- 'cat /proc/devices',
- 'usb')
- self.ssh_command_output_contains(
- 'cat /proc/devices',
- 'fb')
- self.ssh_command_output_contains(
- 'cat /proc/ioports',
- ' : serial')
- self.ssh_command_output_contains(
- 'cat /proc/ioports',
- ' : ata_piix')
- self.ssh_command_output_contains(
- 'cat /proc/ioports',
- ' : piix4_smbus')
- self.ssh_command_output_contains(
- 'lspci -d 11ab:4620',
- 'GT-64120')
- self.ssh_command_output_contains(
- 'cat /sys/bus/i2c/devices/i2c-0/name',
- 'SMBus PIIX4 adapter')
- self.ssh_command_output_contains(
- 'cat /proc/mtd',
- 'YAMON')
- # Empty 'Board Config' (64KB)
- self.ssh_command_output_contains(
- 'md5sum /dev/mtd2ro',
- '0dfbe8aa4c20b52e1b8bf3cb6cbdf193')
-
- def check_mips_malta(self, uname_m, endianess):
- wordsize = 64 if '64' in uname_m else 32
- kernel_url, kernel_hash = self.get_kernel_info(endianess, wordsize)
- kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
- self.boot_debian_wheezy_image_and_ssh_login(endianess, kernel_path)
-
- stdout, _ = self.ssh_command('uname -a')
- self.assertIn(True, [uname_m + " GNU/Linux" in line for line in stdout])
-
- self.run_common_commands(wordsize)
- self.shutdown_via_ssh()
- # Wait for VM to shut down gracefully
- self.vm.wait()
-
- def test_mips_malta32eb_kernel3_2_0(self):
- """
- :avocado: tags=arch:mips
- :avocado: tags=endian:big
- :avocado: tags=device:pcnet32
- """
- self.check_mips_malta('mips', 'be')
-
- def test_mips_malta32el_kernel3_2_0(self):
- """
- :avocado: tags=arch:mipsel
- :avocado: tags=endian:little
- :avocado: tags=device:pcnet32
- """
- self.check_mips_malta('mips', 'le')
-
- def test_mips_malta64eb_kernel3_2_0(self):
- """
- :avocado: tags=arch:mips64
- :avocado: tags=endian:big
- :avocado: tags=device:pcnet32
- """
- self.check_mips_malta('mips64', 'be')
-
- def test_mips_malta64el_kernel3_2_0(self):
- """
- :avocado: tags=arch:mips64el
- :avocado: tags=endian:little
- :avocado: tags=device:pcnet32
- """
- self.check_mips_malta('mips64', 'le')
diff -Nru qemu-10.0.6+ds/tests/avocado/replay_kernel.py qemu-10.0.7+ds/tests/avocado/replay_kernel.py
--- qemu-10.0.6+ds/tests/avocado/replay_kernel.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/replay_kernel.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,110 +0,0 @@
-# Record/replay test that boots a Linux kernel
-#
-# Copyright (c) 2020 ISP RAS
-#
-# Author:
-# Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-import lzma
-import shutil
-import logging
-import time
-import subprocess
-
-from avocado import skip
-from avocado import skipUnless
-from avocado import skipUnless
-from avocado_qemu import wait_for_console_pattern
-from avocado.utils import archive
-from avocado.utils import process
-from boot_linux_console import LinuxKernelTest
-
-class ReplayKernelBase(LinuxKernelTest):
- """
- Boots a Linux kernel in record mode and checks that the console
- is operational and the kernel command line is properly passed
- from QEMU to the kernel.
- Then replays the same scenario and verifies, that QEMU correctly
- terminates.
- """
-
- timeout = 180
- KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 '
-
- def run_vm(self, kernel_path, kernel_command_line, console_pattern,
- record, shift, args, replay_path):
- # icount requires TCG to be available
- self.require_accelerator('tcg')
-
- logger = logging.getLogger('replay')
- start_time = time.time()
- vm = self.get_vm()
- vm.set_console()
- if record:
- logger.info('recording the execution...')
- mode = 'record'
- else:
- logger.info('replaying the execution...')
- mode = 'replay'
- vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
- (shift, mode, replay_path),
- '-kernel', kernel_path,
- '-append', kernel_command_line,
- '-net', 'none',
- '-no-reboot')
- if args:
- vm.add_args(*args)
- vm.launch()
- self.wait_for_console_pattern(console_pattern, vm)
- if record:
- vm.shutdown()
- logger.info('finished the recording with log size %s bytes'
- % os.path.getsize(replay_path))
- self.run_replay_dump(replay_path)
- logger.info('successfully tested replay-dump.py')
- else:
- vm.wait()
- logger.info('successfully finished the replay')
- elapsed = time.time() - start_time
- logger.info('elapsed time %.2f sec' % elapsed)
- return elapsed
-
- def run_replay_dump(self, replay_path):
- try:
- subprocess.check_call(["./scripts/replay-dump.py",
- "-f", replay_path],
- stdout=subprocess.DEVNULL)
- except subprocess.CalledProcessError:
- self.fail('replay-dump.py failed')
-
- def run_rr(self, kernel_path, kernel_command_line, console_pattern,
- shift=7, args=None):
- replay_path = os.path.join(self.workdir, 'replay.bin')
- t1 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
- True, shift, args, replay_path)
- t2 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
- False, shift, args, replay_path)
- logger = logging.getLogger('replay')
- logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
-
-class ReplayKernelNormal(ReplayKernelBase):
-
- def test_i386_pc(self):
- """
- :avocado: tags=arch:i386
- :avocado: tags=machine:pc
- """
- kernel_url = ('https://storage.tuxboot.com/20230331/i386/bzImage')
- kernel_hash = 'a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956'
- kernel_path = self.fetch_asset(kernel_url,
- asset_hash=kernel_hash,
- algorithm = "sha256")
-
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- console_pattern = 'VFS: Cannot open root device'
-
- self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
diff -Nru qemu-10.0.6+ds/tests/avocado/replay_linux.py qemu-10.0.7+ds/tests/avocado/replay_linux.py
--- qemu-10.0.6+ds/tests/avocado/replay_linux.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/replay_linux.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,206 +0,0 @@
-# Record/replay test that boots a complete Linux system via a cloud image
-#
-# Copyright (c) 2020 ISP RAS
-#
-# Author:
-# Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-import os
-import logging
-import time
-
-from avocado import skipUnless
-from avocado_qemu import BUILD_DIR
-from avocado.utils import cloudinit
-from avocado.utils import network
-from avocado.utils import vmimage
-from avocado.utils import datadrainer
-from avocado.utils.path import find_command
-from avocado_qemu.linuxtest import LinuxTest
-
-class ReplayLinux(LinuxTest):
- """
- Boots a Linux system, checking for a successful initialization
- """
-
- timeout = 1800
- chksum = None
- hdd = 'ide-hd'
- cd = 'ide-cd'
- bus = 'ide'
-
- def setUp(self):
- # LinuxTest does many replay-incompatible things, but includes
- # useful methods. Do not setup LinuxTest here and just
- # call some functions.
- super(LinuxTest, self).setUp()
- self._set_distro()
- self.boot_path = self.download_boot()
- self.phone_server = cloudinit.PhoneHomeServer(('0.0.0.0', 0),
- self.name)
- ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys()
- self.cloudinit_path = self.prepare_cloudinit(ssh_pubkey)
-
- def vm_add_disk(self, vm, path, id, device):
- bus_string = ''
- if self.bus:
- bus_string = ',bus=%s.%d' % (self.bus, id,)
- vm.add_args('-drive', 'file=%s,snapshot=on,id=disk%s,if=none' % (path, id))
- vm.add_args('-drive',
- 'driver=blkreplay,id=disk%s-rr,if=none,image=disk%s' % (id, id))
- vm.add_args('-device',
- '%s,drive=disk%s-rr%s' % (device, id, bus_string))
-
- def vm_add_cdrom(self, vm, path, id, device):
- vm.add_args('-drive', 'file=%s,id=disk%s,if=none,media=cdrom' % (path, id))
-
- def launch_and_wait(self, record, args, shift):
- self.require_netdev('user')
- vm = self.get_vm()
- vm.add_args('-smp', '1')
- vm.add_args('-m', '1024')
- vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
- '-device', 'virtio-net,netdev=vnet')
- vm.add_args('-object', 'filter-replay,id=replay,netdev=vnet')
- if args:
- vm.add_args(*args)
- self.vm_add_disk(vm, self.boot_path, 0, self.hdd)
- self.vm_add_cdrom(vm, self.cloudinit_path, 1, self.cd)
- logger = logging.getLogger('replay')
- if record:
- logger.info('recording the execution...')
- mode = 'record'
- else:
- logger.info('replaying the execution...')
- mode = 'replay'
- replay_path = os.path.join(self.workdir, 'replay.bin')
- vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
- (shift, mode, replay_path))
-
- start_time = time.time()
-
- vm.set_console()
- vm.launch()
- console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(),
- logger=self.log.getChild('console'),
- stop_check=(lambda : not vm.is_running()))
- console_drainer.start()
- if record:
- while not self.phone_server.instance_phoned_back:
- self.phone_server.handle_request()
- vm.shutdown()
- logger.info('finished the recording with log size %s bytes'
- % os.path.getsize(replay_path))
- self.run_replay_dump(replay_path)
- logger.info('successfully tested replay-dump.py')
- else:
- vm.event_wait('SHUTDOWN', self.timeout)
- vm.wait()
- logger.info('successfully finished the replay')
- elapsed = time.time() - start_time
- logger.info('elapsed time %.2f sec' % elapsed)
- return elapsed
-
- def run_rr(self, args=None, shift=7):
- t1 = self.launch_and_wait(True, args, shift)
- t2 = self.launch_and_wait(False, args, shift)
- logger = logging.getLogger('replay')
- logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
-
- def run_replay_dump(self, replay_path):
- try:
- subprocess.check_call(["./scripts/replay-dump.py",
- "-f", replay_path],
- stdout=subprocess.DEVNULL)
- except subprocess.CalledProcessError:
- self.fail('replay-dump.py failed')
-
-@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
-class ReplayLinuxX8664(ReplayLinux):
- """
- :avocado: tags=arch:x86_64
- :avocado: tags=accel:tcg
- """
-
- chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
-
- def test_pc_i440fx(self):
- """
- :avocado: tags=machine:pc
- """
- self.run_rr(shift=1)
-
- def test_pc_q35(self):
- """
- :avocado: tags=machine:q35
- """
- self.run_rr(shift=3)
-
-@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
-class ReplayLinuxX8664Virtio(ReplayLinux):
- """
- :avocado: tags=arch:x86_64
- :avocado: tags=virtio
- :avocado: tags=accel:tcg
- """
-
- hdd = 'virtio-blk-pci'
- cd = 'virtio-blk-pci'
- bus = None
-
- chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
-
- def test_pc_i440fx(self):
- """
- :avocado: tags=machine:pc
- """
- self.run_rr(shift=1)
-
- def test_pc_q35(self):
- """
- :avocado: tags=machine:q35
- """
- self.run_rr(shift=3)
-
-@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
-class ReplayLinuxAarch64(ReplayLinux):
- """
- :avocado: tags=accel:tcg
- :avocado: tags=arch:aarch64
- :avocado: tags=machine:virt
- :avocado: tags=cpu:max
- """
-
- chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
-
- hdd = 'virtio-blk-device'
- cd = 'virtio-blk-device'
- bus = None
-
- def get_common_args(self):
- return ('-bios',
- os.path.join(BUILD_DIR, 'pc-bios', 'edk2-aarch64-code.fd'),
- "-cpu", "max,lpa2=off",
- '-device', 'virtio-rng-pci,rng=rng0',
- '-object', 'rng-builtin,id=rng0')
-
- def test_virt_gicv2(self):
- """
- :avocado: tags=machine:gic-version=2
- """
-
- self.run_rr(shift=3,
- args=(*self.get_common_args(),
- "-machine", "virt,gic-version=2"))
-
- def test_virt_gicv3(self):
- """
- :avocado: tags=machine:gic-version=3
- """
-
- self.run_rr(shift=3,
- args=(*self.get_common_args(),
- "-machine", "virt,gic-version=3"))
diff -Nru qemu-10.0.6+ds/tests/avocado/reverse_debugging.py qemu-10.0.7+ds/tests/avocado/reverse_debugging.py
--- qemu-10.0.6+ds/tests/avocado/reverse_debugging.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/reverse_debugging.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,272 +0,0 @@
-# Reverse debugging test
-#
-# Copyright (c) 2020 ISP RAS
-#
-# Author:
-# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-import os
-import logging
-
-from avocado import skipUnless
-from avocado_qemu import BUILD_DIR
-from avocado.utils import datadrainer
-from avocado.utils import gdb
-from avocado.utils import process
-from avocado.utils.network.ports import find_free_port
-from avocado.utils.path import find_command
-from boot_linux_console import LinuxKernelTest
-
-class ReverseDebugging(LinuxKernelTest):
- """
- Test GDB reverse debugging commands: reverse step and reverse continue.
- Recording saves the execution of some instructions and makes an initial
- VM snapshot to allow reverse execution.
- Replay saves the order of the first instructions and then checks that they
- are executed backwards in the correct order.
- After that the execution is replayed to the end, and reverse continue
- command is checked by setting several breakpoints, and asserting
- that the execution is stopped at the last of them.
- """
-
- timeout = 10
- STEPS = 10
- endian_is_le = True
-
- def run_vm(self, record, shift, args, replay_path, image_path, port):
- logger = logging.getLogger('replay')
- vm = self.get_vm()
- vm.set_console()
- if record:
- logger.info('recording the execution...')
- mode = 'record'
- else:
- logger.info('replaying the execution...')
- mode = 'replay'
- vm.add_args('-gdb', 'tcp::%d' % port, '-S')
- vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' %
- (shift, mode, replay_path),
- '-net', 'none')
- vm.add_args('-drive', 'file=%s,if=none' % image_path)
- if args:
- vm.add_args(*args)
- vm.launch()
- console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(),
- logger=self.log.getChild('console'),
- stop_check=(lambda : not vm.is_running()))
- console_drainer.start()
- return vm
-
- @staticmethod
- def get_reg_le(g, reg):
- res = g.cmd(b'p%x' % reg)
- num = 0
- for i in range(len(res))[-2::-2]:
- num = 0x100 * num + int(res[i:i + 2], 16)
- return num
-
- @staticmethod
- def get_reg_be(g, reg):
- res = g.cmd(b'p%x' % reg)
- return int(res, 16)
-
- def get_reg(self, g, reg):
- # value may be encoded in BE or LE order
- if self.endian_is_le:
- return self.get_reg_le(g, reg)
- else:
- return self.get_reg_be(g, reg)
-
- def get_pc(self, g):
- return self.get_reg(g, self.REG_PC)
-
- def check_pc(self, g, addr):
- pc = self.get_pc(g)
- if pc != addr:
- self.fail('Invalid PC (read %x instead of %x)' % (pc, addr))
-
- @staticmethod
- def gdb_step(g):
- g.cmd(b's', b'T05thread:01;')
-
- @staticmethod
- def gdb_bstep(g):
- g.cmd(b'bs', b'T05thread:01;')
-
- @staticmethod
- def vm_get_icount(vm):
- return vm.qmp('query-replay')['return']['icount']
-
- def reverse_debugging(self, shift=7, args=None):
- logger = logging.getLogger('replay')
-
- # create qcow2 for snapshots
- logger.info('creating qcow2 image for VM snapshots')
- image_path = os.path.join(self.workdir, 'disk.qcow2')
- qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
- if not os.path.exists(qemu_img):
- qemu_img = find_command('qemu-img', False)
- if qemu_img is False:
- self.cancel('Could not find "qemu-img", which is required to '
- 'create the temporary qcow2 image')
- cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path)
- process.run(cmd)
-
- replay_path = os.path.join(self.workdir, 'replay.bin')
- port = find_free_port()
-
- # record the log
- vm = self.run_vm(True, shift, args, replay_path, image_path, port)
- while self.vm_get_icount(vm) <= self.STEPS:
- pass
- last_icount = self.vm_get_icount(vm)
- vm.shutdown()
-
- logger.info("recorded log with %s+ steps" % last_icount)
-
- # replay and run debug commands
- vm = self.run_vm(False, shift, args, replay_path, image_path, port)
- logger.info('connecting to gdbstub')
- g = gdb.GDBRemote('127.0.0.1', port, False, False)
- g.connect()
- r = g.cmd(b'qSupported')
- if b'qXfer:features:read+' in r:
- g.cmd(b'qXfer:features:read:target.xml:0,ffb')
- if b'ReverseStep+' not in r:
- self.fail('Reverse step is not supported by QEMU')
- if b'ReverseContinue+' not in r:
- self.fail('Reverse continue is not supported by QEMU')
-
- logger.info('stepping forward')
- steps = []
- # record first instruction addresses
- for _ in range(self.STEPS):
- pc = self.get_pc(g)
- logger.info('saving position %x' % pc)
- steps.append(pc)
- self.gdb_step(g)
-
- # visit the recorded instruction in reverse order
- logger.info('stepping backward')
- for addr in steps[::-1]:
- self.gdb_bstep(g)
- self.check_pc(g, addr)
- logger.info('found position %x' % addr)
-
- # visit the recorded instruction in forward order
- logger.info('stepping forward')
- for addr in steps:
- self.check_pc(g, addr)
- self.gdb_step(g)
- logger.info('found position %x' % addr)
-
- # set breakpoints for the instructions just stepped over
- logger.info('setting breakpoints')
- for addr in steps:
- # hardware breakpoint at addr with len=1
- g.cmd(b'Z1,%x,1' % addr, b'OK')
-
- # this may hit a breakpoint if first instructions are executed
- # again
- logger.info('continuing execution')
- vm.qmp('replay-break', icount=last_icount - 1)
- # continue - will return after pausing
- # This could stop at the end and get a T02 return, or by
- # re-executing one of the breakpoints and get a T05 return.
- g.cmd(b'c')
- if self.vm_get_icount(vm) == last_icount - 1:
- logger.info('reached the end (icount %s)' % (last_icount - 1))
- else:
- logger.info('hit a breakpoint again at %x (icount %s)' %
- (self.get_pc(g), self.vm_get_icount(vm)))
-
- logger.info('running reverse continue to reach %x' % steps[-1])
- # reverse continue - will return after stopping at the breakpoint
- g.cmd(b'bc', b'T05thread:01;')
-
- # assume that none of the first instructions is executed again
- # breaking the order of the breakpoints
- self.check_pc(g, steps[-1])
- logger.info('successfully reached %x' % steps[-1])
-
- logger.info('exiting gdb and qemu')
- vm.shutdown()
-
-class ReverseDebugging_X86_64(ReverseDebugging):
- """
- :avocado: tags=accel:tcg
- """
-
- REG_PC = 0x10
- REG_CS = 0x12
- def get_pc(self, g):
- return self.get_reg_le(g, self.REG_PC) \
- + self.get_reg_le(g, self.REG_CS) * 0x10
-
- # unidentified gitlab timeout problem
- @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
- def test_x86_64_pc(self):
- """
- :avocado: tags=arch:x86_64
- :avocado: tags=machine:pc
- """
- # start with BIOS only
- self.reverse_debugging()
-
-class ReverseDebugging_AArch64(ReverseDebugging):
- """
- :avocado: tags=accel:tcg
- """
-
- REG_PC = 32
-
- # unidentified gitlab timeout problem
- @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
- def test_aarch64_virt(self):
- """
- :avocado: tags=arch:aarch64
- :avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53
- """
- kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
- '/linux/releases/29/Everything/aarch64/os/images/pxeboot'
- '/vmlinuz')
- kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493'
- kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
-
- self.reverse_debugging(
- args=('-kernel', kernel_path))
-
-class ReverseDebugging_ppc64(ReverseDebugging):
- """
- :avocado: tags=accel:tcg
- """
-
- REG_PC = 0x40
-
- # unidentified gitlab timeout problem
- @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
- def test_ppc64_pseries(self):
- """
- :avocado: tags=arch:ppc64
- :avocado: tags=machine:pseries
- :avocado: tags=flaky
- """
- # SLOF branches back to its entry point, which causes this test
- # to take the 'hit a breakpoint again' path. That's not a problem,
- # just slightly different than the other machines.
- self.endian_is_le = False
- self.reverse_debugging()
-
- # See https://gitlab.com/qemu-project/qemu/-/issues/1992
- @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
- def test_ppc64_powernv(self):
- """
- :avocado: tags=arch:ppc64
- :avocado: tags=machine:powernv
- :avocado: tags=flaky
- """
- self.endian_is_le = False
- self.reverse_debugging()
diff -Nru qemu-10.0.6+ds/tests/avocado/smmu.py qemu-10.0.7+ds/tests/avocado/smmu.py
--- qemu-10.0.6+ds/tests/avocado/smmu.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/avocado/smmu.py 1970-01-01 03:00:00.000000000 +0300
@@ -1,139 +0,0 @@
-# SMMUv3 Functional tests
-#
-# Copyright (c) 2021 Red Hat, Inc.
-#
-# Author:
-# Eric Auger <eric.auger@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-import os
-
-from avocado import skipUnless
-from avocado_qemu import BUILD_DIR
-from avocado_qemu.linuxtest import LinuxTest
-
-@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
-class SMMU(LinuxTest):
- """
- :avocado: tags=accel:kvm
- :avocado: tags=cpu:host
- :avocado: tags=arch:aarch64
- :avocado: tags=machine:virt
- :avocado: tags=distro:fedora
- :avocado: tags=smmu
- :avocado: tags=flaky
- """
-
- IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
- kernel_path = None
- initrd_path = None
- kernel_params = None
-
- def set_up_boot(self):
- path = self.download_boot()
- self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
- 'drive=drv0,id=virtio-disk0,bootindex=1,'
- 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
- self.vm.add_args('-drive',
- 'file=%s,if=none,cache=writethrough,id=drv0' % path)
-
- def setUp(self):
- super(SMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON)
-
- def common_vm_setup(self, custom_kernel=False):
- self.require_accelerator("kvm")
- self.vm.add_args("-accel", "kvm")
- self.vm.add_args("-cpu", "host")
- self.vm.add_args("-machine", "iommu=smmuv3")
- self.vm.add_args("-d", "guest_errors")
- self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
- 'edk2-aarch64-code.fd'))
- self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
- self.vm.add_args('-object',
- 'rng-random,id=rng0,filename=/dev/urandom')
-
- if custom_kernel is False:
- return
-
- kernel_url = self.distro.pxeboot_url + 'vmlinuz'
- initrd_url = self.distro.pxeboot_url + 'initrd.img'
- self.kernel_path = self.fetch_asset(kernel_url)
- self.initrd_path = self.fetch_asset(initrd_url)
-
- def run_and_check(self):
- if self.kernel_path:
- self.vm.add_args('-kernel', self.kernel_path,
- '-append', self.kernel_params,
- '-initrd', self.initrd_path)
- self.launch_and_wait()
- self.ssh_command('cat /proc/cmdline')
- self.ssh_command('dnf -y install numactl-devel')
-
-
- # 5.3 kernel without RIL #
-
- def test_smmu_noril(self):
- """
- :avocado: tags=smmu_noril
- :avocado: tags=smmu_noril_tests
- :avocado: tags=distro_version:31
- """
- self.common_vm_setup()
- self.run_and_check()
-
- def test_smmu_noril_passthrough(self):
- """
- :avocado: tags=smmu_noril_passthrough
- :avocado: tags=smmu_noril_tests
- :avocado: tags=distro_version:31
- """
- self.common_vm_setup(True)
- self.kernel_params = (self.distro.default_kernel_params +
- ' iommu.passthrough=on')
- self.run_and_check()
-
- def test_smmu_noril_nostrict(self):
- """
- :avocado: tags=smmu_noril_nostrict
- :avocado: tags=smmu_noril_tests
- :avocado: tags=distro_version:31
- """
- self.common_vm_setup(True)
- self.kernel_params = (self.distro.default_kernel_params +
- ' iommu.strict=0')
- self.run_and_check()
-
- # 5.8 kernel featuring range invalidation
- # >= v5.7 kernel
-
- def test_smmu_ril(self):
- """
- :avocado: tags=smmu_ril
- :avocado: tags=smmu_ril_tests
- :avocado: tags=distro_version:33
- """
- self.common_vm_setup()
- self.run_and_check()
-
- def test_smmu_ril_passthrough(self):
- """
- :avocado: tags=smmu_ril_passthrough
- :avocado: tags=smmu_ril_tests
- :avocado: tags=distro_version:33
- """
- self.common_vm_setup(True)
- self.kernel_params = (self.distro.default_kernel_params +
- ' iommu.passthrough=on')
- self.run_and_check()
-
- def test_smmu_ril_nostrict(self):
- """
- :avocado: tags=smmu_ril_nostrict
- :avocado: tags=smmu_ril_tests
- :avocado: tags=distro_version:33
- """
- self.common_vm_setup(True)
- self.kernel_params = (self.distro.default_kernel_params +
- ' iommu.strict=0')
- self.run_and_check()
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/aarch64/virt/DSDT and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/aarch64/virt/DSDT differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/aarch64/virt/DSDT.memhp and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/aarch64/virt/DSDT.memhp differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/aarch64/virt/DSDT.pxb and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/aarch64/virt/DSDT.pxb differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/aarch64/virt/DSDT.topology and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/aarch64/virt/DSDT.topology differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/riscv64/virt/DSDT and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/riscv64/virt/DSDT differ
Binary files /tmp/Rlrz8EVmJS/qemu-10.0.6+ds/tests/data/acpi/x86/microvm/DSDT.pcie and /tmp/ANY00v7pVL/qemu-10.0.7+ds/tests/data/acpi/x86/microvm/DSDT.pcie differ
diff -Nru qemu-10.0.6+ds/tests/functional/aspeed.py qemu-10.0.7+ds/tests/functional/aspeed.py
--- qemu-10.0.6+ds/tests/functional/aspeed.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/aspeed.py 2025-12-06 17:54:24.000000000 +0300
@@ -44,7 +44,7 @@
def do_test_arm_aspeed_buildroot_poweroff(self):
exec_command_and_wait_for_pattern(self, 'poweroff',
- 'System halted');
+ 'System halted')
def do_test_arm_aspeed_sdk_start(self, image):
self.require_netdev('user')
diff -Nru qemu-10.0.6+ds/tests/functional/meson.build qemu-10.0.7+ds/tests/functional/meson.build
--- qemu-10.0.6+ds/tests/functional/meson.build 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/meson.build 2025-12-06 17:54:24.000000000 +0300
@@ -13,10 +13,12 @@
test_timeouts = {
'aarch64_aspeed' : 600,
'aarch64_raspi4' : 480,
+ 'aarch64_reverse_debug' : 180,
'aarch64_rme_virt' : 1200,
'aarch64_rme_sbsaref' : 1200,
'aarch64_sbsaref_alpine' : 1200,
'aarch64_sbsaref_freebsd' : 720,
+ 'aarch64_smmu' : 720,
'aarch64_tuxrun' : 240,
'aarch64_virt' : 360,
'aarch64_virt_gpu' : 480,
@@ -38,8 +40,11 @@
'arm_tuxrun' : 240,
'arm_sx1' : 360,
'intel_iommu': 300,
- 'mips_malta' : 120,
+ 'mips_malta' : 480,
+ 'mipsel_malta' : 420,
'mipsel_replay' : 480,
+ 'mips64_malta' : 240,
+ 'mips64el_malta' : 420,
'mips64el_replay' : 180,
'netdev_ethtool' : 180,
'ppc_40p' : 240,
@@ -78,11 +83,13 @@
'aarch64_raspi3',
'aarch64_raspi4',
'aarch64_replay',
+ 'aarch64_reverse_debug',
'aarch64_rme_virt',
'aarch64_rme_sbsaref',
'aarch64_sbsaref',
'aarch64_sbsaref_alpine',
'aarch64_sbsaref_freebsd',
+ 'aarch64_smmu',
'aarch64_tcg_plugins',
'aarch64_tuxrun',
'aarch64_virt',
@@ -149,6 +156,7 @@
]
tests_i386_system_thorough = [
+ 'i386_replay',
'i386_tuxrun',
]
@@ -186,6 +194,7 @@
]
tests_mips64_system_thorough = [
+ 'mips64_malta',
'mips64_tuxrun',
]
@@ -229,6 +238,7 @@
'ppc64_powernv',
'ppc64_pseries',
'ppc64_replay',
+ 'ppc64_reverse_debug',
'ppc64_tuxrun',
'ppc64_mac99',
]
@@ -311,6 +321,7 @@
'x86_64_hotplug_cpu',
'x86_64_kvm_xen',
'x86_64_replay',
+ 'x86_64_reverse_debug',
'x86_64_tuxrun',
]
diff -Nru qemu-10.0.6+ds/tests/functional/qemu_test/asset.py qemu-10.0.7+ds/tests/functional/qemu_test/asset.py
--- qemu-10.0.6+ds/tests/functional/qemu_test/asset.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/qemu_test/asset.py 2025-12-06 17:54:24.000000000 +0300
@@ -15,7 +15,7 @@
from time import sleep
from pathlib import Path
from shutil import copyfileobj
-from urllib.error import HTTPError
+from urllib.error import HTTPError, URLError
class AssetError(Exception):
def __init__(self, asset, msg, transient=False):
@@ -167,9 +167,17 @@
raise AssetError(self, "Unable to download: "
"HTTP error %d" % e.code)
continue
+ except URLError as e:
+ # This is typically a network/service level error
+ # eg urlopen error [Errno 110] Connection timed out>
+ tmp_cache_file.unlink()
+ self.log.error("Unable to download %s: URL error %s",
+ self.url, e.reason)
+ raise AssetError(self, "Unable to download: URL error %s" %
+ e.reason, transient=True)
except Exception as e:
tmp_cache_file.unlink()
- raise AssetError(self, "Unable to download: " % e)
+ raise AssetError(self, "Unable to download: %s" % e)
if not os.path.exists(tmp_cache_file):
raise AssetError(self, "Download retries exceeded", transient=True)
diff -Nru qemu-10.0.6+ds/tests/functional/qemu_test/ports.py qemu-10.0.7+ds/tests/functional/qemu_test/ports.py
--- qemu-10.0.6+ds/tests/functional/qemu_test/ports.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/qemu_test/ports.py 2025-12-06 17:54:24.000000000 +0300
@@ -10,12 +10,11 @@
import fcntl
import os
import socket
-import sys
-import tempfile
from .config import BUILD_DIR
from typing import List
+
class Ports():
PORTS_ADDR = '127.0.0.1'
diff -Nru qemu-10.0.6+ds/tests/functional/qemu_test/tuxruntest.py qemu-10.0.7+ds/tests/functional/qemu_test/tuxruntest.py
--- qemu-10.0.6+ds/tests/functional/qemu_test/tuxruntest.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/qemu_test/tuxruntest.py 2025-12-06 17:54:24.000000000 +0300
@@ -10,8 +10,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import os
-import stat
-from subprocess import check_call, DEVNULL
from qemu_test import QemuSystemTest
from qemu_test import exec_command_and_wait_for_pattern
@@ -77,12 +75,12 @@
blockdev = "driver=raw,file.driver=file," \
+ f"file.filename={disk},node-name=hd0"
- kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
- kcmd_line += f" root=/dev/{self.root}"
- kcmd_line += f" console={self.console}"
+ self.kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
+ self.kcmd_line += f" root=/dev/{self.root}"
+ self.kcmd_line += f" console={self.console}"
self.vm.add_args('-kernel', kernel,
- '-append', kcmd_line,
+ '-append', self.kcmd_line,
'-blockdev', blockdev)
# Sometimes we need extra devices attached
@@ -103,6 +101,7 @@
wait to exit cleanly.
"""
ps1='root@tuxtest:~#'
+ self.wait_for_console_pattern(self.kcmd_line)
self.wait_for_console_pattern('tuxtest login:')
exec_command_and_wait_for_pattern(self, 'root', ps1)
exec_command_and_wait_for_pattern(self, 'cat /proc/interrupts', ps1)
diff -Nru qemu-10.0.6+ds/tests/functional/qemu_test/uncompress.py qemu-10.0.7+ds/tests/functional/qemu_test/uncompress.py
--- qemu-10.0.6+ds/tests/functional/qemu_test/uncompress.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/qemu_test/uncompress.py 2025-12-06 17:54:24.000000000 +0300
@@ -13,7 +13,7 @@
import stat
import shutil
from urllib.parse import urlparse
-from subprocess import run, CalledProcessError, DEVNULL
+from subprocess import run, CalledProcessError
from .asset import Asset
diff -Nru qemu-10.0.6+ds/tests/functional/reverse_debugging.py qemu-10.0.7+ds/tests/functional/reverse_debugging.py
--- qemu-10.0.6+ds/tests/functional/reverse_debugging.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/reverse_debugging.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,196 @@
+# Reverse debugging test
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+import os
+import logging
+
+from qemu_test import LinuxKernelTest, get_qemu_img
+from qemu_test.ports import Ports
+
+
+class ReverseDebugging(LinuxKernelTest):
+ """
+ Test GDB reverse debugging commands: reverse step and reverse continue.
+ Recording saves the execution of some instructions and makes an initial
+ VM snapshot to allow reverse execution.
+ Replay saves the order of the first instructions and then checks that they
+ are executed backwards in the correct order.
+ After that the execution is replayed to the end, and reverse continue
+ command is checked by setting several breakpoints, and asserting
+ that the execution is stopped at the last of them.
+ """
+
+ timeout = 10
+ STEPS = 10
+ endian_is_le = True
+
+ def run_vm(self, record, shift, args, replay_path, image_path, port):
+ from avocado.utils import datadrainer
+
+ logger = logging.getLogger('replay')
+ vm = self.get_vm(name='record' if record else 'replay')
+ vm.set_console()
+ if record:
+ logger.info('recording the execution...')
+ mode = 'record'
+ else:
+ logger.info('replaying the execution...')
+ mode = 'replay'
+ vm.add_args('-gdb', 'tcp::%d' % port, '-S')
+ vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' %
+ (shift, mode, replay_path),
+ '-net', 'none')
+ vm.add_args('-drive', 'file=%s,if=none' % image_path)
+ if args:
+ vm.add_args(*args)
+ vm.launch()
+ console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(),
+ logger=self.log.getChild('console'),
+ stop_check=(lambda : not vm.is_running()))
+ console_drainer.start()
+ return vm
+
+ @staticmethod
+ def get_reg_le(g, reg):
+ res = g.cmd(b'p%x' % reg)
+ num = 0
+ for i in range(len(res))[-2::-2]:
+ num = 0x100 * num + int(res[i:i + 2], 16)
+ return num
+
+ @staticmethod
+ def get_reg_be(g, reg):
+ res = g.cmd(b'p%x' % reg)
+ return int(res, 16)
+
+ def get_reg(self, g, reg):
+ # value may be encoded in BE or LE order
+ if self.endian_is_le:
+ return self.get_reg_le(g, reg)
+ else:
+ return self.get_reg_be(g, reg)
+
+ def get_pc(self, g):
+ return self.get_reg(g, self.REG_PC)
+
+ def check_pc(self, g, addr):
+ pc = self.get_pc(g)
+ if pc != addr:
+ self.fail('Invalid PC (read %x instead of %x)' % (pc, addr))
+
+ @staticmethod
+ def gdb_step(g):
+ g.cmd(b's', b'T05thread:01;')
+
+ @staticmethod
+ def gdb_bstep(g):
+ g.cmd(b'bs', b'T05thread:01;')
+
+ @staticmethod
+ def vm_get_icount(vm):
+ return vm.qmp('query-replay')['return']['icount']
+
+ def reverse_debugging(self, shift=7, args=None):
+ from avocado.utils import gdb
+ from avocado.utils import process
+
+ logger = logging.getLogger('replay')
+
+ # create qcow2 for snapshots
+ logger.info('creating qcow2 image for VM snapshots')
+ image_path = os.path.join(self.workdir, 'disk.qcow2')
+ qemu_img = get_qemu_img(self)
+ if qemu_img is None:
+ self.skipTest('Could not find "qemu-img", which is required to '
+ 'create the temporary qcow2 image')
+ cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path)
+ process.run(cmd)
+
+ replay_path = os.path.join(self.workdir, 'replay.bin')
+
+ # record the log
+ vm = self.run_vm(True, shift, args, replay_path, image_path, -1)
+ while self.vm_get_icount(vm) <= self.STEPS:
+ pass
+ last_icount = self.vm_get_icount(vm)
+ vm.shutdown()
+
+ logger.info("recorded log with %s+ steps" % last_icount)
+
+ # replay and run debug commands
+ with Ports() as ports:
+ port = ports.find_free_port()
+ vm = self.run_vm(False, shift, args, replay_path, image_path, port)
+ logger.info('connecting to gdbstub')
+ g = gdb.GDBRemote('127.0.0.1', port, False, False)
+ g.connect()
+ r = g.cmd(b'qSupported')
+ if b'qXfer:features:read+' in r:
+ g.cmd(b'qXfer:features:read:target.xml:0,ffb')
+ if b'ReverseStep+' not in r:
+ self.fail('Reverse step is not supported by QEMU')
+ if b'ReverseContinue+' not in r:
+ self.fail('Reverse continue is not supported by QEMU')
+
+ logger.info('stepping forward')
+ steps = []
+ # record first instruction addresses
+ for _ in range(self.STEPS):
+ pc = self.get_pc(g)
+ logger.info('saving position %x' % pc)
+ steps.append(pc)
+ self.gdb_step(g)
+
+ # visit the recorded instruction in reverse order
+ logger.info('stepping backward')
+ for addr in steps[::-1]:
+ self.gdb_bstep(g)
+ self.check_pc(g, addr)
+ logger.info('found position %x' % addr)
+
+ # visit the recorded instruction in forward order
+ logger.info('stepping forward')
+ for addr in steps:
+ self.check_pc(g, addr)
+ self.gdb_step(g)
+ logger.info('found position %x' % addr)
+
+ # set breakpoints for the instructions just stepped over
+ logger.info('setting breakpoints')
+ for addr in steps:
+ # hardware breakpoint at addr with len=1
+ g.cmd(b'Z1,%x,1' % addr, b'OK')
+
+ # this may hit a breakpoint if first instructions are executed
+ # again
+ logger.info('continuing execution')
+ vm.qmp('replay-break', icount=last_icount - 1)
+ # continue - will return after pausing
+ # This could stop at the end and get a T02 return, or by
+ # re-executing one of the breakpoints and get a T05 return.
+ g.cmd(b'c')
+ if self.vm_get_icount(vm) == last_icount - 1:
+ logger.info('reached the end (icount %s)' % (last_icount - 1))
+ else:
+ logger.info('hit a breakpoint again at %x (icount %s)' %
+ (self.get_pc(g), self.vm_get_icount(vm)))
+
+ logger.info('running reverse continue to reach %x' % steps[-1])
+ # reverse continue - will return after stopping at the breakpoint
+ g.cmd(b'bc', b'T05thread:01;')
+
+ # assume that none of the first instructions is executed again
+ # breaking the order of the breakpoints
+ self.check_pc(g, steps[-1])
+ logger.info('successfully reached %x' % steps[-1])
+
+ logger.info('exiting gdb and qemu')
+ vm.shutdown()
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_aspeed.py qemu-10.0.7+ds/tests/functional/test_aarch64_aspeed.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_aspeed.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_aspeed.py 2025-12-06 17:54:24.000000000 +0300
@@ -85,7 +85,7 @@
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
- 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_replay.py qemu-10.0.7+ds/tests/functional/test_aarch64_replay.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_replay.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -5,25 +5,46 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipIfOperatingSystem
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipIfOperatingSystem, get_qemu_img
from replay_kernel import ReplayKernelBase
class Aarch64Replay(ReplayKernelBase):
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
- 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
- '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/Image',
+ 'b74743c5e89e1cea0f73368d24ae0ae85c5204ff84be3b5e9610417417d2f235')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/rootfs.ext4.zst',
+ 'a1acaaae2068df4648d04ff75f532aaa8c5edcd6b936122b6f0db4848a07b465')
def test_aarch64_virt(self):
+ self.require_netdev('user')
self.set_machine('virt')
- self.cpu = 'cortex-a53'
+ self.cpu = 'cortex-a57'
kernel_path = self.ASSET_KERNEL.fetch()
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', 'virtio-blk-device,drive=hd0-rr',
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
- 'console=ttyAMA0')
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern)
+ 'console=ttyAMA0 root=/dev/vda')
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern,
+ args=args)
if __name__ == '__main__':
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_reverse_debug.py qemu-10.0.7+ds/tests/functional/test_aarch64_reverse_debug.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_reverse_debug.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_reverse_debug.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import Asset, skipIfMissingImports, skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+@skipIfMissingImports('avocado.utils')
+class ReverseDebugging_AArch64(ReverseDebugging):
+
+ REG_PC = 32
+
+ KERNEL_ASSET = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
+ '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2921")
+ def test_aarch64_virt(self):
+ self.set_machine('virt')
+ self.cpu = 'cortex-a53'
+ kernel_path = self.KERNEL_ASSET.fetch()
+ self.reverse_debugging(args=('-kernel', kernel_path))
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_rme_sbsaref.py qemu-10.0.7+ds/tests/functional/test_aarch64_rme_sbsaref.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_rme_sbsaref.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_rme_sbsaref.py 2025-12-06 17:54:24.000000000 +0300
@@ -9,15 +9,13 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import time
import os
-import logging
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, wait_for_console_pattern
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
from qemu_test import exec_command_and_wait_for_pattern
from test_aarch64_rme_virt import test_realms_guest
+
class Aarch64RMESbsaRefMachine(QemuSystemTest):
# Stack is built with OP-TEE build environment from those instructions:
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_rme_virt.py qemu-10.0.7+ds/tests/functional/test_aarch64_rme_virt.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_rme_virt.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_rme_virt.py 2025-12-06 17:54:24.000000000 +0300
@@ -9,9 +9,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import time
import os
-import logging
from qemu_test import QemuSystemTest, Asset
from qemu_test import exec_command, wait_for_console_pattern
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_sbsaref_alpine.py qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref_alpine.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_sbsaref_alpine.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref_alpine.py 2025-12-06 17:54:24.000000000 +0300
@@ -10,11 +10,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
-from unittest import skipUnless
from test_aarch64_sbsaref import fetch_firmware
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_sbsaref_freebsd.py qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref_freebsd.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_sbsaref_freebsd.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref_freebsd.py 2025-12-06 17:54:24.000000000 +0300
@@ -10,8 +10,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
from test_aarch64_sbsaref import fetch_firmware
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_smmu.py qemu-10.0.7+ds/tests/functional/test_aarch64_smmu.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_smmu.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_smmu.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,205 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# SMMUv3 Functional tests
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Eric Auger <eric.auger@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+import os
+import time
+
+from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import BUILD_DIR
+from qemu.utils import kvm_available
+
+
+class SMMU(LinuxKernelTest):
+
+ default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check '
+ 'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 '
+ 'console=ttyAMA0 rd.rescue')
+ IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
+ kernel_path = None
+ initrd_path = None
+ kernel_params = None
+
+ GUEST_PORT = 8080
+
+ def set_up_boot(self, path):
+ self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
+ 'drive=drv0,id=virtio-disk0,bootindex=1,'
+ 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
+ self.vm.add_args('-drive',
+ f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on')
+
+ self.vm.add_args('-netdev',
+ 'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
+ self.GUEST_PORT)
+ self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
+
+ def common_vm_setup(self, kernel, initrd, disk):
+ self.require_accelerator("kvm")
+ self.require_netdev('user')
+ self.set_machine("virt")
+ self.vm.add_args('-m', '1G')
+ self.vm.add_args("-accel", "kvm")
+ self.vm.add_args("-cpu", "host")
+ self.vm.add_args("-machine", "iommu=smmuv3")
+ self.vm.add_args("-d", "guest_errors")
+ self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
+ 'edk2-aarch64-code.fd'))
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
+ self.vm.add_args('-object',
+ 'rng-random,id=rng0,filename=/dev/urandom')
+
+ self.kernel_path = kernel.fetch()
+ self.initrd_path = initrd.fetch()
+ self.set_up_boot(disk.fetch())
+
+ def run_and_check(self, filename, hashsum):
+ self.vm.add_args('-initrd', self.initrd_path)
+ self.vm.add_args('-append', self.kernel_params)
+ self.launch_kernel(self.kernel_path, initrd=self.initrd_path,
+ wait_for='attach it to a bug report.')
+ prompt = '# '
+ # Fedora 33 requires 'return' to be pressed to enter the shell.
+ # There seems to be a small race between detecting the previous ':'
+ # and sending the newline, so we need to add a small delay here.
+ self.wait_for_console_pattern(':')
+ time.sleep(0.2)
+ exec_command_and_wait_for_pattern(self, '\n', prompt)
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
+ self.kernel_params)
+
+ # Checking for SMMU enablement:
+ self.log.info("Checking whether SMMU has been enabled...")
+ exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu',
+ 'arm-smmu-v3')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ 'find /sys/kernel/iommu_groups/ -type l',
+ 'devices/0000:00:')
+ self.wait_for_console_pattern(prompt)
+
+ # Copy a file (checked later), umount afterwards to drop disk cache:
+ self.log.info("Checking hard disk...")
+ exec_command_and_wait_for_pattern(self,
+ "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done",
+ "vda2")
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ 'mounted filesystem')
+ exec_command_and_wait_for_pattern(self, 'cp /bin/vi /sysroot/root/vi',
+ prompt)
+ exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
+ # Switch from initrd to the cloud image filesystem:
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ prompt)
+ exec_command_and_wait_for_pattern(self,
+ ('for d in dev proc sys run ; do '
+ 'mount -o bind /$d /sysroot/$d ; done'), prompt)
+ exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
+ # Check files on the hard disk:
+ exec_command_and_wait_for_pattern(self,
+ ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; '
+ 'else echo "files differ"; fi'), 'file ok')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self, f'sha256sum {filename}',
+ hashsum)
+
+ # Check virtio-net via HTTP:
+ exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
+ self.check_http_download(filename, hashsum, self.GUEST_PORT)
+
+
+ # 5.3 kernel without RIL #
+
+ ASSET_KERNEL_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
+
+ ASSET_INITRD_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a')
+
+ ASSET_DISK_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'),
+ '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49')
+
+ F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img'
+ F31_HSUM = '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9'
+
+ def test_smmu_noril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+
+ # 5.8 kernel featuring range invalidation
+ # >= v5.7 kernel
+
+ ASSET_KERNEL_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ 'd8b1e6f7241f339d8e7609c456cf0461ffa4583ed07e0b55c7d1d8a0c154aa89')
+
+ ASSET_INITRD_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df')
+
+ ASSET_DISK_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'),
+ 'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b')
+
+ F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img'
+ F33_HSUM = '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9'
+
+ def test_smmu_ril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_tcg_plugins.py qemu-10.0.7+ds/tests/functional/test_aarch64_tcg_plugins.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_tcg_plugins.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_tcg_plugins.py 2025-12-06 17:54:24.000000000 +0300
@@ -13,7 +13,6 @@
import tempfile
import mmap
-import os
import re
from qemu.machine.machine import VMLaunchFailure
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_virt.py qemu-10.0.7+ds/tests/functional/test_aarch64_virt.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_virt.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_virt.py 2025-12-06 17:54:24.000000000 +0300
@@ -13,12 +13,8 @@
import logging
from subprocess import check_call, DEVNULL
-from qemu.machine.machine import VMLaunchFailure
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, exec_command_and_wait_for_pattern
-from qemu_test import wait_for_console_pattern
-from qemu_test import skipIfMissingCommands, get_qemu_img
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern, get_qemu_img
class Aarch64VirtMachine(QemuSystemTest):
@@ -64,8 +60,7 @@
ASSET_KERNEL = Asset(
- ('https://fileserver.linaro.org/s/'
- 'z6B2ARM7DQT3HWN/download'),
+ 'https://share.linaro.org/downloadFile?id=3zGlbmXh8pXFewt',
'12a54d4805cda6ab647cb7c7bbdb16fafb3df400e0d6f16445c1a0436100ef8d')
def common_aarch64_virt(self, machine):
@@ -83,7 +78,7 @@
self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0')
- self.vm.add_args('-cpu', 'max,pauth-impdef=on',
+ self.vm.add_args('-cpu', 'max',
'-machine', machine,
'-accel', 'tcg',
'-kernel', kernel_path,
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_virt_gpu.py qemu-10.0.7+ds/tests/functional/test_aarch64_virt_gpu.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_virt_gpu.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_virt_gpu.py 2025-12-06 17:54:24.000000000 +0300
@@ -23,15 +23,11 @@
class Aarch64VirtGPUMachine(LinuxKernelTest):
ASSET_VIRT_GPU_KERNEL = Asset(
- 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/'
- 'download?path=%2F&files='
- 'Image.6.12.16.aarch64',
+ 'https://share.linaro.org/downloadFile?id=lL8wgnMmSXZo7Co',
'7888c51c55d37e86bbbdeb5acea9f08c34e6b0f03c1f5b2463285f6a6f6eec8b')
ASSET_VIRT_GPU_ROOTFS = Asset(
- 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/'
- 'download?path=%2F&files='
- 'rootfs.aarch64.ext2.zstd',
+ 'https://share.linaro.org/downloadFile?id=qOn1wbfKmS6KVHZ',
'd45118c899420b7e673f1539a37a35480134b3e36e3a59e2cb69b1781cbb14ef')
def _launch_virt_gpu(self, gpu_device):
diff -Nru qemu-10.0.6+ds/tests/functional/test_aarch64_xen.py qemu-10.0.7+ds/tests/functional/test_aarch64_xen.py
--- qemu-10.0.6+ds/tests/functional/test_aarch64_xen.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_aarch64_xen.py 2025-12-06 17:54:24.000000000 +0300
@@ -25,8 +25,7 @@
XEN_COMMON_COMMAND_LINE = 'dom0_mem=128M loglvl=all guest_loglvl=all'
ASSET_KERNEL = Asset(
- ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/'
- 'download?path=%2F&files=linux-5.9.9-arm64-ajb'),
+ 'https://share.linaro.org/downloadFile?id=RRahAWwAwYKTZQd',
'00366fa51ea957c19462d2e2aefd480bef80ce727120e714ae48e0c88f261edb')
def launch_xen(self, xen_path):
@@ -54,8 +53,7 @@
wait_for_console_pattern(self, console_pattern, "Panic on CPU 0:")
ASSET_XEN_4_11 = Asset(
- ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/download?path=%2F&'
- 'files=xen-hypervisor-4.11-arm64_4.11.4%2B37-g3263f257ca-1_arm64.deb'),
+ 'https://share.linaro.org/downloadFile?id=ALU4n2NGGYbE4fO',
'b745c2631342f9fcc0147ddc364edb62c20ecfebd430e5a3546e7d7c6891c0bc')
def test_arm64_xen_411_and_dom0(self):
@@ -65,8 +63,7 @@
self.launch_xen(xen_path)
ASSET_XEN_4_14 = Asset(
- ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/download?path=%2F&'
- 'files=xen-hypervisor-4.14-arm64_4.14.0%2B80-gd101b417b7-1_arm64.deb'),
+ 'https://share.linaro.org/downloadFile?id=os4zSXPl7WW4lqX',
'e930a3293248edabd367d5b4b3b6448b9c99c057096ea8b47228a7870661d5cb')
def test_arm64_xen_414_and_dom0(self):
@@ -76,8 +73,7 @@
self.launch_xen(xen_path)
ASSET_XEN_4_15 = Asset(
- ('https://fileserver.linaro.org/s/JSsewXGZ6mqxPr5/download?path=%2F&'
- 'files=xen-upstream-4.15-unstable.deb'),
+ 'https://share.linaro.org/downloadFile?id=jjjG4uTp2wuO4Ks',
'2a9a8af8acf0231844657cc28baab95bd918b0ee2d493ee4ee6f8846e1358bc9')
def test_arm64_xen_415_and_dom0(self):
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_ast2500.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_ast2500.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_ast2500.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_ast2500.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,9 +4,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset
+from qemu_test import Asset, exec_command_and_wait_for_pattern
from aspeed import AspeedTest
-from qemu_test import exec_command_and_wait_for_pattern
class AST2500Machine(AspeedTest):
@@ -22,17 +21,17 @@
image_path = self.ASSET_BR2_202411_AST2500_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.do_test_arm_aspeed_buildroot_start(image_path, '0x0',
'ast2500-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_ast2600.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_ast2600.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_ast2600.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_ast2600.py 2025-12-06 17:54:24.000000000 +0300
@@ -27,38 +27,38 @@
image_path = self.ASSET_BR2_202411_AST2600_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.3,address=0x32');
+ 'ds1338,bus=aspeed.i2c.bus.3,address=0x32')
self.vm.add_args('-device',
- 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42');
+ 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42')
self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00',
'ast2600-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
exec_command_and_wait_for_pattern(self,
'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32');
+ 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32')
year = time.strftime("%Y")
- exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year);
+ exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year)
exec_command_and_wait_for_pattern(self,
'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device',
- 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64');
+ 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64')
exec_command_and_wait_for_pattern(self,
- 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#');
+ 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#')
exec_command_and_wait_for_pattern(self,
'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom',
- '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff');
+ '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff')
self.do_test_arm_aspeed_buildroot_poweroff()
ASSET_BR2_202302_AST2600_TPM_FLASH = Asset(
@@ -90,10 +90,10 @@
exec_command_and_wait_for_pattern(self,
'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device',
- 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)');
+ 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/tpm/tpm0/pcr-sha256/0',
- 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0');
+ 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0')
self.do_test_arm_aspeed_buildroot_poweroff()
@@ -107,9 +107,9 @@
self.archive_extract(self.ASSET_SDK_V806_AST2600_A2)
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.5,address=0x32');
+ 'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2600-a2", "image-bmc"))
@@ -120,20 +120,20 @@
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
exec_command_and_wait_for_pattern(self,
'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
+ 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32')
year = time.strftime("%Y")
exec_command_and_wait_for_pattern(self,
- '/sbin/hwclock -f /dev/rtc1', year);
+ '/sbin/hwclock -f /dev/rtc1', year)
if __name__ == '__main__':
AspeedTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_bletchley.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_bletchley.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_bletchley.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_bletchley.py 2025-12-06 17:54:24.000000000 +0300
@@ -12,14 +12,14 @@
ASSET_BLETCHLEY_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/bletchley-bmc/openbmc-20250128071329/obmc-phosphor-image-bletchley-20250128071329.static.mtd.xz',
- 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844');
+ 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844')
def test_arm_ast2600_bletchley_openbmc(self):
image_path = self.uncompress(self.ASSET_BLETCHLEY_FLASH)
self.do_test_arm_aspeed_openbmc('bletchley-bmc', image=image_path,
uboot='2019.04', cpu_id='0xf00',
- soc='AST2600 rev A3');
+ soc='AST2600 rev A3')
if __name__ == '__main__':
AspeedTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_palmetto.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_palmetto.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_palmetto.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_palmetto.py 2025-12-06 17:54:24.000000000 +0300
@@ -12,14 +12,14 @@
ASSET_PALMETTO_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/palmetto-bmc/openbmc-20250128071432/obmc-phosphor-image-palmetto-20250128071432.static.mtd',
- 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81');
+ 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81')
def test_arm_ast2400_palmetto_openbmc(self):
image_path = self.ASSET_PALMETTO_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('palmetto-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2400 rev A1');
+ soc='AST2400 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_romulus.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_romulus.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_romulus.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_romulus.py 2025-12-06 17:54:24.000000000 +0300
@@ -12,14 +12,14 @@
ASSET_ROMULUS_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/romulus-bmc/openbmc-20250128071340/obmc-phosphor-image-romulus-20250128071340.static.mtd',
- '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b');
+ '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b')
def test_arm_ast2500_romulus_openbmc(self):
image_path = self.ASSET_ROMULUS_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('romulus-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_aspeed_witherspoon.py qemu-10.0.7+ds/tests/functional/test_arm_aspeed_witherspoon.py
--- qemu-10.0.6+ds/tests/functional/test_arm_aspeed_witherspoon.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_aspeed_witherspoon.py 2025-12-06 17:54:24.000000000 +0300
@@ -12,14 +12,14 @@
ASSET_WITHERSPOON_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/witherspoon-bmc/openbmc-20240618035022/obmc-phosphor-image-witherspoon-20240618035022.ubi.mtd',
- '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213');
+ '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213')
def test_arm_ast2500_witherspoon_openbmc(self):
image_path = self.ASSET_WITHERSPOON_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('witherspoon-bmc', image=image_path,
uboot='2016.07', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_bpim2u.py qemu-10.0.7+ds/tests/functional/test_arm_bpim2u.py
--- qemu-10.0.6+ds/tests/functional/test_arm_bpim2u.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_bpim2u.py 2025-12-06 17:54:24.000000000 +0300
@@ -163,7 +163,7 @@
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_cubieboard.py qemu-10.0.7+ds/tests/functional/test_arm_cubieboard.py
--- qemu-10.0.6+ds/tests/functional/test_arm_cubieboard.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_cubieboard.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern
from qemu_test import skipBigDataTest
@@ -128,7 +126,7 @@
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_orangepi.py qemu-10.0.7+ds/tests/functional/test_arm_orangepi.py
--- qemu-10.0.6+ds/tests/functional/test_arm_orangepi.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_orangepi.py 2025-12-06 17:54:24.000000000 +0300
@@ -174,7 +174,7 @@
exec_command_and_wait_for_pattern(self, ' ', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern('systemd[1]: Hostname set ' +
'to <orangepipc>')
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_quanta_gsj.py qemu-10.0.7+ds/tests/functional/test_arm_quanta_gsj.py
--- qemu-10.0.6+ds/tests/functional/test_arm_quanta_gsj.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_quanta_gsj.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern, skipSlowTest
diff -Nru qemu-10.0.6+ds/tests/functional/test_arm_smdkc210.py qemu-10.0.7+ds/tests/functional/test_arm_smdkc210.py
--- qemu-10.0.6+ds/tests/functional/test_arm_smdkc210.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_arm_smdkc210.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset
diff -Nru qemu-10.0.6+ds/tests/functional/test_i386_replay.py qemu-10.0.7+ds/tests/functional/test_i386_replay.py
--- qemu-10.0.6+ds/tests/functional/test_i386_replay.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_i386_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+#
+# Replay test that boots a Linux kernel on a i386 machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from replay_kernel import ReplayKernelBase
+
+
+class I386Replay(ReplayKernelBase):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/20230331/i386/bzImage',
+ 'a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956')
+
+ def test_pc(self):
+ self.set_machine('pc')
+ kernel_url = ()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+ console_pattern = 'VFS: Cannot open root device'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+
+if __name__ == '__main__':
+ ReplayKernelBase.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_migration.py qemu-10.0.7+ds/tests/functional/test_migration.py
--- qemu-10.0.6+ds/tests/functional/test_migration.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_migration.py 2025-12-06 17:54:24.000000000 +0300
@@ -11,14 +11,13 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-
import tempfile
-import os
import time
from qemu_test import QemuSystemTest, skipIfMissingCommands
from qemu_test.ports import Ports
+
class MigrationTest(QemuSystemTest):
timeout = 10
diff -Nru qemu-10.0.6+ds/tests/functional/test_mips64_malta.py qemu-10.0.7+ds/tests/functional/test_mips64_malta.py
--- qemu-10.0.6+ds/tests/functional/test_mips64_malta.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mips64_malta.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the big-endian 64-bit MIPS Malta board
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+from test_mips_malta import mips_check_wheezy
+
+
+class MaltaMachineConsole(LinuxKernelTest):
+
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '3e4ec154db080b3f1839f04dde83120654a33e5e1716863de576c47cb94f68f6')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='d98b953bb4a41c0fc0fd8d19bbc691c08989ac52568c1d3054d92dfd890d3f06')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_mips64el_malta.py qemu-10.0.7+ds/tests/functional/test_mips64el_malta.py
--- qemu-10.0.6+ds/tests/functional/test_mips64el_malta.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mips64el_malta.py 2025-12-06 17:54:24.000000000 +0300
@@ -16,6 +16,8 @@
from qemu_test import exec_command_and_wait_for_pattern
from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
+from test_mips_malta import mips_check_wheezy
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -90,6 +92,26 @@
# Wait for VM to shut down gracefully
self.vm.wait()
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '5e8b725244c59745bb8b64f5d8f49f25fecfa549f3395fb6d19a3b9e5065b85b')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='7579f8b56c1187c7c04d0dc3c0c56c7a6314c5ddd3a9bf8803ecc7cf8a3be9f8')
+
@skipIfMissingImports('numpy', 'cv2')
class MaltaMachineFramebuffer(LinuxKernelTest):
diff -Nru qemu-10.0.6+ds/tests/functional/test_mips64el_replay.py qemu-10.0.7+ds/tests/functional/test_mips64el_replay.py
--- qemu-10.0.6+ds/tests/functional/test_mips64el_replay.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mips64el_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,11 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-import logging
-
-from qemu_test import Asset, exec_command_and_wait_for_pattern
-from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
+from qemu_test import Asset, skipUntrustedTest
from replay_kernel import ReplayKernelBase
diff -Nru qemu-10.0.6+ds/tests/functional/test_mips_malta.py qemu-10.0.7+ds/tests/functional/test_mips_malta.py
--- qemu-10.0.6+ds/tests/functional/test_mips_malta.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mips_malta.py 2025-12-06 17:54:24.000000000 +0300
@@ -6,10 +6,93 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import LinuxKernelTest, Asset
+import os
+
+from qemu_test import LinuxKernelTest, Asset, wait_for_console_pattern
from qemu_test import exec_command_and_wait_for_pattern
+def mips_run_common_commands(test, prompt='#'):
+ exec_command_and_wait_for_pattern(test,
+ 'uname -m',
+ 'mips')
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'timer')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'ata_piix')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'rtc')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'input')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'fb')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : ata_piix')
+ wait_for_console_pattern(test, prompt)
+
+def mips_check_wheezy(test, kernel_path, image_path, kernel_command_line,
+ dl_file, hsum, nic='pcnet', cpuinfo='MIPS 24Kc'):
+ test.require_netdev('user')
+ test.require_device(nic)
+ test.set_machine('malta')
+
+ port=8080
+ test.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line,
+ '-drive', 'file=%s,snapshot=on' % image_path,
+ '-netdev', 'user,id=n1' +
+ ',tftp=' + os.path.basename(kernel_path) +
+ ',hostfwd=tcp:127.0.0.1:0-:%d' % port,
+ '-device', f'{nic},netdev=n1',
+ '-no-reboot')
+ test.vm.set_console()
+ test.vm.launch()
+
+ wait_for_console_pattern(test, 'login: ', 'Oops')
+ exec_command_and_wait_for_pattern(test, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(test, 'root', ':~# ')
+ mips_run_common_commands(test)
+
+ exec_command_and_wait_for_pattern(test, 'cd /', '# ')
+ test.check_http_download(dl_file, hsum, port,
+ pythoncmd='python -m SimpleHTTPServer')
+
+ exec_command_and_wait_for_pattern(test, 'cat /proc/cpuinfo', cpuinfo)
+ exec_command_and_wait_for_pattern(test, 'cat /proc/devices', 'usb')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/ioports',
+ ' : piix4_smbus')
+ # lspci for the host bridge does not work on big endian targets:
+ # https://gitlab.com/qemu-project/qemu/-/issues/2826
+ # exec_command_and_wait_for_pattern(test, 'lspci -d 11ab:4620',
+ # 'GT-64120')
+ exec_command_and_wait_for_pattern(test,
+ 'cat /sys/bus/i2c/devices/i2c-0/name',
+ 'SMBus PIIX4 adapter')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/mtd', 'YAMON')
+ # Empty 'Board Config' (64KB)
+ exec_command_and_wait_for_pattern(test, 'md5sum /dev/mtd2ro',
+ '0dfbe8aa4c20b52e1b8bf3cb6cbdf193')
+
+
class MaltaMachineConsole(LinuxKernelTest):
ASSET_KERNEL_2_63_2 = Asset(
@@ -70,7 +153,8 @@
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
'BogoMIPS')
exec_command_and_wait_for_pattern(self, 'uname -a',
- 'Debian')
+ '4.5.0-2-4kc-malta #1 Debian')
+ mips_run_common_commands(self)
exec_command_and_wait_for_pattern(self, 'ip link set eth0 up',
'eth0: link up')
@@ -89,6 +173,26 @@
# Wait for VM to shut down gracefully
self.vm.wait()
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ '0377fcda31299213c10b8e5babe7260ef99188b3ae1aca6f56594abb71e7f67e')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, nic='e1000',
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='ff0c0369143d9bbb9a6e6bc79322a2be535619df639e84103237f406e87493dc')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_mips_replay.py qemu-10.0.7+ds/tests/functional/test_mips_replay.py
--- qemu-10.0.6+ds/tests/functional/test_mips_replay.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mips_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipSlowTest, exec_command_and_wait_for_pattern
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff -Nru qemu-10.0.6+ds/tests/functional/test_mipsel_malta.py qemu-10.0.7+ds/tests/functional/test_mipsel_malta.py
--- qemu-10.0.6+ds/tests/functional/test_mipsel_malta.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mipsel_malta.py 2025-12-06 17:54:24.000000000 +0300
@@ -13,6 +13,8 @@
from qemu_test import interrupt_interactive_console_until_pattern
from qemu_test import wait_for_console_pattern
+from test_mips_malta import mips_check_wheezy
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -57,6 +59,26 @@
def test_mips_malta32el_nanomips_64k_dbg(self):
self.do_test_mips_malta32el_nanomips(self.ASSET_KERNEL_64K)
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ 'dc8a3648305b0201ca7a5cd135fe2890067a65d93c38728022bb0e656ad2bf9a')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line,
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='9fc9f250ed56a74e35e704ddfd5a1c5a5625adefc5c9da91f649288d3ca000f0')
+
class MaltaMachineYAMON(QemuSystemTest):
diff -Nru qemu-10.0.6+ds/tests/functional/test_mipsel_replay.py qemu-10.0.7+ds/tests/functional/test_mipsel_replay.py
--- qemu-10.0.6+ds/tests/functional/test_mipsel_replay.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_mipsel_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, wait_for_console_pattern, skipSlowTest
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff -Nru qemu-10.0.6+ds/tests/functional/test_netdev_ethtool.py qemu-10.0.7+ds/tests/functional/test_netdev_ethtool.py
--- qemu-10.0.6+ds/tests/functional/test_netdev_ethtool.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_netdev_ethtool.py 2025-12-06 17:54:24.000000000 +0300
@@ -16,16 +16,10 @@
# Runs in about 17s under KVM, 19s under TCG, 25s under GCOV
timeout = 45
- # Fetch assets from the netdev-ethtool subdir of my shared test
- # images directory on fileserver.linaro.org.
- ASSET_BASEURL = ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/'
- 'download?path=%2Fnetdev-ethtool&files=')
- ASSET_BZIMAGE = Asset(
- ASSET_BASEURL + "bzImage",
- "ed62ee06ea620b1035747f3f66a5e9fc5d3096b29f75562ada888b04cd1c4baf")
- ASSET_ROOTFS = Asset(
- ASSET_BASEURL + "rootfs.squashfs",
- "8f0207e3c4d40832ae73c1a927e42ca30ccb1e71f047acb6ddb161ba422934e6")
+ ASSET_BZIMAGE = Asset("https://share.linaro.org/downloadFile?id=QD37GYYAJhGOgVe",
+ "ed62ee06ea620b1035747f3f66a5e9fc5d3096b29f75562ada888b04cd1c4baf")
+ ASSET_ROOTFS = Asset("https://share.linaro.org/downloadFile?id=YAqnr0W8fruDh3f",
+ "8f0207e3c4d40832ae73c1a927e42ca30ccb1e71f047acb6ddb161ba422934e6")
def common_test_code(self, netdev, extra_args=None):
self.set_machine('q35')
diff -Nru qemu-10.0.6+ds/tests/functional/test_ppc64_hv.py qemu-10.0.7+ds/tests/functional/test_ppc64_hv.py
--- qemu-10.0.6+ds/tests/functional/test_ppc64_hv.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_ppc64_hv.py 2025-12-06 17:54:24.000000000 +0300
@@ -9,14 +9,14 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
+import os
+import subprocess
+
+from datetime import datetime
from qemu_test import QemuSystemTest, Asset
from qemu_test import wait_for_console_pattern, exec_command
from qemu_test import skipIfMissingCommands, skipBigDataTest
from qemu_test import exec_command_and_wait_for_pattern
-import os
-import time
-import subprocess
-from datetime import datetime
# Alpine is a light weight distro that supports QEMU. These tests boot
# that on the machine then run a QEMU guest inside it in KVM mode,
diff -Nru qemu-10.0.6+ds/tests/functional/test_ppc64_reverse_debug.py qemu-10.0.7+ds/tests/functional/test_ppc64_reverse_debug.py
--- qemu-10.0.6+ds/tests/functional/test_ppc64_reverse_debug.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_ppc64_reverse_debug.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import skipIfMissingImports, skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+@skipIfMissingImports('avocado.utils')
+class ReverseDebugging_ppc64(ReverseDebugging):
+
+ REG_PC = 0x40
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
+ def test_ppc64_pseries(self):
+ self.set_machine('pseries')
+ # SLOF branches back to its entry point, which causes this test
+ # to take the 'hit a breakpoint again' path. That's not a problem,
+ # just slightly different than the other machines.
+ self.endian_is_le = False
+ self.reverse_debugging()
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
+ def test_ppc64_powernv(self):
+ self.set_machine('powernv')
+ self.endian_is_le = False
+ self.reverse_debugging()
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff -Nru qemu-10.0.6+ds/tests/functional/test_s390x_topology.py qemu-10.0.7+ds/tests/functional/test_s390x_topology.py
--- qemu-10.0.6+ds/tests/functional/test_s390x_topology.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_s390x_topology.py 2025-12-06 17:54:24.000000000 +0300
@@ -217,12 +217,12 @@
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'vertical')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
@@ -283,7 +283,7 @@
self.check_polarization('vertical:high')
self.check_topology(0, 0, 0, 0, 'high', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_polarization("horizontal")
self.check_topology(0, 0, 0, 0, 'high', False)
@@ -310,11 +310,11 @@
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("vertical:high")
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
@@ -360,7 +360,7 @@
self.check_topology(0, 0, 0, 0, 'high', True)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
diff -Nru qemu-10.0.6+ds/tests/functional/test_vnc.py qemu-10.0.7+ds/tests/functional/test_vnc.py
--- qemu-10.0.6+ds/tests/functional/test_vnc.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_vnc.py 2025-12-06 17:54:24.000000000 +0300
@@ -11,12 +11,12 @@
# later. See the COPYING file in the top-level directory.
import socket
-from typing import List
-from qemu.machine.machine import VMLaunchFailure
+from qemu.machine.machine import VMLaunchFailure
from qemu_test import QemuSystemTest
from qemu_test.ports import Ports
+
VNC_ADDR = '127.0.0.1'
def check_connect(port: int) -> bool:
@@ -55,6 +55,8 @@
except VMLaunchFailure as excp:
if "-vnc: invalid option" in excp.output:
self.skipTest("VNC support not available")
+ elif "Cipher backend does not support DES algorithm" in excp.output:
+ self.skipTest("No cryptographic backend available")
else:
self.log.info("unhandled launch failure: %s", excp.output)
raise excp
diff -Nru qemu-10.0.6+ds/tests/functional/test_x86_64_kvm_xen.py qemu-10.0.7+ds/tests/functional/test_x86_64_kvm_xen.py
--- qemu-10.0.6+ds/tests/functional/test_x86_64_kvm_xen.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_x86_64_kvm_xen.py 2025-12-06 17:54:24.000000000 +0300
@@ -11,8 +11,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu.machine import machine
from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
@@ -25,18 +23,11 @@
kernel_path = None
kernel_params = None
- # Fetch assets from the kvm-xen-guest subdir of my shared test
- # images directory on fileserver.linaro.org where you can find
- # build instructions for how they where assembled.
- ASSET_KERNEL = Asset(
- ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?'
- 'path=%2Fkvm-xen-guest&files=bzImage'),
- 'ec0ad7bb8c33c5982baee0a75505fe7dbf29d3ff5d44258204d6307c6fe0132a')
-
- ASSET_ROOTFS = Asset(
- ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?'
- 'path=%2Fkvm-xen-guest&files=rootfs.ext4'),
- 'b11045d649006c649c184e93339aaa41a8fe20a1a86620af70323252eb29e40b')
+ ASSET_KERNEL = Asset('https://share.linaro.org/downloadFile?id=UG0V8dzzHrrHb9X',
+ 'ec0ad7bb8c33c5982baee0a75505fe7dbf29d3ff5d44258204d6307c6fe0132a')
+
+ ASSET_ROOTFS = Asset('https://share.linaro.org/downloadFile?id=VwLRKDXKFl6oKti',
+ 'b11045d649006c649c184e93339aaa41a8fe20a1a86620af70323252eb29e40b')
def common_vm_setup(self):
# We also catch lack of KVM_XEN support if we fail to launch
diff -Nru qemu-10.0.6+ds/tests/functional/test_x86_64_replay.py qemu-10.0.7+ds/tests/functional/test_x86_64_replay.py
--- qemu-10.0.6+ds/tests/functional/test_x86_64_replay.py 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_x86_64_replay.py 2025-12-06 17:54:24.000000000 +0300
@@ -5,30 +5,53 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipFlakyTest
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipFlakyTest, get_qemu_img
from replay_kernel import ReplayKernelBase
class X86Replay(ReplayKernelBase):
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/29/Everything/x86_64/os/images/pxeboot/vmlinuz'),
- '8f237d84712b1b411baf3af2aeaaee10b9aae8e345ec265b87ab3a39639eb143')
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/bzImage',
+ 'f57bfc6553bcd6e0a54aab86095bf642b33b5571d14e3af1731b18c87ed5aef8')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/rootfs.ext4.zst',
+ '4b8b2a99117519c5290e1202cb36eb6c7aaba92b357b5160f5970cf5fb78a751')
- def do_test_x86(self, machine):
+ def do_test_x86(self, machine, blkdevice, devroot):
+ self.require_netdev('user')
self.set_machine(machine)
+ self.cpu="Nehalem"
kernel_path = self.ASSET_KERNEL.fetch()
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', '%s,drive=hd0-rr' % blkdevice,
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ f"console=ttyS0 root=/dev/{devroot}")
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
+ args=args)
@skipFlakyTest('https://gitlab.com/qemu-project/qemu/-/issues/2094')
def test_pc(self):
- self.do_test_x86('pc')
+ self.do_test_x86('pc', 'virtio-blk', 'vda')
def test_q35(self):
- self.do_test_x86('q35')
+ self.do_test_x86('q35', 'ide-hd', 'sda')
if __name__ == '__main__':
diff -Nru qemu-10.0.6+ds/tests/functional/test_x86_64_reverse_debug.py qemu-10.0.7+ds/tests/functional/test_x86_64_reverse_debug.py
--- qemu-10.0.6+ds/tests/functional/test_x86_64_reverse_debug.py 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/functional/test_x86_64_reverse_debug.py 2025-12-06 17:54:24.000000000 +0300
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import skipIfMissingImports, skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+@skipIfMissingImports('avocado.utils')
+class ReverseDebugging_X86_64(ReverseDebugging):
+
+ REG_PC = 0x10
+ REG_CS = 0x12
+ def get_pc(self, g):
+ return self.get_reg_le(g, self.REG_PC) \
+ + self.get_reg_le(g, self.REG_CS) * 0x10
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2922")
+ def test_x86_64_pc(self):
+ self.set_machine('pc')
+ # start with BIOS only
+ self.reverse_debugging()
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff -Nru qemu-10.0.6+ds/tests/qemu-iotests/024 qemu-10.0.7+ds/tests/qemu-iotests/024
--- qemu-10.0.6+ds/tests/qemu-iotests/024 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/qemu-iotests/024 2025-12-06 17:54:24.000000000 +0300
@@ -315,6 +315,52 @@
$QEMU_IMG map "$OVERLAY" | _filter_qemu_img_map
+# Check that the region to copy to the overlay during a rebase
+# operation does not exceed the I/O buffer size.
+#
+# backing_new <-- backing_old <-- overlay
+#
+# Backing (new): -- -- -- -- <-- Empty image, size 4MB
+# Backing (old):|--|ff|ff|--| <-- 4 clusters, 1MB each
+# Overlay: |-- --|-- --| <-- 2 clusters, 2MB each
+#
+# The data at [1MB, 3MB) must be copied from the old backing image to
+# the overlay. However the rebase code will extend that region to the
+# overlay's (sub)cluster boundaries to avoid CoW (see commit 12df580b).
+# This test checks that IO_BUF_SIZE (2 MB) is taken into account.
+
+echo
+echo "=== Test that the region to copy does not exceed 2MB (IO_BUF_SIZE) ==="
+echo
+
+echo "Creating backing chain"
+echo
+
+TEST_IMG=$BASE_NEW _make_test_img 4M
+TEST_IMG=$BASE_OLD CLUSTER_SIZE=1M _make_test_img -b "$BASE_NEW" -F $IMGFMT
+TEST_IMG=$OVERLAY CLUSTER_SIZE=2M _make_test_img -b "$BASE_OLD" -F $IMGFMT
+
+echo
+echo "Writing data to region [1MB, 3MB)"
+echo
+
+$QEMU_IO "$BASE_OLD" -c "write -P 0xff 1M 2M" | _filter_qemu_io
+
+echo
+echo "Rebasing"
+echo
+
+$QEMU_IMG rebase -b "$BASE_NEW" -F $IMGFMT "$OVERLAY"
+
+echo "Verifying the data"
+echo
+
+$QEMU_IO "$OVERLAY" -c "read -P 0x00 0 1M" | _filter_qemu_io
+$QEMU_IO "$OVERLAY" -c "read -P 0xff 1M 2M" | _filter_qemu_io
+$QEMU_IO "$OVERLAY" -c "read -P 0x00 3M 1M" | _filter_qemu_io
+
+$QEMU_IO -c map "$OVERLAY" | _filter_qemu_io
+
echo
# success, all done
diff -Nru qemu-10.0.6+ds/tests/qemu-iotests/024.out qemu-10.0.7+ds/tests/qemu-iotests/024.out
--- qemu-10.0.6+ds/tests/qemu-iotests/024.out 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/qemu-iotests/024.out 2025-12-06 17:54:24.000000000 +0300
@@ -243,4 +243,29 @@
0 0x20000 TEST_DIR/subdir/t.IMGFMT
0x40000 0x20000 TEST_DIR/subdir/t.IMGFMT
+=== Test that the region to copy does not exceed 2MB (IO_BUF_SIZE) ===
+
+Creating backing chain
+
+Formatting 'TEST_DIR/subdir/t.IMGFMT.base_new', fmt=IMGFMT size=4194304
+Formatting 'TEST_DIR/subdir/t.IMGFMT.base_old', fmt=IMGFMT size=4194304 backing_file=TEST_DIR/subdir/t.IMGFMT.base_new backing_fmt=IMGFMT
+Formatting 'TEST_DIR/subdir/t.IMGFMT', fmt=IMGFMT size=4194304 backing_file=TEST_DIR/subdir/t.IMGFMT.base_old backing_fmt=IMGFMT
+
+Writing data to region [1MB, 3MB)
+
+wrote 2097152/2097152 bytes at offset 1048576
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+Rebasing
+
+Verifying the data
+
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2097152/2097152 bytes at offset 1048576
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048576/1048576 bytes at offset 3145728
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+4 MiB (0x400000) bytes allocated at offset 0 bytes (0x0)
+
*** done
diff -Nru qemu-10.0.6+ds/tests/qemu-iotests/tests/commit-zero-blocks qemu-10.0.7+ds/tests/qemu-iotests/tests/commit-zero-blocks
--- qemu-10.0.6+ds/tests/qemu-iotests/tests/commit-zero-blocks 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/qemu-iotests/tests/commit-zero-blocks 2025-12-06 17:54:25.000000000 +0300
@@ -0,0 +1,96 @@
+#!/usr/bin/env bash
+# group: rw quick
+#
+# Test for commit of discarded blocks
+#
+# This tests committing a live snapshot where some of the blocks that
+# are present in the base image are discarded in the intermediate image.
+# This intends to check that these blocks are also discarded in the base
+# image after the commit.
+#
+# Copyright (C) 2024 Vincent Vanlaer.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# creator
+owner=libvirt-e6954efa@volkihar.be
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_qemu
+ _rm_test_img "${TEST_IMG}.base"
+ _rm_test_img "${TEST_IMG}.mid"
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+cd ..
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt qcow2
+_supported_proto file
+
+size="1M"
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
+TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT $size
+_make_test_img -b "${TEST_IMG}.mid" -F $IMGFMT $size
+
+$QEMU_IO -c "write -P 0x01 64k 128k" "$TEST_IMG.base" | _filter_qemu_io
+$QEMU_IO -c "discard 64k 64k" "$TEST_IMG.mid" | _filter_qemu_io
+
+echo
+echo "=== Base image info before commit ==="
+TEST_IMG="${TEST_IMG}.base" _img_info | _filter_img_info
+$QEMU_IMG map --output=json "$TEST_IMG.base" | _filter_qemu_img_map
+
+echo
+echo "=== Middle image info before commit ==="
+TEST_IMG="${TEST_IMG}.mid" _img_info | _filter_img_info
+$QEMU_IMG map --output=json "$TEST_IMG.mid" | _filter_qemu_img_map
+
+echo
+echo === Running QEMU Live Commit Test ===
+echo
+
+qemu_comm_method="qmp"
+_launch_qemu -drive file="${TEST_IMG}",if=virtio,id=test
+h=$QEMU_HANDLE
+
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
+
+_send_qemu_cmd $h "{ 'execute': 'block-commit',
+ 'arguments': { 'device': 'test',
+ 'top': '"${TEST_IMG}.mid"',
+ 'base': '"${TEST_IMG}.base"'} }" '"status": "null"'
+
+_cleanup_qemu
+
+echo
+echo "=== Base image info after commit ==="
+TEST_IMG="${TEST_IMG}.base" _img_info | _filter_img_info
+$QEMU_IMG map --output=json "$TEST_IMG.base" | _filter_qemu_img_map
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff -Nru qemu-10.0.6+ds/tests/qemu-iotests/tests/commit-zero-blocks.out qemu-10.0.7+ds/tests/qemu-iotests/tests/commit-zero-blocks.out
--- qemu-10.0.6+ds/tests/qemu-iotests/tests/commit-zero-blocks.out 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/qemu-iotests/tests/commit-zero-blocks.out 2025-12-06 17:54:25.000000000 +0300
@@ -0,0 +1,54 @@
+QA output created by commit-zero-blocks
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
+Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.mid backing_fmt=IMGFMT
+wrote 131072/131072 bytes at offset 65536
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+discard 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Base image info before commit ===
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
+virtual size: 1 MiB (1048576 bytes)
+[{ "start": 0, "length": 65536, "depth": 0, "present": false, "zero": true, "data": false, "compressed": false},
+{ "start": 65536, "length": 131072, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 196608, "length": 851968, "depth": 0, "present": false, "zero": true, "data": false, "compressed": false}]
+
+=== Middle image info before commit ===
+image: TEST_DIR/t.IMGFMT.mid
+file format: IMGFMT
+virtual size: 1 MiB (1048576 bytes)
+backing file: TEST_DIR/t.IMGFMT.base
+backing file format: IMGFMT
+[{ "start": 0, "length": 65536, "depth": 1, "present": false, "zero": true, "data": false, "compressed": false},
+{ "start": 65536, "length": 65536, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false},
+{ "start": 131072, "length": 65536, "depth": 1, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 196608, "length": 851968, "depth": 1, "present": false, "zero": true, "data": false, "compressed": false}]
+
+=== Running QEMU Live Commit Test ===
+
+{ 'execute': 'qmp_capabilities' }
+{"return": {}}
+{ 'execute': 'block-commit',
+ 'arguments': { 'device': 'test',
+ 'top': 'TEST_DIR/t.IMGFMT.mid',
+ 'base': 'TEST_DIR/t.IMGFMT.base'} }
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "test"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "test"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "test"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "test"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "test", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "test"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "test"}}
+
+=== Base image info after commit ===
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
+virtual size: 1 MiB (1048576 bytes)
+[{ "start": 0, "length": 65536, "depth": 0, "present": false, "zero": true, "data": false, "compressed": false},
+{ "start": 65536, "length": 65536, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false},
+{ "start": 131072, "length": 65536, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 196608, "length": 851968, "depth": 0, "present": false, "zero": true, "data": false, "compressed": false}]
+*** done
diff -Nru qemu-10.0.6+ds/tests/qtest/am53c974-test.c qemu-10.0.7+ds/tests/qtest/am53c974-test.c
--- qemu-10.0.6+ds/tests/qtest/am53c974-test.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/qtest/am53c974-test.c 2025-12-06 17:54:25.000000000 +0300
@@ -109,6 +109,44 @@
qtest_quit(s);
}
+/* Reported as https://issues.oss-fuzz.com/issues/439878564 */
+static void test_cmdfifo_overflow3_ok(void)
+{
+ QTestState *s = qtest_init(
+ "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
+ "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
+ qtest_outl(s, 0xcf8, 0x80001010);
+ qtest_outl(s, 0xcfc, 0xc000);
+ qtest_outl(s, 0xcf8, 0x80001004);
+ qtest_outw(s, 0xcfc, 0x01);
+ qtest_outb(s, 0xc00c, 0x43);
+ qtest_outl(s, 0xc00b, 0x9100);
+ qtest_outl(s, 0xc009, 0x02000000);
+ qtest_outl(s, 0xc000, 0x0b);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0xc200);
+ qtest_outl(s, 0xc00b, 0x1000);
+ qtest_outl(s, 0xc00b, 0x9000);
+ qtest_outb(s, 0xc008, 0x00);
+ qtest_outb(s, 0xc008, 0x00);
+ qtest_outl(s, 0xc03f, 0x0300);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outw(s, 0xc00b, 0x4200);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outw(s, 0xc00b, 0x1200);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outb(s, 0xc00c, 0x43);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc00b, 0x1000);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_quit(s);
+}
+
/* Reported as crash_0900379669 */
static void test_fifo_pop_buf(void)
{
@@ -266,6 +304,8 @@
test_cmdfifo_overflow_ok);
qtest_add_func("am53c974/test_cmdfifo_overflow2_ok",
test_cmdfifo_overflow2_ok);
+ qtest_add_func("am53c974/test_cmdfifo_overflow3_ok",
+ test_cmdfifo_overflow3_ok);
qtest_add_func("am53c974/test_fifo_pop_buf",
test_fifo_pop_buf);
qtest_add_func("am53c974/test_target_selected_ok",
diff -Nru qemu-10.0.6+ds/tests/tcg/multiarch/linux/linux-test.c qemu-10.0.7+ds/tests/tcg/multiarch/linux/linux-test.c
--- qemu-10.0.6+ds/tests/tcg/multiarch/linux/linux-test.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/tcg/multiarch/linux/linux-test.c 2025-12-06 17:54:25.000000000 +0300
@@ -155,9 +155,14 @@
error("stat mode");
if ((st.st_mode & 0777) != 0600)
error("stat mode2");
- if (st.st_atime != 1001 ||
- st.st_mtime != 1000)
+ /*
+ * Only check mtime, not atime: other processes such as
+ * virus scanners might race with this test program and get
+ * in and update the atime, causing random failures.
+ */
+ if (st.st_mtime != 1000) {
error("stat time");
+ }
chk_error(stat(tmpdir, &st));
if (!S_ISDIR(st.st_mode))
diff -Nru qemu-10.0.6+ds/tests/tcg/s390x/Makefile.softmmu-target qemu-10.0.7+ds/tests/tcg/s390x/Makefile.softmmu-target
--- qemu-10.0.6+ds/tests/tcg/s390x/Makefile.softmmu-target 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/tcg/s390x/Makefile.softmmu-target 2025-12-06 17:54:25.000000000 +0300
@@ -28,6 +28,7 @@
mc \
per \
precise-smc-softmmu \
+ sckc \
ssm-early \
stosm-early \
stpq \
diff -Nru qemu-10.0.6+ds/tests/tcg/s390x/sckc.S qemu-10.0.7+ds/tests/tcg/s390x/sckc.S
--- qemu-10.0.6+ds/tests/tcg/s390x/sckc.S 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.7+ds/tests/tcg/s390x/sckc.S 2025-12-06 17:54:25.000000000 +0300
@@ -0,0 +1,63 @@
+/*
+ * Test clock comparator.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x130
+ext_old_psw:
+ .org 0x1b0
+ext_new_psw:
+ .quad 0x180000000, _ext /* 64-bit mode */
+ .org 0x1d0
+pgm_new_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ lpswe start31_psw
+_start31:
+ stctg %c0,%c0,c0
+ oi c0+6,8 /* set clock-comparator subclass mask */
+ lctlg %c0,%c0,c0
+
+0:
+ brasl %r14,_f /* %r14's most significant bit is 1 */
+ jg 0b
+_f:
+ br %r14 /* it must not end up in ext_old_psw */
+
+_ext:
+ stg %r0,ext_saved_r0
+
+ lg %r0,ext_counter
+ aghi %r0,1
+ stg %r0,ext_counter
+
+ cgfi %r0,0x1000
+ jnz 0f
+ lpswe success_psw
+0:
+
+ stck clock
+ lg %r0,clock
+ agfi %r0,0x40000 /* 64us * 0x1000 =~ 0.25s */
+ stg %r0,clock
+ sckc clock
+
+ lg %r0,ext_saved_r0
+ lpswe ext_old_psw
+
+ .align 8
+start31_psw:
+ .quad 0x100000080000000,_start31 /* EX, 31-bit mode */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+c0:
+ .skip 8
+clock:
+ .quad 0
+ext_counter:
+ .quad 0
+ext_saved_r0:
+ .skip 8
diff -Nru qemu-10.0.6+ds/tests/unit/crypto-tls-x509-helpers.h qemu-10.0.7+ds/tests/unit/crypto-tls-x509-helpers.h
--- qemu-10.0.6+ds/tests/unit/crypto-tls-x509-helpers.h 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/unit/crypto-tls-x509-helpers.h 2025-12-06 17:54:25.000000000 +0300
@@ -148,8 +148,7 @@
.basicConstraintsIsCA = false, \
.keyUsageEnable = true, \
.keyUsageCritical = true, \
- .keyUsageValue = \
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, \
+ .keyUsageValue = GNUTLS_KEY_DIGITAL_SIGNATURE, \
.keyPurposeEnable = true, \
.keyPurposeCritical = true, \
.keyPurposeOID1 = GNUTLS_KP_TLS_WWW_CLIENT, \
@@ -168,8 +167,7 @@
.basicConstraintsIsCA = false, \
.keyUsageEnable = true, \
.keyUsageCritical = true, \
- .keyUsageValue = \
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, \
+ .keyUsageValue = GNUTLS_KEY_DIGITAL_SIGNATURE, \
.keyPurposeEnable = true, \
.keyPurposeCritical = true, \
.keyPurposeOID1 = GNUTLS_KP_TLS_WWW_SERVER, \
diff -Nru qemu-10.0.6+ds/tests/unit/test-crypto-tlscredsx509.c qemu-10.0.7+ds/tests/unit/test-crypto-tlscredsx509.c
--- qemu-10.0.6+ds/tests/unit/test-crypto-tlscredsx509.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/unit/test-crypto-tlscredsx509.c 2025-12-06 17:54:25.000000000 +0300
@@ -166,14 +166,14 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(clientcertreq, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
@@ -196,7 +196,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
@@ -211,7 +211,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
@@ -226,7 +226,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
@@ -250,7 +250,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
/* no-basic */
@@ -264,7 +264,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
/* Key usage:dig-sig:critical */
@@ -278,7 +278,7 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
@@ -303,7 +303,7 @@
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT |
+ GNUTLS_KEY_DIGITAL_SIGNATURE |
GNUTLS_KEY_KEY_CERT_SIGN,
false, false, NULL, NULL,
0, 0);
@@ -406,7 +406,7 @@
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT |
+ GNUTLS_KEY_DIGITAL_SIGNATURE |
GNUTLS_KEY_KEY_CERT_SIGN,
false, false, NULL, NULL,
0, 0);
@@ -508,21 +508,21 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(servercertexp1req, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, -1);
TLS_CERT_REQ(clientcertexp1req, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, -1);
@@ -546,21 +546,21 @@
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(servercertnew1req, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
1, 2);
TLS_CERT_REQ(clientcertnew1req, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
1, 2);
@@ -599,14 +599,14 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq,
"UK", "qemu client level 2b", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
diff -Nru qemu-10.0.6+ds/tests/unit/test-crypto-tlssession.c qemu-10.0.7+ds/tests/unit/test-crypto-tlssession.c
--- qemu-10.0.6+ds/tests/unit/test-crypto-tlssession.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/unit/test-crypto-tlssession.c 2025-12-06 17:54:25.000000000 +0300
@@ -472,14 +472,14 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(clientcertreq, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
@@ -487,7 +487,7 @@
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
@@ -506,7 +506,7 @@
"192.168.122.1", "fec0::dead:beaf",
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
/* This intentionally doesn't replicate */
@@ -515,7 +515,7 @@
"192.168.122.1", "fec0::dead:beaf",
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
@@ -619,14 +619,14 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq,
"UK", "qemu client level 2b", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
diff -Nru qemu-10.0.6+ds/tests/unit/test-io-channel-tls.c qemu-10.0.7+ds/tests/unit/test-io-channel-tls.c
--- qemu-10.0.6+ds/tests/unit/test-io-channel-tls.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/tests/unit/test-io-channel-tls.c 2025-12-06 17:54:25.000000000 +0300
@@ -302,14 +302,14 @@
"UK", "qemu.org", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
TLS_CERT_REQ(clientcertreq, cacertreq,
"UK", "qemu", NULL, NULL, NULL, NULL,
true, true, false,
true, true,
- GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
+ GNUTLS_KEY_DIGITAL_SIGNATURE,
true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL,
0, 0);
diff -Nru qemu-10.0.6+ds/ui/gtk-gl-area.c qemu-10.0.7+ds/ui/gtk-gl-area.c
--- qemu-10.0.6+ds/ui/gtk-gl-area.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/ui/gtk-gl-area.c 2025-12-06 17:54:25.000000000 +0300
@@ -137,7 +137,22 @@
if (vc->gfx.guest_fb.dmabuf &&
qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
- gd_gl_area_draw(vc);
+ /*
+ * gd_egl_refresh() calls gd_egl_draw() if a DMA-BUF draw has already
+ * been submitted, but this function does not call gd_gl_area_draw() in
+ * such a case due to display corruption.
+ *
+ * Calling gd_gl_area_draw() is necessary to prevent a situation where
+ * there is a scheduled draw event but it won't happen bacause the window
+ * is currently in inactive state (minimized or tabified). If draw is not
+ * done for a long time, gl_block timeout and/or fence timeout (on the
+ * guest) will happen eventually.
+ *
+ * However, it is found that calling gd_gl_area_draw() here causes guest
+ * display corruption on a Wayland Compositor. The display corruption is
+ * more serious than the possible fence timeout so gd_gl_area_draw() is
+ * omitted for now.
+ */
return;
}
diff -Nru qemu-10.0.6+ds/ui/vnc.c qemu-10.0.7+ds/ui/vnc.c
--- qemu-10.0.6+ds/ui/vnc.c 2025-10-20 21:13:46.000000000 +0300
+++ qemu-10.0.7+ds/ui/vnc.c 2025-12-06 17:54:25.000000000 +0300
@@ -562,9 +562,12 @@
qmp_query_auth(vd->auth, vd->subauth, &info->auth,
&info->vencrypt, &info->has_vencrypt);
if (vd->dcl.con) {
- dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
- "device", &error_abort));
- info->display = g_strdup(dev->id);
+ Object *obj = object_property_get_link(OBJECT(vd->dcl.con),
+ "device", NULL);
+ if (obj) {
+ dev = DEVICE(obj);
+ info->display = g_strdup(dev->id);
+ }
}
for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
info->server = qmp_query_server_entry(
Reply to: