Version in base suite: 10.0.7+ds-0+deb13u1 Base version: qemu_10.0.7+ds-0+deb13u1 Target version: qemu_10.0.8+ds-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/q/qemu/qemu_10.0.7+ds-0+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/q/qemu/qemu_10.0.8+ds-0+deb13u1.dsc .gitlab-ci.d/cirrus.yml | 2 .gitlab-ci.d/custom-runners.yml | 6 .gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml | 25 - .gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml | 151 ------- .gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml | 128 ------ .gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml | 25 + .gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml | 151 +++++++ .gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml | 128 ++++++ VERSION | 2 backends/cryptodev-builtin.c | 9 backends/tpm/tpm_passthrough.c | 2 block/nvme.c | 99 ++-- block/vmdk.c | 2 block/vvfat.c | 2 blockdev.c | 1 bsd-user/syscall_defs.h | 2 chardev/char-io.c | 8 chardev/char-socket.c | 10 configs/meson/windows.txt | 1 debian/changelog | 103 +++++ debian/control.mk | 2 debian/patches/series | 1 debian/patches/virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch | 179 ++++++++ gdbstub/gdbstub.c | 2 gdbstub/user.c | 2 hw/adc/aspeed_adc.c | 3 hw/core/qdev-properties.c | 4 hw/display/virtio-dmabuf.c | 6 hw/display/virtio-gpu-virgl.c | 6 hw/i2c/aspeed_i2c.c | 103 +++-- hw/i2c/imx_i2c.c | 4 hw/i386/kvm/xen_evtchn.c | 2 hw/i386/x86-common.c | 2 hw/intc/arm_gicv3_its_common.c | 2 hw/intc/arm_gicv3_its_kvm.c | 2 hw/loongarch/virt-fdt-build.c | 55 +- hw/loongarch/virt.c | 14 hw/nvme/ns.c | 7 hw/nvme/nvme.h | 1 hw/pci-host/q35.c | 25 - hw/sd/sdhci.c | 2 hw/uefi/var-service-vars.c | 2 hw/ufs/lu.c | 3 hw/ufs/ufs.c | 50 +- hw/ufs/ufs.h | 9 hw/virtio/vhost-vdpa.c | 6 hw/virtio/vhost.c | 38 + hw/virtio/virtio-crypto.c | 7 hw/virtio/virtio-pmem.c | 1 include/block/ufs.h | 2 include/chardev/char-io.h | 2 include/chardev/char.h | 2 include/hw/virtio/vhost-vdpa.h | 8 linux-user/aarch64/target_fcntl.h | 1 linux-user/alpha/termbits.h | 30 + linux-user/generic/termbits.h | 2 linux-user/hppa/termbits.h | 45 ++ linux-user/ioctls.h | 6 linux-user/main.c | 2 linux-user/mips/termbits.h | 35 + linux-user/mmap.c | 16 linux-user/ppc/termbits.h | 1 linux-user/sh4/termbits.h | 51 +- linux-user/sparc/termbits.h | 33 + linux-user/strace.c | 69 +++ linux-user/syscall.c | 206 ++++++++-- linux-user/syscall_types.h | 3 linux-user/user-internals.h | 5 monitor/hmp.c | 5 monitor/qmp.c | 5 pc-bios/optionrom/Makefile | 2 python/scripts/mkvenv.py | 2 qga/commands-linux.c | 15 scripts/nsis.py | 2 scripts/qemugdb/timers.py | 5 target/arm/helper.c | 171 ++++---- target/arm/tcg/tlb_helper.c | 21 - target/i386/ops_sse.h | 16 target/i386/tcg/decode-new.c.inc | 31 - target/i386/tcg/decode-new.h | 2 target/i386/tcg/emit.c.inc | 17 target/i386/tcg/ops_sse_header.h.inc | 8 target/i386/tcg/user/seg_helper.c | 2 target/loongarch/cpu.c | 7 target/m68k/op_helper.c | 4 tcg/riscv/tcg-target.c.inc | 29 - tcg/tcg-op-ldst.c | 72 ++- tests/docker/dockerfiles/debian-all-test-cross.docker | 32 - tests/functional/test_aarch64_sbsaref.py | 20 tests/functional/test_arm_aspeed_rainier.py | 6 tests/functional/test_mips64el_replay.py | 3 tests/functional/test_mips_replay.py | 2 tests/qtest/q35-test.c | 6 tests/qtest/ufs-test.c | 126 ++++++ tests/tcg/multiarch/test-mmap.c | 42 +- tests/vhost-user-bridge.c | 10 tests/vm/freebsd | 4 ui/ui-hmp-cmds.c | 2 util/log.c | 2 99 files changed, 1842 insertions(+), 745 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpsvtv_r_7/qemu_10.0.7+ds-0+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpsvtv_r_7/qemu_10.0.8+ds-0+deb13u1.dsc: no acceptable signature found diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/cirrus.yml qemu-10.0.8+ds/.gitlab-ci.d/cirrus.yml --- qemu-10.0.7+ds/.gitlab-ci.d/cirrus.yml 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/cirrus.yml 2026-02-12 20:30:13.000000000 +0000 @@ -37,7 +37,7 @@ NAME: freebsd-14 CIRRUS_VM_INSTANCE_TYPE: freebsd_instance CIRRUS_VM_IMAGE_SELECTOR: image_family - CIRRUS_VM_IMAGE_NAME: freebsd-14-2 + CIRRUS_VM_IMAGE_NAME: freebsd-14-3 CIRRUS_VM_CPUS: 8 CIRRUS_VM_RAM: 8G UPDATE_COMMAND: pkg update; pkg upgrade -y diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# All ubuntu-22.04 jobs should run successfully in an environment -# setup by the scripts/ci/setup/ubuntu/build-environment.yml task -# "Install basic packages to build QEMU on Ubuntu 22.04" - -ubuntu-22.04-aarch32-all: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch32 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH32_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --cross-prefix=arm-linux-gnueabihf- - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -# All ubuntu-22.04 jobs should run successfully in an environment -# setup by the scripts/ci/setup/ubuntu/build-environment.yml task -# "Install basic packages to build QEMU on Ubuntu 22.04" - -ubuntu-22.04-aarch64-all-linux-static: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - - if: "$AARCH64_RUNNER_AVAILABLE" - script: - - mkdir build - - cd build - # Disable -static-pie due to build error with system libc: - # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1987438 - - ../configure --enable-debug --static --disable-system --disable-pie - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make check-tcg - - make --output-sync -j`nproc --ignore=40` check - -ubuntu-22.04-aarch64-all: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check - -ubuntu-22.04-aarch64-without-defaults: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --disable-user --without-default-devices --without-default-features - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check - -ubuntu-22.04-aarch64-alldbg: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - - if: "$AARCH64_RUNNER_AVAILABLE" - script: - - mkdir build - - cd build - - ../configure --enable-debug - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make clean - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check - -ubuntu-22.04-aarch64-clang: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-ubsan - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check - -ubuntu-22.04-aarch64-tci: - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --enable-tcg-interpreter - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - -ubuntu-22.04-aarch64-notcg: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - aarch64 - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$AARCH64_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --disable-tcg --with-devices-aarch64=minimal - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc --ignore=40` - - make --output-sync -j`nproc --ignore=40` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -# All ubuntu-22.04 jobs should run successfully in an environment -# setup by the scripts/ci/setup/ubuntu/build-environment.yml task -# "Install basic packages to build QEMU on Ubuntu 22.04" - -ubuntu-22.04-s390x-all-linux: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - - if: "$S390X_RUNNER_AVAILABLE" - script: - - mkdir build - - cd build - - ../configure --enable-debug --disable-system --disable-tools --disable-docs - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc` - - make --output-sync check-tcg - - make --output-sync -j`nproc` check - -ubuntu-22.04-s390x-all-system: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - timeout: 75m - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - - if: "$S390X_RUNNER_AVAILABLE" - script: - - mkdir build - - cd build - - ../configure --disable-user - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc` - - make --output-sync -j`nproc` check - -ubuntu-22.04-s390x-alldbg: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$S390X_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --enable-debug - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make clean - - make --output-sync -j`nproc` - - make --output-sync -j`nproc` check - -ubuntu-22.04-s390x-clang: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$S390X_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --cc=clang --cxx=clang++ --enable-ubsan - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc` - - make --output-sync -j`nproc` check - -ubuntu-22.04-s390x-tci: - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$S390X_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --enable-tcg-interpreter - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc` - -ubuntu-22.04-s390x-notcg: - extends: .custom_runner_template - needs: [] - stage: build - tags: - - ubuntu_22.04 - - s390x - rules: - - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - when: manual - allow_failure: true - - if: "$S390X_RUNNER_AVAILABLE" - when: manual - allow_failure: true - script: - - mkdir build - - cd build - - ../configure --disable-tcg - || { cat config.log meson-logs/meson-log.txt; exit 1; } - - make --output-sync -j`nproc` - - make --output-sync -j`nproc` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml 1970-01-01 00:00:00.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml 2026-02-12 20:30:13.000000000 +0000 @@ -0,0 +1,25 @@ +# All ubuntu-24.04 jobs should run successfully in an environment +# setup by the scripts/ci/setup/ubuntu/build-environment.yml task +# "Install basic packages to build QEMU on Ubuntu 24.04" + +ubuntu-24.04-aarch32-all: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch32 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH32_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --cross-prefix=arm-linux-gnueabihf- + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml 1970-01-01 00:00:00.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml 2026-02-12 20:30:13.000000000 +0000 @@ -0,0 +1,151 @@ +# All ubuntu-24.04 jobs should run successfully in an environment +# setup by the scripts/ci/setup/ubuntu/build-environment.yml task +# "Install basic packages to build QEMU on Ubuntu 24.04" + +ubuntu-24.04-aarch64-all-linux-static: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$AARCH64_RUNNER_AVAILABLE" + script: + - mkdir build + - cd build + # Disable -static-pie due to build error with system libc: + # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1987438 + - ../configure --enable-debug --static --disable-system --disable-pie + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make check-tcg + - make --output-sync -j`nproc --ignore=40` check + +ubuntu-24.04-aarch64-all: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check + +ubuntu-24.04-aarch64-without-defaults: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --disable-user --without-default-devices --without-default-features + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check + +ubuntu-24.04-aarch64-alldbg: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$AARCH64_RUNNER_AVAILABLE" + script: + - mkdir build + - cd build + - ../configure --enable-debug + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make clean + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check + +ubuntu-24.04-aarch64-clang: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-ubsan + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check + +ubuntu-24.04-aarch64-tci: + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --enable-tcg-interpreter + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + +ubuntu-24.04-aarch64-notcg: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - aarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$AARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --disable-tcg --with-devices-aarch64=minimal + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml 1970-01-01 00:00:00.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml 2026-02-12 20:30:13.000000000 +0000 @@ -0,0 +1,128 @@ +# All ubuntu-24.04 jobs should run successfully in an environment +# setup by the scripts/ci/setup/ubuntu/build-environment.yml task +# "Install basic packages to build QEMU on Ubuntu 24.04" + +ubuntu-24.04-s390x-all-linux: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" + script: + - mkdir build + - cd build + - ../configure --enable-debug --disable-system --disable-tools --disable-docs + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc` + - make --output-sync check-tcg + - make --output-sync -j`nproc` check + +ubuntu-24.04-s390x-all-system: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + timeout: 75m + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + - if: "$S390X_RUNNER_AVAILABLE" + script: + - mkdir build + - cd build + - ../configure --disable-user + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc` + - make --output-sync -j`nproc` check + +ubuntu-24.04-s390x-alldbg: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$S390X_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --enable-debug + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make clean + - make --output-sync -j`nproc` + - make --output-sync -j`nproc` check + +ubuntu-24.04-s390x-clang: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$S390X_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --cc=clang --cxx=clang++ --enable-ubsan + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc` + - make --output-sync -j`nproc` check + +ubuntu-24.04-s390x-tci: + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$S390X_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --enable-tcg-interpreter + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc` + +ubuntu-24.04-s390x-notcg: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - ubuntu_24.04 + - s390x + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$S390X_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --disable-tcg + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc` + - make --output-sync -j`nproc` check diff -Nru qemu-10.0.7+ds/.gitlab-ci.d/custom-runners.yml qemu-10.0.8+ds/.gitlab-ci.d/custom-runners.yml --- qemu-10.0.7+ds/.gitlab-ci.d/custom-runners.yml 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/.gitlab-ci.d/custom-runners.yml 2026-02-12 20:30:13.000000000 +0000 @@ -29,6 +29,6 @@ junit: build/meson-logs/testlog.junit.xml include: - - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-s390x.yml' - - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml' - - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml' + - local: '/.gitlab-ci.d/custom-runners/ubuntu-24.04-s390x.yml' + - local: '/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch64.yml' + - local: '/.gitlab-ci.d/custom-runners/ubuntu-24.04-aarch32.yml' diff -Nru qemu-10.0.7+ds/VERSION qemu-10.0.8+ds/VERSION --- qemu-10.0.7+ds/VERSION 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/VERSION 2026-02-12 20:30:13.000000000 +0000 @@ -1 +1 @@ -10.0.7 +10.0.8 diff -Nru qemu-10.0.7+ds/backends/cryptodev-builtin.c qemu-10.0.8+ds/backends/cryptodev-builtin.c --- qemu-10.0.7+ds/backends/cryptodev-builtin.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/backends/cryptodev-builtin.c 2026-02-12 20:30:14.000000000 +0000 @@ -53,6 +53,8 @@ #define CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN 512 #define CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN 64 +/* demonstration purposes only, use a limited size to avoid QEMU OOM */ +#define CRYPTODEV_BUITLIN_MAX_REQUEST_SIZE (1024 * 1024) struct CryptoDevBackendBuiltin { CryptoDevBackend parent_obj; @@ -98,12 +100,7 @@ 1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC; backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC; backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1; - /* - * Set the Maximum length of crypto request. - * Why this value? Just avoid to overflow when - * memory allocation for each crypto request. - */ - backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendOpInfo); + backend->conf.max_size = CRYPTODEV_BUITLIN_MAX_REQUEST_SIZE; backend->conf.max_cipher_key_len = CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN; backend->conf.max_auth_key_len = CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN; cryptodev_builtin_init_akcipher(backend); diff -Nru qemu-10.0.7+ds/backends/tpm/tpm_passthrough.c qemu-10.0.8+ds/backends/tpm/tpm_passthrough.c --- qemu-10.0.7+ds/backends/tpm/tpm_passthrough.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/backends/tpm/tpm_passthrough.c 2026-02-12 20:30:14.000000000 +0000 @@ -211,7 +211,7 @@ static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt) { int fd = -1; - char *dev; + const char *dev; char path[PATH_MAX]; if (tpm_pt->options->cancel_path) { diff -Nru qemu-10.0.7+ds/block/nvme.c qemu-10.0.8+ds/block/nvme.c --- qemu-10.0.7+ds/block/nvme.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/block/nvme.c 2026-02-12 20:30:14.000000000 +0000 @@ -64,6 +64,7 @@ } NVMeQueue; typedef struct { + /* Called from nvme_process_completion() in the BDS's main AioContext */ BlockCompletionFunc *cb; void *opaque; int cid; @@ -83,6 +84,7 @@ uint8_t *prp_list_pages; /* Fields protected by @lock */ + /* Coroutines in this queue are woken in their own context */ CoQueue free_req_queue; NVMeQueue sq, cq; int cq_phase; @@ -91,7 +93,7 @@ int need_kick; int inflight; - /* Thread-safe, no lock necessary */ + /* Thread-safe, no lock necessary; runs in the BDS's main context */ QEMUBH *completion_bh; } NVMeQueuePair; @@ -205,11 +207,13 @@ g_free(q); } +/* Runs in the BDS's main AioContext */ static void nvme_free_req_queue_cb(void *opaque) { NVMeQueuePair *q = opaque; qemu_mutex_lock(&q->lock); + /* qemu_co_enter_next() wakes the coroutine in its own AioContext */ while (q->free_req_head != -1 && qemu_co_enter_next(&q->free_req_queue, &q->lock)) { /* Retry waiting requests */ @@ -280,7 +284,7 @@ return NULL; } -/* With q->lock */ +/* With q->lock, must be run in the BDS's main AioContext */ static void nvme_kick(NVMeQueuePair *q) { BDRVNVMeState *s = q->s; @@ -307,7 +311,10 @@ return req; } -/* Return a free request element if any, otherwise return NULL. */ +/* + * Return a free request element if any, otherwise return NULL. + * May be run from any AioContext. + */ static NVMeRequest *nvme_get_free_req_nowait(NVMeQueuePair *q) { QEMU_LOCK_GUARD(&q->lock); @@ -320,6 +327,7 @@ /* * Wait for a free request to become available if necessary, then * return it. + * May be called in any AioContext. */ static coroutine_fn NVMeRequest *nvme_get_free_req(NVMeQueuePair *q) { @@ -327,20 +335,21 @@ while (q->free_req_head == -1) { trace_nvme_free_req_queue_wait(q->s, q->index); + /* nvme_free_req_queue_cb() wakes us in our own AioContext */ qemu_co_queue_wait(&q->free_req_queue, &q->lock); } return nvme_get_free_req_nofail_locked(q); } -/* With q->lock */ +/* With q->lock, may be called in any AioContext */ static void nvme_put_free_req_locked(NVMeQueuePair *q, NVMeRequest *req) { req->free_req_next = q->free_req_head; q->free_req_head = req - q->reqs; } -/* With q->lock */ +/* With q->lock, may be called in any AioContext */ static void nvme_wake_free_req_locked(NVMeQueuePair *q) { if (!qemu_co_queue_empty(&q->free_req_queue)) { @@ -349,7 +358,7 @@ } } -/* Insert a request in the freelist and wake waiters */ +/* Insert a request in the freelist and wake waiters (from any AioContext) */ static void nvme_put_free_req_and_wake(NVMeQueuePair *q, NVMeRequest *req) { qemu_mutex_lock(&q->lock); @@ -380,7 +389,7 @@ } } -/* With q->lock */ +/* With q->lock, must be run in the BDS's main AioContext */ static bool nvme_process_completion(NVMeQueuePair *q) { BDRVNVMeState *s = q->s; @@ -450,6 +459,7 @@ return progress; } +/* As q->completion_bh, runs in the BDS's main AioContext */ static void nvme_process_completion_bh(void *opaque) { NVMeQueuePair *q = opaque; @@ -480,6 +490,7 @@ } } +/* Must be run in the BDS's main AioContext */ static void nvme_kick_and_check_completions(void *opaque) { NVMeQueuePair *q = opaque; @@ -489,6 +500,7 @@ nvme_process_completion(q); } +/* Runs in nvme_submit_command()'s AioContext */ static void nvme_deferred_fn(void *opaque) { NVMeQueuePair *q = opaque; @@ -501,6 +513,7 @@ } } +/* May be run in any AioContext */ static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req, NvmeCmd *cmd, BlockCompletionFunc cb, void *opaque) @@ -522,6 +535,7 @@ defer_call(nvme_deferred_fn, q); } +/* Put into NVMeRequest.cb, so runs in the BDS's main AioContext */ static void nvme_admin_cmd_sync_cb(void *opaque, int ret) { int *pret = opaque; @@ -529,6 +543,7 @@ aio_wait_kick(); } +/* Must be run in the BDS's or qemu's main AioContext */ static int nvme_admin_cmd_sync(BlockDriverState *bs, NvmeCmd *cmd) { BDRVNVMeState *s = bs->opaque; @@ -637,6 +652,7 @@ return ret; } +/* Must be run in the BDS's main AioContext */ static void nvme_poll_queue(NVMeQueuePair *q) { const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES; @@ -659,6 +675,7 @@ qemu_mutex_unlock(&q->lock); } +/* Must be run in the BDS's main AioContext */ static void nvme_poll_queues(BDRVNVMeState *s) { int i; @@ -668,6 +685,7 @@ } } +/* Run as an event notifier in the BDS's main AioContext */ static void nvme_handle_event(EventNotifier *n) { BDRVNVMeState *s = container_of(n, BDRVNVMeState, @@ -721,6 +739,7 @@ return false; } +/* Run as an event notifier in the BDS's main AioContext */ static bool nvme_poll_cb(void *opaque) { EventNotifier *e = opaque; @@ -744,6 +763,7 @@ return false; } +/* Run as an event notifier in the BDS's main AioContext */ static void nvme_poll_ready(EventNotifier *e) { BDRVNVMeState *s = container_of(e, BDRVNVMeState, @@ -1045,7 +1065,7 @@ return 0; } -/* Called with s->dma_map_lock */ +/* Called with s->dma_map_lock, may be run in any AioContext */ static coroutine_fn int nvme_cmd_unmap_qiov(BlockDriverState *bs, QEMUIOVector *qiov) { @@ -1056,13 +1076,17 @@ if (!s->dma_map_count && !qemu_co_queue_empty(&s->dma_flush_queue)) { r = qemu_vfio_dma_reset_temporary(s->vfio); if (!r) { + /* + * Queue access is protected by the dma_map_lock, and all + * coroutines are woken in their own AioContext + */ qemu_co_queue_restart_all(&s->dma_flush_queue); } } return r; } -/* Called with s->dma_map_lock */ +/* Called with s->dma_map_lock, may be run in any AioContext */ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd, NVMeRequest *req, QEMUIOVector *qiov) { @@ -1171,35 +1195,26 @@ typedef struct { Coroutine *co; - bool skip_yield; int ret; + AioContext *ctx; } NVMeCoData; -static void nvme_rw_cb(void *opaque, int ret) +static void nvme_rw_cb_bh(void *opaque) { NVMeCoData *data = opaque; + qemu_coroutine_enter(data->co); +} +/* Put into NVMeRequest.cb, so runs in the BDS's main AioContext */ +static void nvme_rw_cb(void *opaque, int ret) +{ + NVMeCoData *data = opaque; data->ret = ret; - - 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); + if (!data->co) { + /* The rw coroutine hasn't yielded, don't try to enter. */ + return; } + replay_bh_schedule_oneshot_event(data->ctx, nvme_rw_cb_bh, data); } static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs, @@ -1223,7 +1238,7 @@ .cdw12 = cpu_to_le32(cdw12), }; NVMeCoData data = { - .co = qemu_coroutine_self(), + .ctx = bdrv_get_aio_context(bs), .ret = -EINPROGRESS, }; @@ -1240,7 +1255,9 @@ return r; } nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data); - if (!data.skip_yield) { + + data.co = qemu_coroutine_self(); + while (data.ret == -EINPROGRESS) { qemu_coroutine_yield(); } @@ -1336,7 +1353,7 @@ .nsid = cpu_to_le32(s->nsid), }; NVMeCoData data = { - .co = qemu_coroutine_self(), + .ctx = bdrv_get_aio_context(bs), .ret = -EINPROGRESS, }; @@ -1344,7 +1361,9 @@ req = nvme_get_free_req(ioq); assert(req); nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data); - if (!data.skip_yield) { + + data.co = qemu_coroutine_self(); + if (data.ret == -EINPROGRESS) { qemu_coroutine_yield(); } @@ -1385,7 +1404,7 @@ }; NVMeCoData data = { - .co = qemu_coroutine_self(), + .ctx = bdrv_get_aio_context(bs), .ret = -EINPROGRESS, }; @@ -1405,7 +1424,9 @@ assert(req); nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data); - if (!data.skip_yield) { + + data.co = qemu_coroutine_self(); + while (data.ret == -EINPROGRESS) { qemu_coroutine_yield(); } @@ -1433,7 +1454,7 @@ }; NVMeCoData data = { - .co = qemu_coroutine_self(), + .ctx = bdrv_get_aio_context(bs), .ret = -EINPROGRESS, }; @@ -1478,7 +1499,9 @@ trace_nvme_dsm(s, offset, bytes); nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data); - if (!data.skip_yield) { + + data.co = qemu_coroutine_self(); + while (data.ret == -EINPROGRESS) { qemu_coroutine_yield(); } diff -Nru qemu-10.0.7+ds/block/vmdk.c qemu-10.0.8+ds/block/vmdk.c --- qemu-10.0.7+ds/block/vmdk.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/block/vmdk.c 2026-02-12 20:30:14.000000000 +0000 @@ -1089,7 +1089,7 @@ static int vmdk_parse_description(const char *desc, const char *opt_name, char *buf, int buf_size) { - char *opt_pos, *opt_end; + const char *opt_pos, *opt_end; const char *end = desc + strlen(desc); opt_pos = strstr(desc, opt_name); diff -Nru qemu-10.0.7+ds/block/vvfat.c qemu-10.0.8+ds/block/vvfat.c --- qemu-10.0.7+ds/block/vvfat.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/block/vvfat.c 2026-02-12 20:30:14.000000000 +0000 @@ -1826,7 +1826,7 @@ static const char* get_basename(const char* path) { - char* basename = strrchr(path, '/'); + const char *basename = strrchr(path, '/'); if (basename == NULL) return path; else diff -Nru qemu-10.0.7+ds/blockdev.c qemu-10.0.8+ds/blockdev.c --- qemu-10.0.7+ds/blockdev.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/blockdev.c 2026-02-12 20:30:14.000000000 +0000 @@ -685,6 +685,7 @@ GLOBAL_STATE_CODE(); QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) { + QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list); bdrv_unref(bs); } } diff -Nru qemu-10.0.7+ds/bsd-user/syscall_defs.h qemu-10.0.8+ds/bsd-user/syscall_defs.h --- qemu-10.0.7+ds/bsd-user/syscall_defs.h 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/bsd-user/syscall_defs.h 2026-02-12 20:30:14.000000000 +0000 @@ -247,7 +247,7 @@ unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); } __packed; -#if defined(__i386__) +#if defined(TARGET_I386) && !defined(TARGET_X86_64) #define TARGET_HAS_STAT_TIME_T_EXT 1 #endif diff -Nru qemu-10.0.7+ds/chardev/char-io.c qemu-10.0.8+ds/chardev/char-io.c --- qemu-10.0.7+ds/chardev/char-io.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/chardev/char-io.c 2026-02-12 20:30:14.000000000 +0000 @@ -182,3 +182,11 @@ { return io_channel_send_full(ioc, buf, len, NULL, 0); } + +void remove_listener_fd_in_watch(Chardev *chr) +{ + ChardevClass *cc = CHARDEV_GET_CLASS(chr); + if (cc->chr_listener_cleanup) { + cc->chr_listener_cleanup(chr); + } +} diff -Nru qemu-10.0.7+ds/chardev/char-socket.c qemu-10.0.8+ds/chardev/char-socket.c --- qemu-10.0.7+ds/chardev/char-socket.c 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/chardev/char-socket.c 2026-02-12 20:30:14.000000000 +0000 @@ -1581,6 +1581,15 @@ return s->state == TCP_CHARDEV_STATE_CONNECTED; } +static void tcp_chr_listener_cleanup(Chardev *chr) +{ + SocketChardev *s = SOCKET_CHARDEV(chr); + if (s->listener) { + qio_net_listener_set_client_func_full(s->listener, NULL, NULL, + NULL, chr->gcontext); + } +} + static void char_socket_class_init(ObjectClass *oc, void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); @@ -1598,6 +1607,7 @@ cc->chr_add_client = tcp_chr_add_client; cc->chr_add_watch = tcp_chr_add_watch; cc->chr_update_read_handler = tcp_chr_update_read_handler; + cc->chr_listener_cleanup = tcp_chr_listener_cleanup; object_class_property_add(oc, "addr", "SocketAddress", char_socket_get_addr, NULL, diff -Nru qemu-10.0.7+ds/configs/meson/windows.txt qemu-10.0.8+ds/configs/meson/windows.txt --- qemu-10.0.7+ds/configs/meson/windows.txt 2025-12-06 14:54:23.000000000 +0000 +++ qemu-10.0.8+ds/configs/meson/windows.txt 2026-02-12 20:30:14.000000000 +0000 @@ -3,7 +3,6 @@ [built-in options] bindir = '' -prefix = '/qemu' [project options] qemu_suffix = '' diff -Nru qemu-10.0.7+ds/debian/changelog qemu-10.0.8+ds/debian/changelog --- qemu-10.0.7+ds/debian/changelog 2025-12-16 07:01:50.000000000 +0000 +++ qemu-10.0.8+ds/debian/changelog 2026-02-28 19:03:46.000000000 +0000 @@ -1,3 +1,106 @@ +qemu (1:10.0.8+ds-0+deb13u1) trixie; urgency=medium + + * 10.0.8 upstream stable/bugfix release: + - Update version for 10.0.8 release + - scripts/qemugdb: timers: Fix KeyError in 'qemu timers' command + - linux-user/syscall.c: Prevent acquiring clone_lock while fork() + - virtio-gpu: fix error handling in virgl_cmd_resource_create_blob + - virtio-pmem: ignore empty queue notifications + - virtio-gpu-virgl: correct parent for blob memory region + - cryptodev-builtin: Limit the maximum size + - hw/virtio/virtio-crypto: verify asym request size + Closes: #1123670, CVE-2025-14876 + - q35: Fix migration of SMRAM state + - virtio-dmabuf: Ensure UUID persistence for hash table insertion + - vdpa: fix vhost-vdpa suspended state not be shared + - hw/i2c/aspeed_i2c: Fix DMA moving data into incorrect address + - hw/i2c/aspeed: Fix wrong I2CC_DMA_LEN when I2CM_DMA_TX/RX_ADDR set first + - hw/i2c/aspeed_i2c.c: Add a check for dma_read + - hw/adc: Fix out-of-bounds write in Aspeed ADC model + - hw/uefi: fix size negotiation + - hw/nvme: Fix bootindex suffix use-after-free + - python: fix msys64 wheel directory specification + - tests/qtest/ufs-test: Add test for mcq completion queue wraparound + - hw/ufs: Fix mcq completion queue wraparound + - hw/ufs: fix CQE endianness and UPIU length + - hw/ufs: Ensure DBC of PRDT uses only lower 18 bits + - tests/functional: migrate sbsa_ref test images + - pc-bios/optionrom: Use 32-bit linker emulation for the optionroms + - target/i386/tcg: fix a few instructions that do not support VEX.L=1 + - linux-user: fixup termios2 related things on PowerPC + - linux-user: Add missing termios baud rates + - linux-user: Add termios2 support to sparc target + - linux-user: Add termios2 support to sh4 target + - linux-user: Add termios2 support to mips target + - linux-user: Add termios2 support to hppa target + - linux-user: Add termios2 support to alpha target + - linux-user: Add termios2 support + - hw/intc: avoid byte swap fiddling in gicv3 its path + - bsd-user/syscall_defs.h: define STAT_TIME_T_EXT only for 32 bits + - bsd-user: Fix __i386__ test for TARGET_HAS_STAT_TIME_T_EXT + - hw/sd/sdhci: Fix TYPE_IMX_USDHC to implement sd-spec-version 3 by default + - linux-user/aarch64/target_fcntl.h: add missing + TARGET_O_LARGEFILE definition + https://gitlab.com/qemu-project/qemu/-/issues/3262 + - tests/functional: Mark another MIPS replay test as flaky + - tests/functional: Mark the MIPS replay tests as flaky + - target/arm: Correctly trap HCR.TID1 registers in v7A + - target/arm: Correctly honour HCR.TID3 for v7A cores + - target/arm: Don't specify ID_PFR1 accessfn twice + - tests/functional: migrate aspeed_rainier image + - hw/loongarch/virt: Don't abort on access to unimplemented IOCSR + - target/loongarch: Fix exception ADEF/ADEM missing to update CSR_BADV + - target/loongarch: Fix exception BCE missing to update CSR_BADV + - target/loongach: Fix some exceptions failure in updating CSR_BADV + - hw/loongarch/virt: Fix irq allocation failure with pci device from fdt + - hw/loongarch/virt: Modify the interrupt trigger type in fdt table + - hw/i386/kvm: fix PIRQ bounds check in xen_physdev_map_pirq() + Closes: #1125423, CVE-2026-0665 + - target/i386/tcg: allow VEX in 16-bit protected mode + - target/i386/tcg: mask addresses for VSIB + - target/i386/tcg: do not mark all SSE instructions as unaligned + - m68k: fix CAS2 writeback when Dc1==Dc2 + - configs: use default prefix for Windows compilation + - tests: add tcg coverage for fixed mremap bugs + - linux-user: fix reserved_va page leak in do_munmap + - linux-user: fix mremap errors for invalid ranges + - linux-user: fix mremap unmapping adjacent region + - linux-user: allow null `pathname` for statx()/fstatat() + - tcg/riscv: Fix TCG_REG_TMP0 clobber in tcg_gen_dup{m,i} + - monitor/qmp: cleanup SocketChardev listener sources early + to avoid fd handling race + - hw/i2c/imx: Fix trace func name error + - target/i386/tcg: ignore V3 in 32-bit mode + - target/i386: Fix #GP error code for INT instructions + https://gitlab.com/qemu-project/qemu/-/issues/3160 + - qdev: fix error handling in set_uint64_checkmask + - gdbstub: Fix const qualifier build errors with recent glibc + - monitor: Fix const qualifier build errors with recent glibc + - tests/vhost-user-bridge.c: Fix const qualifier build errors + with recent glibc + - i386: Fix const qualifier build errors with recent glibc + - Fix const qualifier build errors with recent glibc + - qga: Fix ubsan warning + - Revert "nvme: Fix coroutine waking" + - nvme: Note in which AioContext some functions run + - block: Fix BDS use after free during shutdown + - scripts/nsis.py: Tell makensis that WoA is 64 bit + - vhost: Always initialize cached vring data + - target/arm: handle unaligned PC during tlb probe + https://gitlab.com/qemu-project/qemu/-/issues/3233 + - tcg: Zero extend 32-bit addresses for TCI + - tests/docker: fix debian-all-test-cross + - tests/docker: handle host-arch selection for all-test-cross + - tests/docker: add --arch-only to qemu deps for all-test-cross + - gitlab: move custom runners to Ubuntu 24.04 + - gitlab-ci.d/cirrus: Update the FreeBSD job to v14.3 + - tests/vm: bump FreeBSD image to 14.3 + * virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch + (fix regression in 10.0.8, introduced in + "virtio-gpu-virgl: correct parent for blob memory region") + + -- Michael Tokarev Sat, 28 Feb 2026 22:03:46 +0300 + qemu (1:10.0.7+ds-0+deb13u1) trixie; urgency=medium * 10.0.7 upstream stable/bugfix release: diff -Nru qemu-10.0.7+ds/debian/control.mk qemu-10.0.8+ds/debian/control.mk --- qemu-10.0.7+ds/debian/control.mk 2025-12-16 07:01:50.000000000 +0000 +++ qemu-10.0.8+ds/debian/control.mk 2026-02-28 17:43:45.000000000 +0000 @@ -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.7+ds +checked-version := 10.0.8+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.7+ds/debian/patches/series qemu-10.0.8+ds/debian/patches/series --- qemu-10.0.7+ds/debian/patches/series 2025-12-16 07:01:50.000000000 +0000 +++ qemu-10.0.8+ds/debian/patches/series 2026-02-28 17:31:14.000000000 +0000 @@ -15,3 +15,4 @@ slof-ensure-ld-is-called-with-C-locale.patch qemu-img-options.patch disable-pycotap.patch +virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch diff -Nru qemu-10.0.7+ds/debian/patches/virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch qemu-10.0.8+ds/debian/patches/virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch --- qemu-10.0.7+ds/debian/patches/virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-10.0.8+ds/debian/patches/virtio-gpu-virgl-Add-virtio-gpu-virgl-hostmem-region.patch 2026-02-28 17:31:14.000000000 +0000 @@ -0,0 +1,179 @@ +From: Akihiko Odaki +Date: Sat, 14 Feb 2026 13:33:36 +0900 +Subject: virtio-gpu-virgl: Add virtio-gpu-virgl-hostmem-region type +Origin: upstream, https://gitlab.com/qemu-project/qemu/-/commit/b2a279094c3b86667969cc645f7fb1087e08dd19 +Forwarded: not-needed + +Commit e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory +region") made the name member of MemoryRegion unset, causing a NULL +pointer dereference[1]: +> Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. +> (gdb) bt +> #0 0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6 +> #1 0x0000555555841bdb in find_fd (head=0x5555572337d0 , +> name=0x0, id=0) at ../migration/cpr.c:68 +> #2 cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at +> ../migration/cpr.c:77 +> #3 0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at +> ../system/physmem.c:2615 +> #4 0x000055555581ae02 in memory_region_finalize (obj=) +> at ../system/memory.c:1816 +> #5 0x0000555555a70ab9 in object_deinit (obj=, +> type=) at ../qom/object.c:715 +> #6 object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729 +> #7 object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232 +> #8 0x0000555555814fae in memory_region_unref (mr=) at +> ../system/memory.c:1848 +> #9 flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301 +> #10 0x0000555555bfc122 in call_rcu_thread (opaque=) at +> ../util/rcu.c:324 +> #11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at +> ../util/qemu-thread-posix.c:393 +> #12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6 +> #13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6 + +The intention of the aforementioned commit is to prevent a MemoryRegion +from parenting itself while its references is counted indendependently +of the device. To achieve the same goal, add a type of QOM objects that +count references and parent MemoryRegions. + +[1] https://lore.kernel.org/qemu-devel/4eb93d7a-1fa9-4b3c-8ad7-a2eb64f025a0@collabora.com/ + +Cc: qemu-stable@nongnu.org +Fixes: e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory region") +Fixes: 8d5a8ebaaff2 ("virtio-gpu-virgl: correct parent for blob memory region") in 10.0.x +Signed-off-by: Akihiko Odaki +Tested-by: Dmitry Osipenko +Tested-by: Joelle van Dyne +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Message-Id: <20260214-region-v1-1-229f00ae1f38@rsg.ci.i.u-tokyo.ac.jp> +(cherry picked from commit b2a279094c3b86667969cc645f7fb1087e08dd19) +Signed-off-by: Michael Tokarev +--- + hw/display/virtio-gpu-virgl.c | 54 +++++++++++++++++++++++++---------- + 1 file changed, 39 insertions(+), 15 deletions(-) + +diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c +index b25ddc0746..362828f54e 100644 +--- a/hw/display/virtio-gpu-virgl.c ++++ b/hw/display/virtio-gpu-virgl.c +@@ -52,11 +52,17 @@ virgl_get_egl_display(G_GNUC_UNUSED void *cookie) + + #if VIRGL_VERSION_MAJOR >= 1 + struct virtio_gpu_virgl_hostmem_region { ++ Object parent_obj; + MemoryRegion mr; + struct VirtIOGPU *g; + bool finish_unmapping; + }; + ++#define TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION "virtio-gpu-virgl-hostmem-region" ++ ++OBJECT_DECLARE_SIMPLE_TYPE(virtio_gpu_virgl_hostmem_region, ++ VIRTIO_GPU_VIRGL_HOSTMEM_REGION) ++ + static struct virtio_gpu_virgl_hostmem_region * + to_hostmem_region(MemoryRegion *mr) + { +@@ -70,14 +76,22 @@ static void virtio_gpu_virgl_resume_cmdq_bh(void *opaque) + virtio_gpu_process_cmdq(g); + } + +-static void virtio_gpu_virgl_hostmem_region_free(void *obj) ++/* ++ * MR could outlive the resource if MR's reference is held outside of ++ * virtio-gpu. In order to prevent unmapping resource while MR is alive, ++ * and thus, making the data pointer invalid, we will block virtio-gpu ++ * command processing until MR is fully unreferenced and freed. ++ */ ++static void virtio_gpu_virgl_hostmem_region_finalize(Object *obj) + { +- MemoryRegion *mr = MEMORY_REGION(obj); +- struct virtio_gpu_virgl_hostmem_region *vmr; ++ struct virtio_gpu_virgl_hostmem_region *vmr = VIRTIO_GPU_VIRGL_HOSTMEM_REGION(obj); + VirtIOGPUBase *b; + VirtIOGPUGL *gl; + +- vmr = to_hostmem_region(mr); ++ if (!vmr->g) { ++ return; ++ } ++ + vmr->finish_unmapping = true; + + b = VIRTIO_GPU_BASE(vmr->g); +@@ -92,11 +106,26 @@ static void virtio_gpu_virgl_hostmem_region_free(void *obj) + qemu_bh_schedule(gl->cmdq_resume_bh); + } + ++static const TypeInfo virtio_gpu_virgl_hostmem_region_info = { ++ .parent = TYPE_OBJECT, ++ .name = TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION, ++ .instance_size = sizeof(struct virtio_gpu_virgl_hostmem_region), ++ .instance_finalize = virtio_gpu_virgl_hostmem_region_finalize ++}; ++ ++static void virtio_gpu_virgl_types(void) ++{ ++ type_register_static(&virtio_gpu_virgl_hostmem_region_info); ++} ++ ++type_init(virtio_gpu_virgl_types) ++ + static int + virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g, + struct virtio_gpu_virgl_resource *res, + uint64_t offset) + { ++ g_autofree char *name = NULL; + struct virtio_gpu_virgl_hostmem_region *vmr; + VirtIOGPUBase *b = VIRTIO_GPU_BASE(g); + MemoryRegion *mr; +@@ -117,21 +146,16 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g, + } + + vmr = g_new0(struct virtio_gpu_virgl_hostmem_region, 1); ++ name = g_strdup_printf("blob[%" PRIu32 "]", res->base.resource_id); ++ object_initialize_child(OBJECT(g), name, vmr, ++ TYPE_VIRTIO_GPU_VIRGL_HOSTMEM_REGION); + vmr->g = g; + + mr = &vmr->mr; +- memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data); ++ memory_region_init_ram_ptr(mr, OBJECT(vmr), "mr", size, data); + memory_region_add_subregion(&b->hostmem, offset, mr); + memory_region_set_enabled(mr, true); + +- /* +- * MR could outlive the resource if MR's reference is held outside of +- * virtio-gpu. In order to prevent unmapping resource while MR is alive, +- * and thus, making the data pointer invalid, we will block virtio-gpu +- * command processing until MR is fully unreferenced and freed. +- */ +- OBJECT(mr)->free = virtio_gpu_virgl_hostmem_region_free; +- + res->mr = mr; + + return 0; +@@ -159,7 +183,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g, + * 1. Begin async unmapping with memory_region_del_subregion() + * and suspend/block cmd processing. + * 2. Wait for res->mr to be freed and cmd processing resumed +- * asynchronously by virtio_gpu_virgl_hostmem_region_free(). ++ * asynchronously by virtio_gpu_virgl_hostmem_region_finalize(). + * 3. Finish the unmapping with final virgl_renderer_resource_unmap(). + */ + if (vmr->finish_unmapping) { +@@ -182,7 +206,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g, + /* memory region owns self res->mr object and frees it by itself */ + memory_region_set_enabled(mr, false); + memory_region_del_subregion(&b->hostmem, mr); +- object_unref(OBJECT(mr)); ++ object_unparent(OBJECT(vmr)); + } + + return 0; +-- +2.47.3 + diff -Nru qemu-10.0.7+ds/gdbstub/gdbstub.c qemu-10.0.8+ds/gdbstub/gdbstub.c --- qemu-10.0.7+ds/gdbstub/gdbstub.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/gdbstub/gdbstub.c 2026-02-12 20:30:14.000000000 +0000 @@ -361,7 +361,7 @@ * qXfer:features:read:ANNEX:OFFSET,LENGTH' * ^p ^newp */ - char *term = strchr(p, ':'); + const char *term = strchr(p, ':'); *newp = term + 1; len = term - p; diff -Nru qemu-10.0.7+ds/gdbstub/user.c qemu-10.0.8+ds/gdbstub/user.c --- qemu-10.0.7+ds/gdbstub/user.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/gdbstub/user.c 2026-02-12 20:30:14.000000000 +0000 @@ -319,7 +319,7 @@ static int gdbserver_open_socket(const char *path, Error **errp) { g_autoptr(GString) buf = g_string_new(""); - char *pid_placeholder; + const char *pid_placeholder; pid_placeholder = strstr(path, "%d"); if (pid_placeholder != NULL) { diff -Nru qemu-10.0.7+ds/hw/adc/aspeed_adc.c qemu-10.0.8+ds/hw/adc/aspeed_adc.c --- qemu-10.0.7+ds/hw/adc/aspeed_adc.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/adc/aspeed_adc.c 2026-02-12 20:30:14.000000000 +0000 @@ -228,7 +228,8 @@ qemu_log_mask(LOG_UNIMP, "%s: engine[%u]: " "0x%" HWADDR_PRIx " 0x%" PRIx64 "\n", __func__, s->engine_id, addr, value); - break; + /* Do not update the regs[] array */ + return; } s->regs[reg] = value; diff -Nru qemu-10.0.7+ds/hw/core/qdev-properties.c qemu-10.0.8+ds/hw/core/qdev-properties.c --- qemu-10.0.7+ds/hw/core/qdev-properties.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/core/qdev-properties.c 2026-02-12 20:30:14.000000000 +0000 @@ -429,7 +429,9 @@ const Property *prop = opaque; uint64_t *ptr = object_field_prop_ptr(obj, prop); - visit_type_uint64(v, name, ptr, errp); + if (!visit_type_uint64(v, name, ptr, errp)) { + return; + } if (*ptr & ~prop->bitmask) { error_setg(errp, "Property value for '%s' has bits outside mask '0x%" PRIx64 "'", name, prop->bitmask); diff -Nru qemu-10.0.7+ds/hw/display/virtio-dmabuf.c qemu-10.0.8+ds/hw/display/virtio-dmabuf.c --- qemu-10.0.7+ds/hw/display/virtio-dmabuf.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/display/virtio-dmabuf.c 2026-02-12 20:30:14.000000000 +0000 @@ -35,11 +35,13 @@ if (resource_uuids == NULL) { resource_uuids = g_hash_table_new_full(qemu_uuid_hash, uuid_equal_func, - NULL, + g_free, g_free); } if (g_hash_table_lookup(resource_uuids, uuid) == NULL) { - g_hash_table_insert(resource_uuids, uuid, value); + g_hash_table_insert(resource_uuids, + g_memdup2(uuid, sizeof(*uuid)), + value); } else { result = false; } diff -Nru qemu-10.0.7+ds/hw/display/virtio-gpu-virgl.c qemu-10.0.8+ds/hw/display/virtio-gpu-virgl.c --- qemu-10.0.7+ds/hw/display/virtio-gpu-virgl.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/display/virtio-gpu-virgl.c 2026-02-12 20:30:14.000000000 +0000 @@ -120,7 +120,7 @@ vmr->g = g; mr = &vmr->mr; - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data); + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data); memory_region_add_subregion(&b->hostmem, offset, mr); memory_region_set_enabled(mr, true); @@ -182,7 +182,7 @@ /* memory region owns self res->mr object and frees it by itself */ memory_region_set_enabled(mr, false); memory_region_del_subregion(&b->hostmem, mr); - object_unparent(OBJECT(mr)); + object_unref(OBJECT(mr)); } return 0; @@ -701,7 +701,7 @@ ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob), cmd, &res->base.addrs, &res->base.iov, &res->base.iov_cnt); - if (!ret) { + if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; } diff -Nru qemu-10.0.7+ds/hw/i2c/aspeed_i2c.c qemu-10.0.8+ds/hw/i2c/aspeed_i2c.c --- qemu-10.0.7+ds/hw/i2c/aspeed_i2c.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/i2c/aspeed_i2c.c 2026-02-12 20:30:14.000000000 +0000 @@ -116,8 +116,6 @@ value = -1; break; } - - value = extract64(bus->dma_dram_offset, 0, 32); break; case A_I2CD_DMA_LEN: if (!aic->has_dma) { @@ -221,6 +219,64 @@ return SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD, TX_STATE); } +/* + * The AST2700 support the maximum DRAM size is 8 GB. + * The DRAM offset range is from 0x0_0000_0000 to + * 0x1_FFFF_FFFF and it is enough to use bits [33:0] + * saving the dram offset. + * Therefore, save the high part physical address bit[1:0] + * of Tx/Rx buffer address as dma_dram_offset bit[33:32]. + */ +static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + uint32_t value; + + assert(aic->has_dma); + + if (aspeed_i2c_is_new_mode(bus->controller)) { + value = bus->regs[R_I2CM_DMA_TX_ADDR]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 0, 32, + FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR)); + if (!aic->has_dma64) { + value = bus->regs[R_I2CM_DMA_TX_ADDR_HI]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 32, 32, + extract32(value, 0, 2)); + } + } else { + value = bus->regs[R_I2CD_DMA_ADDR]; + bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, + value & 0x3ffffffc); + } +} + +static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + uint32_t value; + + assert(aic->has_dma); + + if (aspeed_i2c_is_new_mode(bus->controller)) { + value = bus->regs[R_I2CM_DMA_RX_ADDR]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 0, 32, + FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR)); + if (!aic->has_dma64) { + value = bus->regs[R_I2CM_DMA_RX_ADDR_HI]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 32, 32, + extract32(value, 0, 2)); + } + } else { + value = bus->regs[R_I2CD_DMA_ADDR]; + bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, + value & 0x3ffffffc); + } +} + static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data) { MemTxResult result; @@ -270,9 +326,14 @@ if (aspeed_i2c_is_new_mode(bus->controller)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, TX_LEN, 0); } + aspeed_i2c_set_tx_dma_dram_offset(bus); while (bus->regs[reg_dma_len]) { uint8_t data; - aspeed_i2c_dma_read(bus, &data); + ret = aspeed_i2c_dma_read(bus, &data); + /* Check that we were able to read the DMA */ + if (ret) { + break; + } trace_aspeed_i2c_bus_send("DMA", bus->regs[reg_dma_len], bus->regs[reg_dma_len], data); ret = i2c_send(bus->bus, data); @@ -331,6 +392,7 @@ ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, RX_LEN, 0); } + aspeed_i2c_set_rx_dma_dram_offset(bus); while (bus->regs[reg_dma_len]) { MemTxResult result; @@ -397,6 +459,7 @@ } else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) { uint8_t data; + aspeed_i2c_set_tx_dma_dram_offset(bus); aspeed_i2c_dma_read(bus, &data); return data; } else { @@ -653,20 +716,10 @@ case A_I2CM_DMA_TX_ADDR: bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR); - bus->dma_dram_offset = - deposit64(bus->dma_dram_offset, 0, 32, - FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR)); - bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, - TX_BUF_LEN) + 1; break; case A_I2CM_DMA_RX_ADDR: bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR); - bus->dma_dram_offset = - deposit64(bus->dma_dram_offset, 0, 32, - FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR)); - bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, - RX_BUF_LEN) + 1; break; case A_I2CM_DMA_LEN: w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) || @@ -679,10 +732,16 @@ if (FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN, FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN)); + bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, + I2CM_DMA_LEN, + RX_BUF_LEN) + 1; } if (FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN, FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN)); + bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, + I2CM_DMA_LEN, + TX_BUF_LEN) + 1; } break; case A_I2CM_DMA_LEN_STS: @@ -742,15 +801,6 @@ qemu_log_mask(LOG_UNIMP, "%s: Slave mode DMA TX is not implemented\n", __func__); break; - - /* - * The AST2700 support the maximum DRAM size is 8 GB. - * The DRAM offset range is from 0x0_0000_0000 to - * 0x1_FFFF_FFFF and it is enough to use bits [33:0] - * saving the dram offset. - * Therefore, save the high part physical address bit[1:0] - * of Tx/Rx buffer address as dma_dram_offset bit[33:32]. - */ case A_I2CM_DMA_TX_ADDR_HI: if (!aic->has_dma64) { qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n", @@ -760,8 +810,6 @@ bus->regs[R_I2CM_DMA_TX_ADDR_HI] = FIELD_EX32(value, I2CM_DMA_TX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; case A_I2CM_DMA_RX_ADDR_HI: if (!aic->has_dma64) { @@ -772,8 +820,6 @@ bus->regs[R_I2CM_DMA_RX_ADDR_HI] = FIELD_EX32(value, I2CM_DMA_RX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; case A_I2CS_DMA_TX_ADDR_HI: qemu_log_mask(LOG_UNIMP, @@ -789,8 +835,6 @@ bus->regs[R_I2CS_DMA_RX_ADDR_HI] = FIELD_EX32(value, I2CS_DMA_RX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -881,9 +925,6 @@ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); break; } - - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, - value & 0x3ffffffc); break; case A_I2CD_DMA_LEN: diff -Nru qemu-10.0.7+ds/hw/i2c/imx_i2c.c qemu-10.0.8+ds/hw/i2c/imx_i2c.c --- qemu-10.0.7+ds/hw/i2c/imx_i2c.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/i2c/imx_i2c.c 2026-02-12 20:30:14.000000000 +0000 @@ -151,8 +151,8 @@ { IMXI2CState *s = IMX_I2C(opaque); - trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset), - offset, value); + trace_imx_i2c_write(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset), + offset, value); value &= 0xff; diff -Nru qemu-10.0.7+ds/hw/i386/kvm/xen_evtchn.c qemu-10.0.8+ds/hw/i386/kvm/xen_evtchn.c --- qemu-10.0.7+ds/hw/i386/kvm/xen_evtchn.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/i386/kvm/xen_evtchn.c 2026-02-12 20:30:14.000000000 +0000 @@ -1877,7 +1877,7 @@ return pirq; } map->pirq = pirq; - } else if (pirq > s->nr_pirqs) { + } else if (pirq >= s->nr_pirqs) { return -EINVAL; } else { /* diff -Nru qemu-10.0.7+ds/hw/i386/x86-common.c qemu-10.0.8+ds/hw/i386/x86-common.c --- qemu-10.0.7+ds/hw/i386/x86-common.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/i386/x86-common.c 2026-02-12 20:30:14.000000000 +0000 @@ -653,7 +653,7 @@ uint8_t header[8192], *setup, *kernel; hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0; FILE *f; - char *vmode; + const char *vmode; MachineState *machine = MACHINE(x86ms); struct setup_data *setup_data; const char *kernel_filename = machine->kernel_filename; diff -Nru qemu-10.0.7+ds/hw/intc/arm_gicv3_its_common.c qemu-10.0.8+ds/hw/intc/arm_gicv3_its_common.c --- qemu-10.0.7+ds/hw/intc/arm_gicv3_its_common.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/intc/arm_gicv3_its_common.c 2026-02-12 20:30:14.000000000 +0000 @@ -81,7 +81,7 @@ if (offset == 0x0040 && ((size == 2) || (size == 4))) { GICv3ITSState *s = ARM_GICV3_ITS_COMMON(opaque); GICv3ITSCommonClass *c = ARM_GICV3_ITS_COMMON_GET_CLASS(s); - int ret = c->send_msi(s, le64_to_cpu(value), attrs.requester_id); + int ret = c->send_msi(s, value, attrs.requester_id); if (ret <= 0) { qemu_log_mask(LOG_GUEST_ERROR, diff -Nru qemu-10.0.7+ds/hw/intc/arm_gicv3_its_kvm.c qemu-10.0.8+ds/hw/intc/arm_gicv3_its_kvm.c --- qemu-10.0.7+ds/hw/intc/arm_gicv3_its_kvm.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/intc/arm_gicv3_its_kvm.c 2026-02-12 20:30:14.000000000 +0000 @@ -58,7 +58,7 @@ msi.address_lo = extract64(s->gits_translater_gpa, 0, 32); msi.address_hi = extract64(s->gits_translater_gpa, 32, 32); - msi.data = le32_to_cpu(value); + msi.data = value; msi.flags = KVM_MSI_VALID_DEVID; msi.devid = devid; memset(msi.pad, 0, sizeof(msi.pad)); diff -Nru qemu-10.0.7+ds/hw/loongarch/virt-fdt-build.c qemu-10.0.8+ds/hw/loongarch/virt-fdt-build.c --- qemu-10.0.7+ds/hw/loongarch/virt-fdt-build.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/loongarch/virt-fdt-build.c 2026-02-12 20:30:14.000000000 +0000 @@ -17,6 +17,11 @@ #include "system/reset.h" #include "target/loongarch/cpu.h" +#define FDT_IRQ_TYPE_EDGE_RISING 1 +#define FDT_IRQ_TYPE_EDGE_FALLING 2 +#define FDT_IRQ_TYPE_LEVEL_HIGH 4 +#define FDT_IRQ_TYPE_LEVEL_LOW 8 + static void create_fdt(LoongArchVirtMachineState *lvms) { MachineState *ms = MACHINE(lvms); @@ -317,6 +322,8 @@ uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 10] = {}; uint32_t *irq_map = full_irq_map; const MachineState *ms = MACHINE(lvms); + uint32_t pin_mask; + uint32_t devfn_mask; /* * This code creates a standard swizzle of interrupts such that @@ -329,37 +336,45 @@ */ for (dev = 0; dev < PCI_NUM_PINS; dev++) { - int devfn = dev * 0x8; + int devfn = PCI_DEVFN(dev, 0); for (pin = 0; pin < PCI_NUM_PINS; pin++) { - int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); + int irq_nr = VIRT_DEVICE_IRQS + \ + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS); int i = 0; - /* Fill PCI address cells */ - irq_map[i] = cpu_to_be32(devfn << 8); - i += 3; - - /* Fill PCI Interrupt cells */ - irq_map[i] = cpu_to_be32(pin + 1); - i += 1; - - /* Fill interrupt controller phandle and cells */ - irq_map[i++] = cpu_to_be32(*pch_pic_phandle); - irq_map[i++] = cpu_to_be32(irq_nr); + uint32_t map[] = { + devfn << 8, 0, 0, /* devfn */ + pin + 1, /* PCI pin */ + *pch_pic_phandle, /* interrupt controller handle */ + irq_nr, /* irq number */ + FDT_IRQ_TYPE_LEVEL_HIGH }; /* irq trigger level */ if (!irq_map_stride) { - irq_map_stride = i; + irq_map_stride = sizeof(map) / sizeof(uint32_t); + } + + /* Convert map to big endian */ + for (i = 0; i < irq_map_stride; i++) { + irq_map[i] = cpu_to_be32(map[i]); } + irq_map += irq_map_stride; } } - qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map, PCI_NUM_PINS * PCI_NUM_PINS * irq_map_stride * sizeof(uint32_t)); + + /* Only need to match the pci slot bit */ + devfn_mask = PCI_DEVFN((PCI_NUM_PINS - 1), 0) << 8; + /* The pci interrupt only needs to match the specified low bit */ + pin_mask = (1 << ((PCI_NUM_PINS - 1))) - 1; + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask", - 0x1800, 0, 0, 0x7); + devfn_mask, 0, 0, /* address cells */ + pin_mask); } static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, @@ -396,6 +411,8 @@ 2, base_mmio, 2, size_mmio); qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", 0, *pch_msi_phandle, 0, 0x10000); + + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1); fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle); g_free(nodename); } @@ -416,7 +433,8 @@ if (chosen) { qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); } - qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, + FDT_IRQ_TYPE_LEVEL_HIGH); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); @@ -436,7 +454,8 @@ "loongson,ls7a-rtc"); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4); + VIRT_RTC_IRQ - VIRT_GSI_BASE , + FDT_IRQ_TYPE_LEVEL_HIGH); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); diff -Nru qemu-10.0.7+ds/hw/loongarch/virt.c qemu-10.0.8+ds/hw/loongarch/virt.c --- qemu-10.0.7+ds/hw/loongarch/virt.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/loongarch/virt.c 2026-02-12 20:30:14.000000000 +0000 @@ -45,6 +45,7 @@ #include "hw/block/flash.h" #include "hw/virtio/virtio-iommu.h" #include "qemu/error-report.h" +#include "qemu/log.h" static void virt_get_veiointc(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -532,8 +533,15 @@ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, features, attrs, NULL); break; + case VERSION_REG: + case FEATURE_REG: + case VENDOR_REG: + case CPUNAME_REG: + break; default: - g_assert_not_reached(); + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n", + __func__, addr); + break; } return MEMTX_OK; @@ -580,7 +588,9 @@ } break; default: - g_assert_not_reached(); + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n", + __func__, addr); + break; } *data = ret; diff -Nru qemu-10.0.7+ds/hw/nvme/ns.c qemu-10.0.8+ds/hw/nvme/ns.c --- qemu-10.0.7+ds/hw/nvme/ns.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/nvme/ns.c 2026-02-12 20:30:14.000000000 +0000 @@ -822,12 +822,11 @@ static void nvme_ns_instance_init(Object *obj) { NvmeNamespace *ns = NVME_NS(obj); - char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid); - device_add_bootindex_property(obj, &ns->bootindex, "bootindex", - bootindex, DEVICE(obj)); + sprintf(ns->bootindex_suffix, "/namespace@%" PRIu32 ",0", ns->params.nsid); - g_free(bootindex); + device_add_bootindex_property(obj, &ns->bootindex, "bootindex", + ns->bootindex_suffix, DEVICE(obj)); } static const TypeInfo nvme_ns_info = { diff -Nru qemu-10.0.7+ds/hw/nvme/nvme.h qemu-10.0.8+ds/hw/nvme/nvme.h --- qemu-10.0.7+ds/hw/nvme/nvme.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/nvme/nvme.h 2026-02-12 20:30:14.000000000 +0000 @@ -229,6 +229,7 @@ DeviceState parent_obj; BlockConf blkconf; int32_t bootindex; + char bootindex_suffix[24]; int64_t size; int64_t moff; NvmeIdNs id_ns; diff -Nru qemu-10.0.7+ds/hw/pci-host/q35.c qemu-10.0.8+ds/hw/pci-host/q35.c --- qemu-10.0.7+ds/hw/pci-host/q35.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/pci-host/q35.c 2026-02-12 20:30:14.000000000 +0000 @@ -432,30 +432,27 @@ } if (*reg == MCH_HOST_BRIDGE_F_SMBASE_QUERY) { - pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = - MCH_HOST_BRIDGE_F_SMBASE_LCK; + pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = MCH_HOST_BRIDGE_F_SMBASE_LCK; *reg = MCH_HOST_BRIDGE_F_SMBASE_IN_RAM; return; } /* - * default/reset state, discard written value - * which will disable SMRAM balackhole at SMBASE + * reg value can come from register write/reset/migration source, + * update wmask to be in sync with it regardless of source */ - if (pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] == 0xff) { - *reg = 0x00; + if (*reg == MCH_HOST_BRIDGE_F_SMBASE_IN_RAM) { + pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = MCH_HOST_BRIDGE_F_SMBASE_LCK; + return; } - - memory_region_transaction_begin(); if (*reg & MCH_HOST_BRIDGE_F_SMBASE_LCK) { - /* disable all writes */ - pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] &= - ~MCH_HOST_BRIDGE_F_SMBASE_LCK; + /* lock register at 0x2 and disable all writes */ + pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0; *reg = MCH_HOST_BRIDGE_F_SMBASE_LCK; - lck = true; - } else { - lck = false; } + + lck = *reg & MCH_HOST_BRIDGE_F_SMBASE_LCK; + memory_region_transaction_begin(); memory_region_set_enabled(&mch->smbase_blackhole, lck); memory_region_set_enabled(&mch->smbase_window, lck); memory_region_transaction_commit(); diff -Nru qemu-10.0.7+ds/hw/sd/sdhci.c qemu-10.0.8+ds/hw/sd/sdhci.c --- qemu-10.0.7+ds/hw/sd/sdhci.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/sd/sdhci.c 2026-02-12 20:30:14.000000000 +0000 @@ -1888,9 +1888,11 @@ static void imx_usdhc_init(Object *obj) { SDHCIState *s = SYSBUS_SDHCI(obj); + DeviceState *dev = DEVICE(obj); s->io_ops = &usdhc_mmio_ops; s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ; + qdev_prop_set_uint8(dev, "sd-spec-version", 3); } /* --- qdev Samsung s3c --- */ diff -Nru qemu-10.0.7+ds/hw/uefi/var-service-vars.c qemu-10.0.8+ds/hw/uefi/var-service-vars.c --- qemu-10.0.7+ds/hw/uefi/var-service-vars.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/uefi/var-service-vars.c 2026-02-12 20:30:14.000000000 +0000 @@ -592,7 +592,7 @@ return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE); } - ps->payload_size = uv->buf_size; + ps->payload_size = uv->buf_size - sizeof(*mhdr) - sizeof(*mvar); mvar->status = EFI_SUCCESS; return length; } diff -Nru qemu-10.0.7+ds/hw/ufs/lu.c qemu-10.0.8+ds/hw/ufs/lu.c --- qemu-10.0.7+ds/hw/ufs/lu.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/ufs/lu.c 2026-02-12 20:30:14.000000000 +0000 @@ -53,8 +53,7 @@ response = UFS_COMMAND_RESULT_FAIL; } - data_segment_length = - cpu_to_be16(sense_len + sizeof(req->rsp_upiu.sr.sense_data_len)); + data_segment_length = sense_len + sizeof(req->rsp_upiu.sr.sense_data_len); ufs_build_upiu_header(req, UFS_UPIU_TRANSACTION_RESPONSE, flags, response, status, data_segment_length); } diff -Nru qemu-10.0.7+ds/hw/ufs/ufs.c qemu-10.0.8+ds/hw/ufs/ufs.c --- qemu-10.0.7+ds/hw/ufs/ufs.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/ufs/ufs.c 2026-02-12 20:30:14.000000000 +0000 @@ -224,7 +224,8 @@ for (uint16_t i = 0; i < prdt_len; ++i) { hwaddr data_dma_addr = le64_to_cpu(prd_entries[i].addr); - uint32_t data_byte_count = le32_to_cpu(prd_entries[i].size) + 1; + uint32_t data_byte_count = + (le32_to_cpu(prd_entries[i].size) & 0x3ffff) + 1; qemu_sglist_add(req->sg, data_dma_addr, data_byte_count); req->data_len += data_byte_count; } @@ -446,17 +447,30 @@ QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) { + if (ufs_mcq_cq_full(u, cq->cqid)) { + break; + } + ufs_dma_write_rsp_upiu(req); - req->cqe.utp_addr = - ((uint64_t)req->utrd.command_desc_base_addr_hi << 32ULL) | - req->utrd.command_desc_base_addr_lo; - req->cqe.utp_addr |= req->sq->sqid; - req->cqe.resp_len = req->utrd.response_upiu_length; - req->cqe.resp_off = req->utrd.response_upiu_offset; - req->cqe.prdt_len = req->utrd.prd_table_length; - req->cqe.prdt_off = req->utrd.prd_table_offset; - req->cqe.status = req->utrd.header.dword_2 & 0xf; + /* UTRD/CQE are LE; round-trip through host to keep BE correct. */ + uint64_t ucdba = + ((uint64_t)le32_to_cpu(req->utrd.command_desc_base_addr_hi) + << 32ULL) | + le32_to_cpu(req->utrd.command_desc_base_addr_lo); + uint16_t resp_len = le16_to_cpu(req->utrd.response_upiu_length); + uint16_t resp_off = le16_to_cpu(req->utrd.response_upiu_offset); + uint16_t prdt_len = le16_to_cpu(req->utrd.prd_table_length); + uint16_t prdt_off = le16_to_cpu(req->utrd.prd_table_offset); + uint8_t status = le32_to_cpu(req->utrd.header.dword_2) & UFS_MASK_OCS; + + ucdba |= req->sq->sqid; + req->cqe.utp_addr = cpu_to_le64(ucdba); + req->cqe.resp_len = cpu_to_le16(resp_len); + req->cqe.resp_off = cpu_to_le16(resp_off); + req->cqe.prdt_len = cpu_to_le16(prdt_len); + req->cqe.prdt_off = cpu_to_le16(prdt_off); + req->cqe.status = status; req->cqe.error = 0; ret = ufs_addr_write(u, cq->addr + tail, &req->cqe, sizeof(req->cqe)); @@ -468,6 +482,12 @@ tail = (tail + sizeof(req->cqe)) % (cq->size * sizeof(req->cqe)); ufs_mcq_update_cq_tail(u, cq->cqid, tail); + if (QTAILQ_EMPTY(&req->sq->req_list) && + !ufs_mcq_sq_empty(u, req->sq->sqid)) { + /* Dequeueing from SQ was blocked due to lack of free requests */ + qemu_bh_schedule(req->sq->bh); + } + ufs_clear_req(req); QTAILQ_INSERT_TAIL(&req->sq->req_list, req, entry); } @@ -777,10 +797,18 @@ } opr->sq.tp = data; break; - case offsetof(UfsMcqOpReg, cq.hp): + case offsetof(UfsMcqOpReg, cq.hp): { + UfsCq *cq = u->cq[qid]; + + if (ufs_mcq_cq_full(u, qid) && !QTAILQ_EMPTY(&cq->req_list)) { + /* Enqueueing to CQ was blocked because it was full */ + qemu_bh_schedule(cq->bh); + } + opr->cq.hp = data; ufs_mcq_update_cq_head(u, qid, data); break; + } case offsetof(UfsMcqOpReg, cq_int.is): opr->cq_int.is &= ~data; break; diff -Nru qemu-10.0.7+ds/hw/ufs/ufs.h qemu-10.0.8+ds/hw/ufs/ufs.h --- qemu-10.0.7+ds/hw/ufs/ufs.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/ufs/ufs.h 2026-02-12 20:30:14.000000000 +0000 @@ -200,6 +200,15 @@ return ufs_mcq_cq_tail(u, qid) == ufs_mcq_cq_head(u, qid); } +static inline bool ufs_mcq_cq_full(UfsHc *u, uint32_t qid) +{ + uint32_t tail = ufs_mcq_cq_tail(u, qid); + uint16_t cq_size = u->cq[qid]->size; + + tail = (tail + sizeof(UfsCqEntry)) % (sizeof(UfsCqEntry) * cq_size); + return tail == ufs_mcq_cq_head(u, qid); +} + #define TYPE_UFS "ufs" #define UFS(obj) OBJECT_CHECK(UfsHc, (obj), TYPE_UFS) diff -Nru qemu-10.0.7+ds/hw/virtio/vhost-vdpa.c qemu-10.0.8+ds/hw/virtio/vhost-vdpa.c --- qemu-10.0.7+ds/hw/virtio/vhost-vdpa.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/virtio/vhost-vdpa.c 2026-02-12 20:30:14.000000000 +0000 @@ -890,7 +890,7 @@ ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status); trace_vhost_vdpa_reset_device(dev); - v->suspended = false; + v->shared->suspended = false; return ret; } @@ -1339,7 +1339,7 @@ if (unlikely(r)) { error_report("Cannot suspend: %s(%d)", g_strerror(errno), errno); } else { - v->suspended = true; + v->shared->suspended = true; return; } } @@ -1461,7 +1461,7 @@ return 0; } - if (!v->suspended) { + if (!v->shared->suspended) { /* * Cannot trust in value returned by device, let vhost recover used * idx from guest. diff -Nru qemu-10.0.7+ds/hw/virtio/vhost.c qemu-10.0.8+ds/hw/virtio/vhost.c --- qemu-10.0.7+ds/hw/virtio/vhost.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/virtio/vhost.c 2026-02-12 20:30:14.000000000 +0000 @@ -1245,7 +1245,7 @@ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusState *vbus = VIRTIO_BUS(qbus); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); - hwaddr s, l, a; + hwaddr l; int r; int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_file file = { @@ -1256,8 +1256,17 @@ }; struct VirtQueue *vvq = virtio_get_queue(vdev, idx); - a = virtio_queue_get_desc_addr(vdev, idx); - if (a == 0) { + vq->desc_size = virtio_queue_get_desc_size(vdev, idx); + vq->desc_phys = virtio_queue_get_desc_addr(vdev, idx); + vq->desc = NULL; + vq->avail_size = virtio_queue_get_avail_size(vdev, idx); + vq->avail_phys = virtio_queue_get_avail_addr(vdev, idx); + vq->avail = NULL; + vq->used_size = virtio_queue_get_used_size(vdev, idx); + vq->used_phys = virtio_queue_get_used_addr(vdev, idx); + vq->used = NULL; + + if (vq->desc_phys == 0) { /* Queue might not be ready for start */ return 0; } @@ -1285,24 +1294,23 @@ } } - vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx); - vq->desc_phys = a; - vq->desc = vhost_memory_map(dev, a, &l, false); - if (!vq->desc || l != s) { + l = vq->desc_size; + vq->desc = vhost_memory_map(dev, vq->desc_phys, &l, false); + if (!vq->desc || l != vq->desc_size) { r = -ENOMEM; goto fail_alloc_desc; } - vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx); - vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx); - vq->avail = vhost_memory_map(dev, a, &l, false); - if (!vq->avail || l != s) { + + l = vq->avail_size; + vq->avail = vhost_memory_map(dev, vq->avail_phys, &l, false); + if (!vq->avail || l != vq->avail_size) { r = -ENOMEM; goto fail_alloc_avail; } - vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx); - vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx); - vq->used = vhost_memory_map(dev, a, &l, true); - if (!vq->used || l != s) { + + l = vq->used_size; + vq->used = vhost_memory_map(dev, vq->used_phys, &l, true); + if (!vq->used || l != vq->used_size) { r = -ENOMEM; goto fail_alloc_used; } diff -Nru qemu-10.0.7+ds/hw/virtio/virtio-crypto.c qemu-10.0.8+ds/hw/virtio/virtio-crypto.c --- qemu-10.0.7+ds/hw/virtio/virtio-crypto.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/virtio/virtio-crypto.c 2026-02-12 20:30:14.000000000 +0000 @@ -767,11 +767,18 @@ uint32_t len; uint8_t *src = NULL; uint8_t *dst = NULL; + uint64_t max_len; asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1); src_len = ldl_le_p(&req->para.src_data_len); dst_len = ldl_le_p(&req->para.dst_data_len); + max_len = (uint64_t)src_len + dst_len; + if (unlikely(max_len > vcrypto->conf.max_size)) { + virtio_error(vdev, "virtio-crypto asym request is too large"); + goto err; + } + if (src_len > 0) { src = g_malloc0(src_len); len = iov_to_buf(iov, out_num, 0, src, src_len); diff -Nru qemu-10.0.7+ds/hw/virtio/virtio-pmem.c qemu-10.0.8+ds/hw/virtio/virtio-pmem.c --- qemu-10.0.7+ds/hw/virtio/virtio-pmem.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/hw/virtio/virtio-pmem.c 2026-02-12 20:30:14.000000000 +0000 @@ -74,7 +74,6 @@ trace_virtio_pmem_flush_request(); req_data = virtqueue_pop(vq, sizeof(VirtIODeviceRequest)); if (!req_data) { - virtio_error(vdev, "virtio-pmem missing request data"); return; } diff -Nru qemu-10.0.7+ds/include/block/ufs.h qemu-10.0.8+ds/include/block/ufs.h --- qemu-10.0.7+ds/include/block/ufs.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/include/block/ufs.h 2026-02-12 20:30:14.000000000 +0000 @@ -645,7 +645,7 @@ }; enum { - UFS_MASK_OCS = 0x0F, + UFS_MASK_OCS = 0xFF, }; /* diff -Nru qemu-10.0.7+ds/include/chardev/char-io.h qemu-10.0.8+ds/include/chardev/char-io.h --- qemu-10.0.7+ds/include/chardev/char-io.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/include/chardev/char-io.h 2026-02-12 20:30:14.000000000 +0000 @@ -43,4 +43,6 @@ int io_channel_send_full(QIOChannel *ioc, const void *buf, size_t len, int *fds, size_t nfds); +void remove_listener_fd_in_watch(Chardev *chr); + #endif /* CHAR_IO_H */ diff -Nru qemu-10.0.7+ds/include/chardev/char.h qemu-10.0.8+ds/include/chardev/char.h --- qemu-10.0.7+ds/include/chardev/char.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/include/chardev/char.h 2026-02-12 20:30:14.000000000 +0000 @@ -307,6 +307,8 @@ /* handle various events */ void (*chr_be_event)(Chardev *s, QEMUChrEvent event); + + void (*chr_listener_cleanup)(Chardev *chr); }; Chardev *qemu_chardev_new(const char *id, const char *typename, diff -Nru qemu-10.0.7+ds/include/hw/virtio/vhost-vdpa.h qemu-10.0.8+ds/include/hw/virtio/vhost-vdpa.h --- qemu-10.0.7+ds/include/hw/virtio/vhost-vdpa.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/include/hw/virtio/vhost-vdpa.h 2026-02-12 20:30:14.000000000 +0000 @@ -56,6 +56,12 @@ /* SVQ switching is in progress, or already completed? */ SVQTransitionState svq_switching; + + /* + * Device suspended successfully. + * The vhost_vdpa devices cannot have different suspended states. + */ + bool suspended; } VhostVDPAShared; typedef struct vhost_vdpa { @@ -63,8 +69,6 @@ uint32_t address_space_id; uint64_t acked_features; bool shadow_vqs_enabled; - /* Device suspended successfully */ - bool suspended; VhostVDPAShared *shared; GPtrArray *shadow_vqs; const VhostShadowVirtqueueOps *shadow_vq_ops; diff -Nru qemu-10.0.7+ds/linux-user/aarch64/target_fcntl.h qemu-10.0.8+ds/linux-user/aarch64/target_fcntl.h --- qemu-10.0.7+ds/linux-user/aarch64/target_fcntl.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/aarch64/target_fcntl.h 2026-02-12 20:30:14.000000000 +0000 @@ -11,6 +11,7 @@ #define TARGET_O_DIRECTORY 040000 /* must be a directory */ #define TARGET_O_NOFOLLOW 0100000 /* don't follow links */ #define TARGET_O_DIRECT 0200000 /* direct disk access hint */ +#define TARGET_O_LARGEFILE 0400000 #include "../generic/fcntl.h" #endif diff -Nru qemu-10.0.7+ds/linux-user/alpha/termbits.h qemu-10.0.8+ds/linux-user/alpha/termbits.h --- qemu-10.0.7+ds/linux-user/alpha/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/alpha/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -17,6 +17,29 @@ target_speed_t c_ospeed; /* output speed */ }; +struct target_termios2 { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_cc_t c_line; /* line discipline (== c_cc[19]) */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + +struct target_ktermios { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_cc_t c_line; /* line discipline (== c_cc[19]) */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + + /* c_cc characters */ #define TARGET_VEOF 0 #define TARGET_VEOL 1 @@ -126,6 +149,7 @@ #define TARGET_B3000000 00034 #define TARGET_B3500000 00035 #define TARGET_B4000000 00036 +#define TARGET_BOTHER 00037 #define TARGET_CSIZE 00001400 #define TARGET_CS5 00000000 @@ -247,6 +271,12 @@ #define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ #define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ #define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct target_termios2) +#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct target_termios2) +#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct target_termios2) +#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct target_termios2) +#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485) +#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485) #define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */ #define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open the slave */ diff -Nru qemu-10.0.7+ds/linux-user/generic/termbits.h qemu-10.0.8+ds/linux-user/generic/termbits.h --- qemu-10.0.7+ds/linux-user/generic/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/generic/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -157,7 +157,7 @@ #define TARGET_B3000000 0010015 #define TARGET_B3500000 0010016 #define TARGET_B4000000 0010017 -#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ +#define TARGET_CIBAUD 002003600000 /* input baud rate */ #define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ #define TARGET_CRTSCTS 020000000000 /* flow control */ diff -Nru qemu-10.0.7+ds/linux-user/hppa/termbits.h qemu-10.0.8+ds/linux-user/hppa/termbits.h --- qemu-10.0.7+ds/linux-user/hppa/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/hppa/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -18,6 +18,29 @@ target_cc_t c_cc[TARGET_NCCS]; /* control characters */ }; +struct target_termios2 { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + +struct target_ktermios { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + + /* c_iflag bits */ #define TARGET_IGNBRK 0000001 #define TARGET_BRKINT 0000002 @@ -100,14 +123,28 @@ #define TARGET_HUPCL 0002000 #define TARGET_CLOCAL 0004000 #define TARGET_CBAUDEX 0010000 +#define TARGET_BOTHER 0010000 #define TARGET_B57600 0010001 #define TARGET_B115200 0010002 #define TARGET_B230400 0010003 #define TARGET_B460800 0010004 -#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ +#define TARGET_B500000 0010005 +#define TARGET_B576000 0010006 +#define TARGET_B921600 0010007 +#define TARGET_B1000000 0010010 +#define TARGET_B1152000 0010011 +#define TARGET_B1500000 0010012 +#define TARGET_B2000000 0010013 +#define TARGET_B2500000 0010014 +#define TARGET_B3000000 0010015 +#define TARGET_B3500000 0010016 +#define TARGET_B4000000 0010017 +#define TARGET_CIBAUD 002003600000 /* input baud rate */ #define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ #define TARGET_CRTSCTS 020000000000 /* flow control */ +#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define TARGET_ISIG 0000001 #define TARGET_ICANON 0000002 @@ -190,6 +227,12 @@ #define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ #define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ #define TARGET_TIOCGSID TARGET_IOR('T', 20, int) +#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct target_termios2) +#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct target_termios2) +#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct target_termios2) +#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct target_termios2) +#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485) +#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485) #define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) diff -Nru qemu-10.0.7+ds/linux-user/ioctls.h qemu-10.0.8+ds/linux-user/ioctls.h --- qemu-10.0.7+ds/linux-user/ioctls.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/ioctls.h 2026-02-12 20:30:14.000000000 +0000 @@ -1,5 +1,11 @@ /* emulated ioctl list */ +#ifdef TARGET_TCGETS2 + IOCTL(TCGETS2, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios2))) + IOCTL(TCSETS2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2))) + IOCTL(TCSETSW2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2))) + IOCTL(TCSETSF2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2))) +#endif IOCTL(TCGETS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) IOCTL(TCSETS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) IOCTL(TCSETSF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) diff -Nru qemu-10.0.7+ds/linux-user/main.c qemu-10.0.8+ds/linux-user/main.c --- qemu-10.0.7+ds/linux-user/main.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/main.c 2026-02-12 20:30:14.000000000 +0000 @@ -145,6 +145,7 @@ void fork_start(void) { start_exclusive(); + clone_fork_start(); mmap_fork_start(); cpu_list_lock(); qemu_plugin_user_prefork_lock(); @@ -174,6 +175,7 @@ cpu_list_unlock(); } gdbserver_fork_end(thread_cpu, pid); + clone_fork_end(child); /* * qemu_init_cpu_list() reinitialized the child exclusive state, but we * also need to keep current_cpu consistent, so call end_exclusive() for diff -Nru qemu-10.0.7+ds/linux-user/mips/termbits.h qemu-10.0.8+ds/linux-user/mips/termbits.h --- qemu-10.0.7+ds/linux-user/mips/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/mips/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -18,6 +18,29 @@ target_cc_t c_cc[TARGET_NCCS]; /* control characters */ }; +struct target_termios2 { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + +struct target_ktermios { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + + /* c_iflag bits */ #define TARGET_IGNBRK 0000001 #define TARGET_BRKINT 0000002 @@ -116,10 +139,12 @@ #define TARGET_B3000000 0010015 #define TARGET_B3500000 0010016 #define TARGET_B4000000 0010017 -#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ +#define TARGET_CIBAUD 002003600000 /* input baud rate */ #define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ #define TARGET_CRTSCTS 020000000000 /* flow control */ +#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define TARGET_ISIG 0000001 #define TARGET_ICANON 0000002 @@ -227,10 +252,10 @@ #define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ #define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ #define TARGET_TIOCGSID 0x7416 /* Return the session ID of FD */ -#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct termios2) -#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct termios2) -#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct termios2) -#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct termios2) +#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct target_termios2) +#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct target_termios2) +#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct target_termios2) +#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct target_termios2) #define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485) #define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485) #define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ diff -Nru qemu-10.0.7+ds/linux-user/mmap.c qemu-10.0.8+ds/linux-user/mmap.c --- qemu-10.0.7+ds/linux-user/mmap.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/mmap.c 2026-02-12 20:30:14.000000000 +0000 @@ -1027,9 +1027,9 @@ void *host_start; int prot; - last = start + len - 1; + last = ROUND_UP(start + len, TARGET_PAGE_SIZE) - 1; real_start = start & -host_page_size; - real_last = ROUND_UP(last, host_page_size) - 1; + real_last = ROUND_UP(last + 1, host_page_size) - 1; /* * If guest pages remain on the first or last host pages, @@ -1108,12 +1108,15 @@ int prot; void *host_addr; - if (!guest_range_valid_untagged(old_addr, old_size) || - ((flags & MREMAP_FIXED) && + if (((flags & MREMAP_FIXED) && !guest_range_valid_untagged(new_addr, new_size)) || ((flags & MREMAP_MAYMOVE) == 0 && !guest_range_valid_untagged(old_addr, new_size))) { - errno = ENOMEM; + errno = EINVAL; + return -1; + } + if (!guest_range_valid_untagged(old_addr, old_size)) { + errno = EFAULT; return -1; } @@ -1169,7 +1172,8 @@ errno = ENOMEM; host_addr = MAP_FAILED; } else if (reserved_va && old_size > new_size) { - mmap_reserve_or_unmap(old_addr + old_size, + /* Re-reserve pages we just shrunk out of the mapping */ + mmap_reserve_or_unmap(old_addr + new_size, old_size - new_size); } } diff -Nru qemu-10.0.7+ds/linux-user/ppc/termbits.h qemu-10.0.8+ds/linux-user/ppc/termbits.h --- qemu-10.0.7+ds/linux-user/ppc/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/ppc/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -129,6 +129,7 @@ #define TARGET_B3000000 00034 #define TARGET_B3500000 00035 #define TARGET_B4000000 00036 +#define TARGET_BOTHER 00037 #define TARGET_CSIZE 00001400 #define TARGET_CS5 00000000 diff -Nru qemu-10.0.7+ds/linux-user/sh4/termbits.h qemu-10.0.8+ds/linux-user/sh4/termbits.h --- qemu-10.0.7+ds/linux-user/sh4/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/sh4/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -18,6 +18,28 @@ target_cc_t c_cc[TARGET_NCCS]; /* control characters */ }; +struct target_termios2 { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + +struct target_ktermios { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define TARGET_VINTR 0 @@ -120,6 +142,7 @@ #define TARGET_HUPCL 0002000 #define TARGET_CLOCAL 0004000 #define TARGET_CBAUDEX 0010000 +#define TARGET_BOTHER 0010000 #define TARGET_B57600 0010001 #define TARGET_B115200 0010002 #define TARGET_B230400 0010003 @@ -135,10 +158,12 @@ #define TARGET_B3000000 0010015 #define TARGET_B3500000 0010016 #define TARGET_B4000000 0010017 -#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ +#define TARGET_CIBAUD 002003600000 /* input baud rate */ #define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ #define TARGET_CRTSCTS 020000000000 /* flow control */ +#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define TARGET_ISIG 0000001 #define TARGET_ICANON 0000002 @@ -251,14 +276,17 @@ #define TARGET_TIOCNOTTY TARGET_IO('T', 34) /* 0x5422 */ #define TARGET_TIOCSETD TARGET_IOW('T', 35, int) /* 0x5423 */ #define TARGET_TIOCGETD TARGET_IOR('T', 36, int) /* 0x5424 */ -#define TARGET_TCSBRKP TARGET_IOW('T', 37, int) /* 0x5425 */ /* Needed for POSIX tcse -ndbreak() */ +#define TARGET_TCSBRKP TARGET_IOW('T', 37, int) /* 0x5425 */ /* Needed for POSIX tcsendbreak() */ #define TARGET_TIOCSBRK TARGET_IO('T', 39) /* 0x5427 */ /* BSD compatibility */ #define TARGET_TIOCCBRK TARGET_IO('T', 40) /* 0x5428 */ /* BSD compatibility */ -#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session -ID of FD */ -#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-m -ux device) */ +#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session ID of FD */ +#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct target_termios2) +#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct target_termios2) +#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct target_termios2) +#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct target_termios2) +#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485) +#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485) +#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */ #define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open the slave */ @@ -270,8 +298,7 @@ #define TARGET_TIOCSLCKTRMIOS 0x5457 #define TARGET_TIOCSERGSTRUCT TARGET_IOR('T', 88, int) /* 0x5458 */ /* For d ebugging only */ -#define TARGET_TIOCSERGETLSR TARGET_IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line sta -tus register */ +#define TARGET_TIOCSERGETLSR TARGET_IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line status register */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ # define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ #define TARGET_TIOCSERGETMULTI TARGET_IOR('T', 90, int) /* 0x545A @@ -279,9 +306,7 @@ #define TARGET_TIOCSERSETMULTI TARGET_IOW('T', 91, int) /* 0x545B */ /* Set multiport config */ -#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /* wait for a change on -serial input line(s) */ -#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /* read -serial port inline interrupt counts */ +#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /* wait for a change on serial input line(s) */ +#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /* read serial port inline interrupt counts */ #endif diff -Nru qemu-10.0.7+ds/linux-user/sparc/termbits.h qemu-10.0.8+ds/linux-user/sparc/termbits.h --- qemu-10.0.7+ds/linux-user/sparc/termbits.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/sparc/termbits.h 2026-02-12 20:30:14.000000000 +0000 @@ -18,6 +18,28 @@ target_cc_t c_cc[TARGET_NCCS]; /* control characters */ }; +struct target_termios2 { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + +struct target_ktermios { + target_tcflag_t c_iflag; /* input mode flags */ + target_tcflag_t c_oflag; /* output mode flags */ + target_tcflag_t c_cflag; /* control mode flags */ + target_tcflag_t c_lflag; /* local mode flags */ + target_cc_t c_line; /* line discipline */ + target_cc_t c_cc[TARGET_NCCS]; /* control characters */ + target_speed_t c_ispeed; /* input speed */ + target_speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define TARGET_VINTR 0 @@ -128,6 +150,7 @@ #define TARGET_HUPCL 0x00000400 #define TARGET_CLOCAL 0x00000800 #define TARGET_CBAUDEX 0x00001000 +#define TARGET_BOTHER 0x00001000 /* We'll never see these speeds with the Zilogs, but for completeness... */ #define TARGET_B57600 0x00001001 #define TARGET_B115200 0x00001002 @@ -154,10 +177,12 @@ #define B3000000 0x00001011 #define B3500000 0x00001012 #define B4000000 0x00001013 */ -#define TARGET_CIBAUD 0x100f0000 /* input baud rate (not used) */ +#define TARGET_CIBAUD 0x100f0000 /* input baud rate */ #define TARGET_CMSPAR 0x40000000 /* mark or space (stick) parity */ #define TARGET_CRTSCTS 0x80000000 /* flow control */ +#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define TARGET_ISIG 0x00000001 #define TARGET_ICANON 0x00000002 @@ -251,6 +276,12 @@ #define TARGET_TIOCGPGRP TARGET_IOR('t', 131, int) #define TARGET_TIOCSCTTY TARGET_IO('t', 132) #define TARGET_TIOCGSID TARGET_IOR('t', 133, int) +#define TARGET_TCGETS2 TARGET_IOR('T', 12, struct target_termios2) +#define TARGET_TCSETS2 TARGET_IOW('T', 13, struct target_termios2) +#define TARGET_TCSETSW2 TARGET_IOW('T', 14, struct target_termios2) +#define TARGET_TCSETSF2 TARGET_IOW('T', 15, struct target_termios2) +#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x41, struct serial_rs485) +#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x42, struct serial_rs485) /* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */ #define TARGET_TIOCGPTN TARGET_IOR('t', 134, unsigned int) /* Get Pty Number */ #define TARGET_TIOCSPTLCK TARGET_IOW('t', 135, int) /* Lock/unlock PTY */ diff -Nru qemu-10.0.7+ds/linux-user/strace.c qemu-10.0.8+ds/linux-user/strace.c --- qemu-10.0.7+ds/linux-user/strace.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/strace.c 2026-02-12 20:30:14.000000000 +0000 @@ -1929,6 +1929,75 @@ qemu_log("}"); } +#ifdef TARGET_TCGETS2 +void +print_termios2(void *arg) +{ + const struct target_termios2 *target = arg; + + target_tcflag_t iflags = tswap32(target->c_iflag); + target_tcflag_t oflags = tswap32(target->c_oflag); + target_tcflag_t cflags = tswap32(target->c_cflag); + target_tcflag_t lflags = tswap32(target->c_lflag); + + qemu_log("{"); + + qemu_log("c_iflag = "); + print_flags(termios_iflags, iflags, 0); + + qemu_log("c_oflag = "); + target_tcflag_t oflags_clean = oflags & ~(TARGET_NLDLY | TARGET_CRDLY | + TARGET_TABDLY | TARGET_BSDLY | + TARGET_VTDLY | TARGET_FFDLY); + print_flags(termios_oflags, oflags_clean, 0); + if (oflags & TARGET_NLDLY) { + print_enums(termios_oflags_NLDLY, oflags & TARGET_NLDLY, 0); + } + if (oflags & TARGET_CRDLY) { + print_enums(termios_oflags_CRDLY, oflags & TARGET_CRDLY, 0); + } + if (oflags & TARGET_TABDLY) { + print_enums(termios_oflags_TABDLY, oflags & TARGET_TABDLY, 0); + } + if (oflags & TARGET_BSDLY) { + print_enums(termios_oflags_BSDLY, oflags & TARGET_BSDLY, 0); + } + if (oflags & TARGET_VTDLY) { + print_enums(termios_oflags_VTDLY, oflags & TARGET_VTDLY, 0); + } + if (oflags & TARGET_FFDLY) { + print_enums(termios_oflags_FFDLY, oflags & TARGET_FFDLY, 0); + } + + qemu_log("c_cflag = "); + if (cflags & TARGET_CBAUD) { + print_enums(termios_cflags_CBAUD, cflags & TARGET_CBAUD, 0); + } + if (cflags & TARGET_CSIZE) { + print_enums(termios_cflags_CSIZE, cflags & TARGET_CSIZE, 0); + } + target_tcflag_t cflags_clean = cflags & ~(TARGET_CBAUD | TARGET_CSIZE); + print_flags(termios_cflags, cflags_clean, 0); + + qemu_log("c_lflag = "); + print_flags(termios_lflags, lflags, 0); + + qemu_log("c_ispeed = "); + print_raw_param("%u", tswap32(target->c_ispeed), 0); + + qemu_log("c_ospeed = "); + print_raw_param("%u", tswap32(target->c_ospeed), 0); + + qemu_log("c_cc = "); + qemu_log("\"%s\",", target->c_cc); + + qemu_log("c_line = "); + print_raw_param("\'%c\'", target->c_line, 1); + + qemu_log("}"); +} +#endif + #undef UNUSED #ifdef TARGET_NR_accept diff -Nru qemu-10.0.7+ds/linux-user/syscall.c qemu-10.0.8+ds/linux-user/syscall.c --- qemu-10.0.7+ds/linux-user/syscall.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/syscall.c 2026-02-12 20:30:14.000000000 +0000 @@ -87,6 +87,7 @@ #endif #define termios host_termios +#define termios2 host_termios2 #define winsize host_winsize #define termio host_termio #define sgttyb host_sgttyb /* same as target */ @@ -148,6 +149,21 @@ #include "fd-trans.h" #include "user/cpu_loop.h" +#if defined(__powerpc__) +/* + * On PowerPC termios2 is lacking and termios along with ioctls w/o 2 + * behaves like termios2 and things with 2 on other architectures. + * + * Just define termios2-related things to be the same with termios-related + * ones to support PowerPC. + */ +#define host_termios2 host_termios +#define TCGETS2 TCGETS +#define TCSETS2 TCSETS +#define TCSETSW2 TCSETSW +#define TCSETSF2 TCSETSF +#endif + #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ #endif @@ -5759,27 +5775,70 @@ { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 }, }; +#if defined(TARGET_CIBAUD) && defined(CIBAUD) + +# define BAUD_TRANSTBL(baud) \ + { TARGET_CBAUD, TARGET_##baud, CBAUD, baud }, \ + { TARGET_CIBAUD, TARGET_##baud << TARGET_IBSHIFT, CIBAUD, baud << IBSHIFT }, + +#else + +/* Alpha in particular does not have CIBAUD/IBSHIFT */ + +# define BAUD_TRANSTBL(baud) \ + { TARGET_CBAUD, TARGET_##baud, CBAUD, baud }, + +#endif + static const bitmask_transtbl cflag_tbl[] = { - { TARGET_CBAUD, TARGET_B0, CBAUD, B0 }, - { TARGET_CBAUD, TARGET_B50, CBAUD, B50 }, - { TARGET_CBAUD, TARGET_B75, CBAUD, B75 }, - { TARGET_CBAUD, TARGET_B110, CBAUD, B110 }, - { TARGET_CBAUD, TARGET_B134, CBAUD, B134 }, - { TARGET_CBAUD, TARGET_B150, CBAUD, B150 }, - { TARGET_CBAUD, TARGET_B200, CBAUD, B200 }, - { TARGET_CBAUD, TARGET_B300, CBAUD, B300 }, - { TARGET_CBAUD, TARGET_B600, CBAUD, B600 }, - { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 }, - { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 }, - { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 }, - { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 }, - { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 }, - { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 }, - { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 }, - { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 }, - { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 }, - { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 }, - { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 }, + BAUD_TRANSTBL(B0) + BAUD_TRANSTBL(B50) + BAUD_TRANSTBL(B75) + BAUD_TRANSTBL(B110) + BAUD_TRANSTBL(B134) + BAUD_TRANSTBL(B150) + BAUD_TRANSTBL(B200) + BAUD_TRANSTBL(B300) + BAUD_TRANSTBL(B600) + BAUD_TRANSTBL(B1200) + BAUD_TRANSTBL(B1800) + BAUD_TRANSTBL(B2400) + BAUD_TRANSTBL(B4800) + BAUD_TRANSTBL(B9600) + BAUD_TRANSTBL(B19200) + BAUD_TRANSTBL(B38400) + BAUD_TRANSTBL(B57600) + BAUD_TRANSTBL(B115200) + BAUD_TRANSTBL(B230400) + BAUD_TRANSTBL(B460800) + BAUD_TRANSTBL(B500000) + BAUD_TRANSTBL(B576000) + BAUD_TRANSTBL(B921600) + BAUD_TRANSTBL(B1000000) + BAUD_TRANSTBL(B1152000) + BAUD_TRANSTBL(B1500000) + BAUD_TRANSTBL(B2000000) + + BAUD_TRANSTBL(BOTHER) + + /* SPARC in particular is missing these higher baud rates */ + +#if defined(TARGET_B2500000) && defined(B2500000) + BAUD_TRANSTBL(B2500000) +#endif + +#if defined(TARGET_B3000000) && defined(B3000000) + BAUD_TRANSTBL(B3000000) +#endif + +#if defined(TARGET_B3500000) && defined(B3500000) + BAUD_TRANSTBL(B3500000) +#endif + +#if defined(TARGET_B4000000) && defined(B4000000) + BAUD_TRANSTBL(B4000000) +#endif + { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, @@ -5889,6 +5948,89 @@ .print = print_termios, }; +#ifdef TARGET_TCGETS2 +static void target_to_host_termios2 (void *dst, const void *src) +{ + struct host_termios2 *host = dst; + const struct target_termios2 *target = src; + + host->c_iflag = + target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); + host->c_oflag = + target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); + host->c_cflag = + target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); + host->c_lflag = + target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); + host->c_line = target->c_line; + host->c_ispeed = tswap32(target->c_ispeed); + host->c_ospeed = tswap32(target->c_ospeed); + + memset(host->c_cc, 0, sizeof(host->c_cc)); + host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; + host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; + host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; + host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; + host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; + host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; + host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; + host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; + host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; + host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; + host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; + host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; + host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; + host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; + host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; + host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; + host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; +} + +static void host_to_target_termios2 (void *dst, const void *src) +{ + struct target_termios2 *target = dst; + const struct host_termios2 *host = src; + + target->c_iflag = + tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); + target->c_oflag = + tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); + target->c_cflag = + tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); + target->c_lflag = + tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); + target->c_line = host->c_line; + target->c_ispeed = tswap32(host->c_ispeed); + target->c_ospeed = tswap32(host->c_ospeed); + + memset(target->c_cc, 0, sizeof(target->c_cc)); + target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; + target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; + target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; + target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; + target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; + target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; + target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; + target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC]; + target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; + target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; + target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; + target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; + target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; + target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; + target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; + target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; + target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; +} + +static const StructEntry struct_termios2_def = { + .convert = { host_to_target_termios2, target_to_host_termios2 }, + .size = { sizeof(struct target_termios2), sizeof(struct host_termios2) }, + .align = { __alignof__(struct target_termios2), __alignof__(struct host_termios2) }, + .print = print_termios2, +}; +#endif + /* If the host does not provide these bits, they may be safely discarded. */ #ifndef MAP_SYNC #define MAP_SYNC 0 @@ -6593,6 +6735,20 @@ return NULL; } +void clone_fork_start(void) +{ + pthread_mutex_lock(&clone_lock); +} + +void clone_fork_end(bool child) +{ + if (child) { + pthread_mutex_init(&clone_lock, NULL); + } else { + pthread_mutex_unlock(&clone_lock); + } +} + /* do_fork() Must return host values and target errnos (unlike most do_*() functions). */ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, @@ -11908,9 +12064,13 @@ int dirfd = arg1; int flags = arg3; - p = lock_user_string(arg2); - if (p == NULL) { - return -TARGET_EFAULT; + p = NULL; + /* Since Linux 6.11, the path argument may be NULL */ + if (arg2 != 0) { + p = lock_user_string(arg2); + if (p == NULL) { + return -TARGET_EFAULT; + } } #if defined(__NR_statx) { diff -Nru qemu-10.0.7+ds/linux-user/syscall_types.h qemu-10.0.8+ds/linux-user/syscall_types.h --- qemu-10.0.7+ds/linux-user/syscall_types.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/syscall_types.h 2026-02-12 20:30:14.000000000 +0000 @@ -1,4 +1,7 @@ STRUCT_SPECIAL(termios) +#ifdef TARGET_TCGETS2 +STRUCT_SPECIAL(termios2) +#endif STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) diff -Nru qemu-10.0.7+ds/linux-user/user-internals.h qemu-10.0.8+ds/linux-user/user-internals.h --- qemu-10.0.7+ds/linux-user/user-internals.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/linux-user/user-internals.h 2026-02-12 20:30:14.000000000 +0000 @@ -68,6 +68,8 @@ const char *target_strerror(int err); int get_osversion(void); void init_qemu_uname_release(void); +void clone_fork_start(void); +void clone_fork_end(bool child); void fork_start(void); void fork_end(pid_t pid); @@ -128,6 +130,9 @@ #endif /* TARGET_ABI_BITS != 32 */ void print_termios(void *arg); +#ifdef TARGET_TCGETS2 +void print_termios2(void *arg); +#endif /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */ #ifdef TARGET_ARM diff -Nru qemu-10.0.7+ds/monitor/hmp.c qemu-10.0.8+ds/monitor/hmp.c --- qemu-10.0.7+ds/monitor/hmp.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/monitor/hmp.c 2026-02-12 20:30:14.000000000 +0000 @@ -577,10 +577,11 @@ * Read key of 'type' into 'key' and return the current * 'type' pointer. */ -static char *key_get_info(const char *type, char **key) +static const char *key_get_info(const char *type, char **key) { size_t len; - char *p, *str; + const char *p; + char *str; if (*type == ',') { type++; diff -Nru qemu-10.0.7+ds/monitor/qmp.c qemu-10.0.8+ds/monitor/qmp.c --- qemu-10.0.7+ds/monitor/qmp.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/monitor/qmp.c 2026-02-12 20:30:14.000000000 +0000 @@ -537,6 +537,11 @@ */ remove_fd_in_watch(chr); /* + * Clean up listener IO sources early to prevent racy fd + * handling between the main thread and the I/O thread. + */ + remove_listener_fd_in_watch(chr); + /* * We can't call qemu_chr_fe_set_handlers() directly here * since chardev might be running in the monitor I/O * thread. Schedule a bottom half. diff -Nru qemu-10.0.7+ds/pc-bios/optionrom/Makefile qemu-10.0.8+ds/pc-bios/optionrom/Makefile --- qemu-10.0.7+ds/pc-bios/optionrom/Makefile 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/pc-bios/optionrom/Makefile 2026-02-12 20:30:14.000000000 +0000 @@ -36,7 +36,7 @@ $(call cc-option,-Wno-array-bounds)) 3> config-cc.mak -include config-cc.mak -override LDFLAGS = -nostdlib -Wl,--build-id=none,-T,$(SRC_DIR)/flat.lds +override LDFLAGS = -nostdlib -Wl,--build-id=none,-T,$(SRC_DIR)/flat.lds,-m,elf_i386 pvh.img: pvh.o pvh_main.o diff -Nru qemu-10.0.7+ds/python/scripts/mkvenv.py qemu-10.0.8+ds/python/scripts/mkvenv.py --- qemu-10.0.7+ds/python/scripts/mkvenv.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/python/scripts/mkvenv.py 2026-02-12 20:30:14.000000000 +0000 @@ -675,7 +675,7 @@ if not online: full_args += ["--no-index"] if wheels_dir: - full_args += ["--find-links", f"file://{str(wheels_dir)}"] + full_args += ["--find-links", str(wheels_dir)] full_args += list(args) subprocess.run( full_args, diff -Nru qemu-10.0.7+ds/qga/commands-linux.c qemu-10.0.8+ds/qga/commands-linux.c --- qemu-10.0.7+ds/qga/commands-linux.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/qga/commands-linux.c 2026-02-12 20:30:14.000000000 +0000 @@ -400,10 +400,11 @@ Error **errp) { unsigned int pci[4], host, hosts[8], tgt[3]; - int i, nhosts = 0, pcilen; + int i, offset, nhosts = 0, pcilen; GuestPCIAddress *pciaddr = disk->pci_controller; bool has_ata = false, has_host = false, has_tgt = false; - char *p, *q, *driver = NULL; + const char *p; + char *driver = NULL; bool ret = false; p = strstr(syspath, "/devices/pci"); @@ -445,13 +446,13 @@ p = strstr(syspath, "/ata"); if (p) { - q = p + 4; + offset = 4; has_ata = true; } else { p = strstr(syspath, "/host"); - q = p + 5; + offset = 5; } - if (p && sscanf(q, "%u", &host) == 1) { + if (p && sscanf(p + offset, "%u", &host) == 1) { has_host = true; nhosts = build_hosts(syspath, p, has_ata, hosts, ARRAY_SIZE(hosts), errp); @@ -543,7 +544,7 @@ Error **errp) { unsigned int tgt[3]; - char *p; + const char *p; if (!strstr(syspath, "/virtio") || !strstr(syspath, "/block")) { g_debug("Unsupported virtio device '%s'", syspath); @@ -575,7 +576,7 @@ Error **errp) { unsigned int cssid, ssid, subchno, devno; - char *p; + const char *p; p = strstr(syspath, "/devices/css"); if (!p || sscanf(p + 12, "%*x/%x.%x.%x/%*x.%*x.%x/", diff -Nru qemu-10.0.7+ds/scripts/nsis.py qemu-10.0.8+ds/scripts/nsis.py --- qemu-10.0.7+ds/scripts/nsis.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/scripts/nsis.py 2026-02-12 20:30:14.000000000 +0000 @@ -114,7 +114,7 @@ "-DSRCDIR=" + args.srcdir, "-DBINDIR=" + destdir + prefix, ] - if args.cpu == "x86_64": + if args.cpu == "aarch64" or args.cpu == "x86_64": makensis += ["-DW64"] makensis += ["-DDLLDIR=" + dlldir] diff -Nru qemu-10.0.7+ds/scripts/qemugdb/timers.py qemu-10.0.8+ds/scripts/qemugdb/timers.py --- qemu-10.0.7+ds/scripts/qemugdb/timers.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/scripts/qemugdb/timers.py 2026-02-12 20:30:14.000000000 +0000 @@ -37,10 +37,9 @@ def process_timerlist(self, tlist, ttype): gdb.write("Processing %s timers\n" % (ttype)) - gdb.write(" clock %s is enabled:%s, last:%s\n" % ( + gdb.write(" clock %s is enabled:%s\n" % ( tlist['clock']['type'], - tlist['clock']['enabled'], - tlist['clock']['last'])) + tlist['clock']['enabled'])) if int(tlist['active_timers']) > 0: self.dump_timers(tlist['active_timers']) diff -Nru qemu-10.0.7+ds/target/arm/helper.c qemu-10.0.8+ds/target/arm/helper.c --- qemu-10.0.7+ds/target/arm/helper.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/arm/helper.c 2026-02-12 20:30:14.000000000 +0000 @@ -1863,8 +1863,8 @@ return ret; } -static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) +static CPAccessResult access_tid1(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) { if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) { return CP_ACCESS_TRAP_EL2; @@ -1873,16 +1873,6 @@ return CP_ACCESS_OK; } -static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) -{ - if (arm_feature(env, ARM_FEATURE_V8)) { - return access_aa64_tid1(env, ri, isread); - } - - return CP_ACCESS_OK; -} - static const ARMCPRegInfo v7_cp_reginfo[] = { /* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */ { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4, @@ -2068,7 +2058,7 @@ { .name = "AIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid1, + .accessfn = access_tid1, .fgt = FGT_AIDR_EL1, .resetvalue = 0 }, /* @@ -6740,7 +6730,7 @@ .writefn = smcr_write, .raw_writefn = raw_write }, { .name = "SMIDR_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 6, - .access = PL1_R, .accessfn = access_aa64_tid1, + .access = PL1_R, .accessfn = access_tid1, /* * IMPLEMENTOR = 0 (software) * REVISION = 0 (implementation defined) @@ -7599,9 +7589,18 @@ .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW }, }; -static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) +static CPAccessResult access_v7a_tid3(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) { + /* + * Trap on TID3 always. This should be used only for the fixed set of + * registers which are defined to trap on HCR.TID3 in v7A, which is: + * ID_PFR{0,1}, ID_DFR0, ID_AFR0, ID_MMFR{0,1,2,3}, ID_ISAR{0,1,2,3,4,5} + * (MVFR0 and MVFR1 also trap in v7A, but this is not handled via + * this accessfn but in check_hcr_el2_trap.) + * Any other registers in the TID3 trap space should use access_tid3(), + * so that they trap on v8 and above, but not on v7. + */ if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID3)) { return CP_ACCESS_TRAP_EL2; } @@ -7609,11 +7608,18 @@ return CP_ACCESS_OK; } -static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri, - bool isread) +static CPAccessResult access_tid3(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) { + /* + * Trap on TID3, if we implement at least v8. For v8 and above + * the ID register space is at least IMPDEF permitted to trap, + * and must trap if FEAT_FGT is implemented. We choose to trap + * always. Use this function for any new registers that should + * trap on TID3. + */ if (arm_feature(env, ARM_FEATURE_V8)) { - return access_aa64_tid3(env, ri, isread); + return access_v7a_tid3(env, ri, isread); } return CP_ACCESS_OK; @@ -7803,7 +7809,7 @@ { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_pfr0 }, /* * ID_PFR1 is not a plain ARM_CP_CONST because we don't know @@ -7812,13 +7818,12 @@ { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1, .access = PL1_R, .type = ARM_CP_NO_RAW, - .accessfn = access_aa32_tid3, #ifdef CONFIG_USER_ONLY .type = ARM_CP_CONST, .resetvalue = cpu->isar.id_pfr1, #else .type = ARM_CP_NO_RAW, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .readfn = id_pfr1_read, .writefn = arm_cp_write_ignore #endif @@ -7826,72 +7831,72 @@ { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_dfr0 }, { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->id_afr0 }, { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_mmfr0 }, { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_mmfr1 }, { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_mmfr2 }, { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_mmfr3 }, { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar0 }, { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar1 }, { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar2 }, { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar3 }, { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar4 }, { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_v7a_tid3, .resetvalue = cpu->isar.id_isar5 }, { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_mmfr4 }, { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_isar6 }, }; define_arm_cp_regs(cpu, v6_idregs); @@ -7946,7 +7951,7 @@ .resetvalue = cpu->isar.id_aa64pfr0 #else .type = ARM_CP_NO_RAW, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .readfn = id_aa64pfr0_read, .writefn = arm_cp_write_ignore #endif @@ -7954,172 +7959,172 @@ { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64pfr1}, { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64zfr0 }, { .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64smfr0 }, { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64dfr0 }, { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64dfr1 }, { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->id_aa64afr0 }, { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->id_aa64afr1 }, { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64isar0 }, { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64isar1 }, { .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64isar2 }, { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64mmfr0 }, { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64mmfr1 }, { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64mmfr2 }, { .name = "ID_AA64MMFR3_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_aa64mmfr3 }, { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.mvfr0 }, { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.mvfr1 }, { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.mvfr2 }, /* * "0, c0, c3, {0,1,2}" are the encodings corresponding to @@ -8130,17 +8135,17 @@ { .name = "RES_0_C0_C3_0", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "RES_0_C0_C3_1", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "RES_0_C0_C3_2", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, /* * Other encodings in "0, c0, c3, ..." are STATE_BOTH because @@ -8151,27 +8156,27 @@ { .name = "RES_0_C0_C3_3", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_pfr2 }, { .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_dfr1 }, { .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = cpu->isar.id_mmfr5 }, { .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }, { .name = "PMCEID0", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6, @@ -8346,7 +8351,7 @@ .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 0, .crn = 0, .crm = i, .opc2 = CP_ANY, .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, + .accessfn = access_tid3, .resetvalue = 0 }; define_one_arm_cp_reg(cpu, &v8_aa32_raz_idregs); } @@ -8633,7 +8638,7 @@ { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6, .access = PL1_R, - .accessfn = access_aa64_tid1, + .accessfn = access_tid1, .fgt = FGT_REVIDR_EL1, .type = ARM_CP_CONST, .resetvalue = cpu->revidr }, }; @@ -8657,7 +8662,7 @@ { .name = "TCMTR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2, .access = PL1_R, - .accessfn = access_aa32_tid1, + .accessfn = access_tid1, .type = ARM_CP_CONST, .resetvalue = 0 }, }; /* TLBTR is specific to VMSA */ @@ -8665,7 +8670,7 @@ .name = "TLBTR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3, .access = PL1_R, - .accessfn = access_aa32_tid1, + .accessfn = access_tid1, .type = ARM_CP_CONST, .resetvalue = 0, }; /* MPUIR is specific to PMSA V6+ */ diff -Nru qemu-10.0.7+ds/target/arm/tcg/tlb_helper.c qemu-10.0.8+ds/target/arm/tcg/tlb_helper.c --- qemu-10.0.7+ds/target/arm/tcg/tlb_helper.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/arm/tcg/tlb_helper.c 2026-02-12 20:30:14.000000000 +0000 @@ -243,7 +243,11 @@ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc); if (access_type == MMU_INST_FETCH) { - syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc); + if (fi->type == ARMFault_Alignment) { + syn = syn_pcalignment(); + } else { + syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc); + } exc = EXCP_PREFETCH_ABORT; } else { syn = merge_syn_data_abort(env->exception.syndrome, fi, target_el, @@ -338,11 +342,18 @@ } /* - * Per R_XCHFJ, alignment fault not due to memory type has - * highest precedence. Otherwise, walk the page table and - * and collect the page description. + * PC alignment faults should be dealt with at translation time + * but we also need to catch them while being probed. + * + * Then per R_XCHFJ, alignment fault not due to memory type take + * precedence. Otherwise, walk the page table and and collect the + * page description. + * */ - if (address & ((1 << memop_alignment_bits(memop)) - 1)) { + if (access_type == MMU_INST_FETCH && !cpu->env.thumb && + (address & 3)) { + fi->type = ARMFault_Alignment; + } else if (address & ((1 << memop_alignment_bits(memop)) - 1)) { fi->type = ARMFault_Alignment; } else if (!get_phys_addr(&cpu->env, address, access_type, memop, core_to_arm_mmu_idx(&cpu->env, mmu_idx), diff -Nru qemu-10.0.7+ds/target/i386/ops_sse.h qemu-10.0.8+ds/target/i386/ops_sse.h --- qemu-10.0.7+ds/target/i386/ops_sse.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/ops_sse.h 2026-02-12 20:30:14.000000000 +0000 @@ -2362,42 +2362,42 @@ } void glue(helper_vpgatherdd, SUFFIX)(CPUX86State *env, - Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale) + Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale, target_ulong amask) { int i; for (i = 0; i < (2 << SHIFT); i++) { if (v->L(i) >> 31) { target_ulong addr = a0 + ((target_ulong)(int32_t)s->L(i) << scale); - d->L(i) = cpu_ldl_data_ra(env, addr, GETPC()); + d->L(i) = cpu_ldl_data_ra(env, addr & amask, GETPC()); } v->L(i) = 0; } } void glue(helper_vpgatherdq, SUFFIX)(CPUX86State *env, - Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale) + Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale, target_ulong amask) { int i; for (i = 0; i < (1 << SHIFT); i++) { if (v->Q(i) >> 63) { target_ulong addr = a0 + ((target_ulong)(int32_t)s->L(i) << scale); - d->Q(i) = cpu_ldq_data_ra(env, addr, GETPC()); + d->Q(i) = cpu_ldq_data_ra(env, addr & amask, GETPC()); } v->Q(i) = 0; } } void glue(helper_vpgatherqd, SUFFIX)(CPUX86State *env, - Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale) + Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale, target_ulong amask) { int i; for (i = 0; i < (1 << SHIFT); i++) { if (v->L(i) >> 31) { target_ulong addr = a0 + ((target_ulong)(int64_t)s->Q(i) << scale); - d->L(i) = cpu_ldl_data_ra(env, addr, GETPC()); + d->L(i) = cpu_ldl_data_ra(env, addr & amask, GETPC()); } v->L(i) = 0; } @@ -2408,14 +2408,14 @@ } void glue(helper_vpgatherqq, SUFFIX)(CPUX86State *env, - Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale) + Reg *d, Reg *v, Reg *s, target_ulong a0, unsigned scale, target_ulong amask) { int i; for (i = 0; i < (1 << SHIFT); i++) { if (v->Q(i) >> 63) { target_ulong addr = a0 + ((target_ulong)(int64_t)s->Q(i) << scale); - d->Q(i) = cpu_ldq_data_ra(env, addr, GETPC()); + d->Q(i) = cpu_ldq_data_ra(env, addr & amask, GETPC()); } v->Q(i) = 0; } diff -Nru qemu-10.0.7+ds/target/i386/tcg/decode-new.c.inc qemu-10.0.8+ds/target/i386/tcg/decode-new.c.inc --- qemu-10.0.7+ds/target/i386/tcg/decode-new.c.inc 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/tcg/decode-new.c.inc 2026-02-12 20:30:14.000000000 +0000 @@ -504,7 +504,7 @@ static const X86OpEntry opcodes_0F7E[4] = { X86_OP_ENTRY3(MOVD_from, E,y, None,None, P,y, vex5 mmx), X86_OP_ENTRY3(MOVD_from, E,y, None,None, V,y, vex5), - X86_OP_ENTRY3(MOVQ, V,x, None,None, W,q, vex5), /* wrong dest Vy on SDM! */ + X86_OP_ENTRY3(MOVQ, V,dq,None,None, W,q, vex5), /* wrong dest Vq on SDM! */ {}, }; *entry = *decode_by_prefix(s, opcodes_0F7E); @@ -569,7 +569,7 @@ { static const X86OpEntry movq[4] = { {}, - X86_OP_ENTRY3(MOVQ, W,x, None, None, V,q, vex5), + X86_OP_ENTRY3(MOVQ, W,dq, None, None, V,q, vex5), X86_OP_ENTRY3(MOVq_dq, V,dq, None, None, N,q), X86_OP_ENTRY3(MOVq_dq, P,q, None, None, U,q), }; @@ -944,15 +944,15 @@ static void decode_0F11(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) { static const X86OpEntry opcodes_0F11_reg[4] = { - X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPS */ - X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPD */ + X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4_unal), /* MOVUPS */ + X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4_unal), /* MOVUPD */ X86_OP_ENTRY3(VMOVSS, W,x, H,x, V,x, vex5), X86_OP_ENTRY3(VMOVLPx, W,x, H,x, V,q, vex5), /* MOVSD */ }; static const X86OpEntry opcodes_0F11_mem[4] = { - X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPS */ - X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4), /* MOVUPD */ + X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4_unal), /* MOVUPS */ + X86_OP_ENTRY3(MOVDQ, W,x, None,None, V,x, vex4_unal), /* MOVUPD */ X86_OP_ENTRY3(VMOVSS_st, M,ss, None,None, V,x, vex5), X86_OP_ENTRY3(VMOVLPx_st, M,sd, None,None, V,x, vex5), /* MOVSD */ }; @@ -978,7 +978,7 @@ }; static const X86OpEntry opcodes_0F12_reg[4] = { X86_OP_ENTRY3(VMOVHLPS, V,dq, H,dq, U,dq, vex7), - X86_OP_ENTRY3(VMOVLPx, W,x, H,x, U,q, vex5), /* MOVLPD */ + X86_OP_ENTRY3(VMOVLPx, W,dq, H,dq, U,q, vex5), /* MOVLPD */ X86_OP_ENTRY3(VMOVSLDUP, V,x, None,None, U,x, vex4 cpuid(SSE3)), X86_OP_ENTRY3(VMOVDDUP, V,x, None,None, U,x, vex5 cpuid(SSE3)), }; @@ -1341,7 +1341,7 @@ [0x6b] = X86_OP_ENTRY3(PACKSSDW, V,x, H,x, W,x, vex4 mmx avx2_256 p_00_66), [0x6c] = X86_OP_ENTRY3(PUNPCKLQDQ, V,x, H,x, W,x, vex4 p_66 avx2_256), [0x6d] = X86_OP_ENTRY3(PUNPCKHQDQ, V,x, H,x, W,x, vex4 p_66 avx2_256), - [0x6e] = X86_OP_ENTRY3(MOVD_to, V,x, None,None, E,y, vex5 mmx p_00_66), /* wrong dest Vy on SDM! */ + [0x6e] = X86_OP_ENTRY3(MOVD_to, V,dq,None,None, E,y, vex5 mmx p_00_66), /* wrong dest Vy on SDM! */ [0x6f] = X86_OP_GROUP0(0F6F), [0x78] = X86_OP_GROUP0(0F78), @@ -2382,6 +2382,9 @@ X86OpEntry *e = &decode->e; switch (e->vex_special) { + case X86_VEX_None: + break; + case X86_VEX_REPScalar: /* * Instructions which differ between 00/66 and F2/F3 in the @@ -2605,20 +2608,16 @@ case 0xc5: /* 2-byte VEX */ case 0xc4: /* 3-byte VEX */ /* - * VEX prefixes cannot be used except in 32-bit mode. - * Otherwise the instruction is LES or LDS. + * Bits 6-7 of the first byte must be set except in 64-bit mode. + * Otherwise the instruction is LES or LDS. Not allowed in real mode. */ - if (CODE32(s) && !VM86(s)) { + if (PE(s) && !VM86(s)) { static const int pp_prefix[4] = { 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ }; int vex3, vex2 = x86_ldub_code(env, s); if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { - /* - * 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, - * otherwise the instruction is LES or LDS. - */ s->pc--; /* rewind the advance_pc() x86_ldub_code() did */ break; } @@ -2657,7 +2656,7 @@ goto unknown_op; } } - s->vex_v = (~vex3 >> 3) & 0xf; + s->vex_v = (~vex3 >> 3) & (CODE64(s) ? 15 : 7); s->vex_l = (vex3 >> 2) & 1; s->prefix |= pp_prefix[vex3 & 3] | PREFIX_VEX; } diff -Nru qemu-10.0.7+ds/target/i386/tcg/decode-new.h qemu-10.0.8+ds/target/i386/tcg/decode-new.h --- qemu-10.0.7+ds/target/i386/tcg/decode-new.h 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/tcg/decode-new.h 2026-02-12 20:30:14.000000000 +0000 @@ -242,6 +242,8 @@ * section of the manual. */ typedef enum X86VEXSpecial { + X86_VEX_None, + /* Legacy SSE instructions that allow unaligned operands */ X86_VEX_SSEUnaligned, diff -Nru qemu-10.0.7+ds/target/i386/tcg/emit.c.inc qemu-10.0.8+ds/target/i386/tcg/emit.c.inc --- qemu-10.0.7+ds/target/i386/tcg/emit.c.inc 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/tcg/emit.c.inc 2026-02-12 20:30:14.000000000 +0000 @@ -53,8 +53,8 @@ TCGv_i32 val); typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv val); -typedef void (*SSEFunc_0_epppti)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, - TCGv_ptr reg_c, TCGv a0, TCGv_i32 scale); +typedef void (*SSEFunc_0_eppptit)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, + TCGv_ptr reg_c, TCGv a0, TCGv_i32 scale, TCGv amask); typedef void (*SSEFunc_0_eppppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_ptr reg_c, TCGv_ptr reg_d, TCGv_i32 flags); typedef void (*SSEFunc_0_eppppii)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, @@ -1108,18 +1108,19 @@ /* Same as above, but with extra arguments to the helper. */ static inline void gen_vsib_avx(DisasContext *s, X86DecodedInsn *decode, - SSEFunc_0_epppti d_xmm, SSEFunc_0_epppti q_xmm, - SSEFunc_0_epppti d_ymm, SSEFunc_0_epppti q_ymm) + SSEFunc_0_eppptit d_xmm, SSEFunc_0_eppptit q_xmm, + SSEFunc_0_eppptit d_ymm, SSEFunc_0_eppptit q_ymm) { - SSEFunc_0_epppti d = s->vex_l ? d_ymm : d_xmm; - SSEFunc_0_epppti q = s->vex_l ? q_ymm : q_xmm; - SSEFunc_0_epppti fn = s->vex_w ? q : d; + SSEFunc_0_eppptit d = s->vex_l ? d_ymm : d_xmm; + SSEFunc_0_eppptit q = s->vex_l ? q_ymm : q_xmm; + SSEFunc_0_eppptit fn = s->vex_w ? q : d; TCGv_i32 scale = tcg_constant_i32(decode->mem.scale); TCGv_ptr index = tcg_temp_new_ptr(); + TCGv mask = tcg_constant_tl(MAKE_64BIT_MASK(0, 8 << s->aflag)); /* Pass third input as (index, base, scale) */ tcg_gen_addi_ptr(index, tcg_env, ZMM_OFFSET(decode->mem.index)); - fn(tcg_env, OP_PTR0, OP_PTR1, index, s->A0, scale); + fn(tcg_env, OP_PTR0, OP_PTR1, index, s->A0, scale, mask); /* * There are two output operands, so zero OP1's high 128 bits diff -Nru qemu-10.0.7+ds/target/i386/tcg/ops_sse_header.h.inc qemu-10.0.8+ds/target/i386/tcg/ops_sse_header.h.inc --- qemu-10.0.7+ds/target/i386/tcg/ops_sse_header.h.inc 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/tcg/ops_sse_header.h.inc 2026-02-12 20:30:14.000000000 +0000 @@ -388,10 +388,10 @@ DEF_HELPER_4(glue(vpmaskmovq_st, SUFFIX), void, env, Reg, Reg, tl) DEF_HELPER_4(glue(vpmaskmovd, SUFFIX), void, env, Reg, Reg, Reg) DEF_HELPER_4(glue(vpmaskmovq, SUFFIX), void, env, Reg, Reg, Reg) -DEF_HELPER_6(glue(vpgatherdd, SUFFIX), void, env, Reg, Reg, Reg, tl, i32) -DEF_HELPER_6(glue(vpgatherdq, SUFFIX), void, env, Reg, Reg, Reg, tl, i32) -DEF_HELPER_6(glue(vpgatherqd, SUFFIX), void, env, Reg, Reg, Reg, tl, i32) -DEF_HELPER_6(glue(vpgatherqq, SUFFIX), void, env, Reg, Reg, Reg, tl, i32) +DEF_HELPER_7(glue(vpgatherdd, SUFFIX), void, env, Reg, Reg, Reg, tl, i32, tl) +DEF_HELPER_7(glue(vpgatherdq, SUFFIX), void, env, Reg, Reg, Reg, tl, i32, tl) +DEF_HELPER_7(glue(vpgatherqd, SUFFIX), void, env, Reg, Reg, Reg, tl, i32, tl) +DEF_HELPER_7(glue(vpgatherqq, SUFFIX), void, env, Reg, Reg, Reg, tl, i32, tl) #if SHIFT == 2 DEF_HELPER_3(vpermd_ymm, void, Reg, Reg, Reg) DEF_HELPER_4(vpermdq_ymm, void, Reg, Reg, Reg, i32) diff -Nru qemu-10.0.7+ds/target/i386/tcg/user/seg_helper.c qemu-10.0.8+ds/target/i386/tcg/user/seg_helper.c --- qemu-10.0.7+ds/target/i386/tcg/user/seg_helper.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/i386/tcg/user/seg_helper.c 2026-02-12 20:30:14.000000000 +0000 @@ -64,7 +64,7 @@ cpl = env->hflags & HF_CPL_MASK; /* check privilege if software int */ if (dpl < cpl) { - raise_exception_err(env, EXCP0D_GPF, (intno << shift) + 2); + raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); } } diff -Nru qemu-10.0.7+ds/target/loongarch/cpu.c qemu-10.0.8+ds/target/loongarch/cpu.c --- qemu-10.0.7+ds/target/loongarch/cpu.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/loongarch/cpu.c 2026-02-12 20:30:14.000000000 +0000 @@ -201,6 +201,9 @@ cause = cs->exception_index; update_badinstr = 0; break; + case EXCCODE_BCE: + env->CSR_BADV = env->pc; + QEMU_FALLTHROUGH; case EXCCODE_SYS: case EXCCODE_BRK: case EXCCODE_INE: @@ -209,9 +212,6 @@ case EXCCODE_FPE: case EXCCODE_SXD: case EXCCODE_ASXD: - env->CSR_BADV = env->pc; - QEMU_FALLTHROUGH; - case EXCCODE_BCE: case EXCCODE_ADEM: case EXCCODE_PIL: case EXCCODE_PIS: @@ -311,6 +311,7 @@ { CPULoongArchState *env = cpu_env(cs); + env->CSR_BADV = addr; if (access_type == MMU_INST_FETCH) { do_raise_exception(env, EXCCODE_ADEF, retaddr); } else { diff -Nru qemu-10.0.7+ds/target/m68k/op_helper.c qemu-10.0.8+ds/target/m68k/op_helper.c --- qemu-10.0.7+ds/target/m68k/op_helper.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/target/m68k/op_helper.c 2026-02-12 20:30:14.000000000 +0000 @@ -778,8 +778,8 @@ env->cc_v = c2; } env->cc_op = CC_OP_CMPW; - env->dregs[Dc1] = deposit32(env->dregs[Dc1], 0, 16, l1); env->dregs[Dc2] = deposit32(env->dregs[Dc2], 0, 16, l2); + env->dregs[Dc1] = deposit32(env->dregs[Dc1], 0, 16, l1); } static void do_cas2l(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2, @@ -840,8 +840,8 @@ env->cc_v = c2; } env->cc_op = CC_OP_CMPL; - env->dregs[Dc1] = l1; env->dregs[Dc2] = l2; + env->dregs[Dc1] = l1; } void HELPER(cas2l)(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2) diff -Nru qemu-10.0.7+ds/tcg/riscv/tcg-target.c.inc qemu-10.0.8+ds/tcg/riscv/tcg-target.c.inc --- qemu-10.0.7+ds/tcg/riscv/tcg-target.c.inc 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tcg/riscv/tcg-target.c.inc 2026-02-12 20:30:14.000000000 +0000 @@ -1151,7 +1151,7 @@ } static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece, - TCGReg dst, TCGReg src) + TCGReg dst, TCGReg src) { set_vtype_len_sew(s, type, vece); tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, src); @@ -1159,29 +1159,34 @@ } static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece, - TCGReg dst, TCGReg base, intptr_t offset) + TCGReg dst, TCGReg base, intptr_t offset) { + /* Note set_vtype* may clobber TMP0, so do that first. */ + set_vtype_len_sew(s, type, vece); tcg_out_ld(s, TCG_TYPE_REG, TCG_REG_TMP0, base, offset); - return tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0); + tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, TCG_REG_TMP0); + return true; } static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece, - TCGReg dst, int64_t arg) + TCGReg dst, int64_t arg) { /* Arg is replicated by VECE; extract the highest element. */ arg >>= (-8 << vece) & 63; + /* Note set_vtype* may clobber TMP0, so do that first. */ + if (arg == 0 || arg == -1) { + set_vtype_len(s, type); + } else { + set_vtype_len_sew(s, type, vece); + } + if (arg >= -16 && arg < 16) { - if (arg == 0 || arg == -1) { - set_vtype_len(s, type); - } else { - set_vtype_len_sew(s, type, vece); - } tcg_out_opc_vi(s, OPC_VMV_V_I, dst, 0, arg); - return; + } else { + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, arg); + tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, TCG_REG_TMP0); } - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, arg); - tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0); } static const struct { diff -Nru qemu-10.0.7+ds/tcg/tcg-op-ldst.c qemu-10.0.8+ds/tcg/tcg-op-ldst.c --- qemu-10.0.7+ds/tcg/tcg-op-ldst.c 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tcg/tcg-op-ldst.c 2026-02-12 20:30:14.000000000 +0000 @@ -118,6 +118,30 @@ } } +static TCGTemp *tci_extend_addr(TCGTemp *addr) +{ +#ifdef CONFIG_TCG_INTERPRETER + /* + * 64-bit interpreter requires 64-bit addresses. + * Compare to the extension performed by tcg_out_{ld,st}_helper_args + * for native code generation. + */ + if (TCG_TARGET_REG_BITS == 64 && tcg_ctx->addr_type == TCG_TYPE_I32) { + TCGv_i64 temp = tcg_temp_ebb_new_i64(); + tcg_gen_extu_i32_i64(temp, temp_tcgv_i32(addr)); + return tcgv_i64_temp(temp); + } +#endif + return addr; +} + +static void maybe_free_addr(TCGTemp *addr, TCGTemp *copy) +{ + if (addr != copy) { + tcg_temp_free_internal(copy); + } +} + /* Only required for loads, where value might overlap addr. */ static TCGv_i64 plugin_maybe_preserve_addr(TCGTemp *addr) { @@ -217,6 +241,7 @@ MemOp orig_memop; MemOpIdx orig_oi, oi; TCGv_i64 copy_addr; + TCGTemp *addr_new; tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); orig_memop = memop = tcg_canonicalize_memop(memop, 0, 0); @@ -231,11 +256,13 @@ oi = make_memop_idx(memop, idx); } + addr_new = tci_extend_addr(addr); copy_addr = plugin_maybe_preserve_addr(addr); gen_ldst(INDEX_op_qemu_ld_i32, TCG_TYPE_I32, - tcgv_i32_temp(val), NULL, addr, oi); + tcgv_i32_temp(val), NULL, addr_new, oi); plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi, QEMU_PLUGIN_MEM_R); + maybe_free_addr(addr, addr_new); if ((orig_memop ^ memop) & MO_BSWAP) { switch (orig_memop & MO_SIZE) { @@ -267,6 +294,7 @@ TCGv_i32 swap = NULL; MemOpIdx orig_oi, oi; TCGOpcode opc; + TCGTemp *addr_new; tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); memop = tcg_canonicalize_memop(memop, 0, 1); @@ -294,8 +322,10 @@ } else { opc = INDEX_op_qemu_st_i32; } - gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi); + addr_new = tci_extend_addr(addr); + gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr_new, oi); plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W); + maybe_free_addr(addr, addr_new); if (swap) { tcg_temp_free_i32(swap); @@ -316,6 +346,7 @@ MemOp orig_memop; MemOpIdx orig_oi, oi; TCGv_i64 copy_addr; + TCGTemp *addr_new; if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_ld_i32_int(TCGV_LOW(val), addr, idx, memop); @@ -340,10 +371,12 @@ oi = make_memop_idx(memop, idx); } + addr_new = tci_extend_addr(addr); copy_addr = plugin_maybe_preserve_addr(addr); - gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, oi); + gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr_new, oi); plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi, QEMU_PLUGIN_MEM_R); + maybe_free_addr(addr, addr_new); if ((orig_memop ^ memop) & MO_BSWAP) { int flags = (orig_memop & MO_SIGN @@ -378,6 +411,7 @@ { TCGv_i64 swap = NULL; MemOpIdx orig_oi, oi; + TCGTemp *addr_new; if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_st_i32_int(TCGV_LOW(val), addr, idx, memop); @@ -408,8 +442,10 @@ oi = make_memop_idx(memop, idx); } - gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, oi); + addr_new = tci_extend_addr(addr); + gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr_new, oi); plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W); + maybe_free_addr(addr, addr_new); if (swap) { tcg_temp_free_i64(swap); @@ -520,6 +556,7 @@ { MemOpIdx orig_oi; TCGv_i64 ext_addr = NULL; + TCGTemp *addr_new; check_max_alignment(memop_alignment_bits(memop)); tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); @@ -547,8 +584,10 @@ hi = TCGV128_HIGH(val); } + addr_new = tci_extend_addr(addr); gen_ldst(INDEX_op_qemu_ld_i128, TCG_TYPE_I128, tcgv_i64_temp(lo), - tcgv_i64_temp(hi), addr, oi); + tcgv_i64_temp(hi), addr_new, oi); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_gen_bswap64_i64(lo, lo); @@ -576,8 +615,10 @@ y = TCGV128_LOW(val); } - gen_ldst_i64(INDEX_op_qemu_ld_i64, x, addr, + addr_new = tci_extend_addr(addr); + gen_ldst_i64(INDEX_op_qemu_ld_i64, x, addr_new, make_memop_idx(mop[0], idx)); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_gen_bswap64_i64(x, x); @@ -593,8 +634,10 @@ addr_p8 = tcgv_i64_temp(t); } - gen_ldst_i64(INDEX_op_qemu_ld_i64, y, addr_p8, + addr_new = tci_extend_addr(addr_p8); + gen_ldst_i64(INDEX_op_qemu_ld_i64, y, addr_new, make_memop_idx(mop[1], idx)); + maybe_free_addr(addr_p8, addr_new); tcg_temp_free_internal(addr_p8); if (need_bswap) { @@ -628,6 +671,7 @@ { MemOpIdx orig_oi; TCGv_i64 ext_addr = NULL; + TCGTemp *addr_new; check_max_alignment(memop_alignment_bits(memop)); tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST); @@ -658,8 +702,10 @@ hi = TCGV128_HIGH(val); } + addr_new = tci_extend_addr(addr); gen_ldst(INDEX_op_qemu_st_i128, TCG_TYPE_I128, - tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi); + tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr_new, oi); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_temp_free_i64(lo); @@ -686,8 +732,10 @@ x = b; } - gen_ldst_i64(INDEX_op_qemu_st_i64, x, addr, + addr_new = tci_extend_addr(addr); + gen_ldst_i64(INDEX_op_qemu_st_i64, x, addr_new, make_memop_idx(mop[0], idx)); + maybe_free_addr(addr, addr_new); if (tcg_ctx->addr_type == TCG_TYPE_I32) { TCGv_i32 t = tcg_temp_ebb_new_i32(); @@ -699,15 +747,17 @@ addr_p8 = tcgv_i64_temp(t); } + addr_new = tci_extend_addr(addr_p8); if (b) { tcg_gen_bswap64_i64(b, y); - gen_ldst_i64(INDEX_op_qemu_st_i64, b, addr_p8, + gen_ldst_i64(INDEX_op_qemu_st_i64, b, addr_new, make_memop_idx(mop[1], idx)); tcg_temp_free_i64(b); } else { - gen_ldst_i64(INDEX_op_qemu_st_i64, y, addr_p8, + gen_ldst_i64(INDEX_op_qemu_st_i64, y, addr_new, make_memop_idx(mop[1], idx)); } + maybe_free_addr(addr_p8, addr_new); tcg_temp_free_internal(addr_p8); } else { if (tcg_ctx->addr_type == TCG_TYPE_I32) { diff -Nru qemu-10.0.7+ds/tests/docker/dockerfiles/debian-all-test-cross.docker qemu-10.0.8+ds/tests/docker/dockerfiles/debian-all-test-cross.docker --- qemu-10.0.7+ds/tests/docker/dockerfiles/debian-all-test-cross.docker 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tests/docker/dockerfiles/debian-all-test-cross.docker 2026-02-12 20:30:14.000000000 +0000 @@ -15,7 +15,7 @@ apt-get update && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ - apt build-dep -yy qemu + apt build-dep -yy --arch-only qemu # Add extra build tools and as many cross compilers as we can for testing RUN DEBIAN_FRONTEND=noninteractive eatmydata \ @@ -23,7 +23,9 @@ bison \ ccache \ clang \ + dpkg-dev \ flex \ + gcc \ git \ libclang-rt-dev \ ninja-build \ @@ -33,16 +35,11 @@ python3-venv \ python3-wheel -RUN DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - gcc-aarch64-linux-gnu \ +# All the generally available compilers +ENV AVAILABLE_COMPILERS gcc-aarch64-linux-gnu \ libc6-dev-arm64-cross \ gcc-arm-linux-gnueabihf \ libc6-dev-armhf-cross \ - gcc-hppa-linux-gnu \ - libc6-dev-hppa-cross \ - gcc-m68k-linux-gnu \ - libc6-dev-m68k-cross \ gcc-mips-linux-gnu \ libc6-dev-mips-cross \ gcc-mips64-linux-gnuabi64 \ @@ -51,18 +48,23 @@ libc6-dev-mips64el-cross \ gcc-mipsel-linux-gnu \ libc6-dev-mipsel-cross \ - gcc-powerpc-linux-gnu \ - libc6-dev-powerpc-cross \ - gcc-powerpc64-linux-gnu \ - libc6-dev-ppc64-cross \ gcc-powerpc64le-linux-gnu \ libc6-dev-ppc64el-cross \ gcc-riscv64-linux-gnu \ libc6-dev-riscv64-cross \ gcc-s390x-linux-gnu \ - libc6-dev-s390x-cross \ - gcc-sparc64-linux-gnu \ - libc6-dev-sparc64-cross && \ + libc6-dev-s390x-cross + +RUN if dpkg-architecture -e amd64; then \ + export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-hppa-linux-gnu libc6-dev-hppa-cross"; \ + export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-m68k-linux-gnu libc6-dev-m68k-cross"; \ + export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc-linux-gnu libc6-dev-powerpc-cross"; \ + export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross"; \ + export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-sparc64-linux-gnu libc6-dev-sparc64-cross"; \ + fi && \ + DEBIAN_FRONTEND=noninteractive eatmydata \ + apt install -y --no-install-recommends \ + ${AVAILABLE_COMPILERS} && \ dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt diff -Nru qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref.py qemu-10.0.8+ds/tests/functional/test_aarch64_sbsaref.py --- qemu-10.0.7+ds/tests/functional/test_aarch64_sbsaref.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tests/functional/test_aarch64_sbsaref.py 2026-02-12 20:30:14.000000000 +0000 @@ -31,10 +31,10 @@ """ # Secure BootRom (TF-A code) - fs0_path = test.uncompress(Aarch64SbsarefMachine.ASSET_FLASH0) + fs0_path = test.uncompress(Aarch64SbsarefMachine.ASSET_FLASH0, format="xz") # Non-secure rom (UEFI and EFI variables) - fs1_path = test.uncompress(Aarch64SbsarefMachine.ASSET_FLASH1) + fs1_path = test.uncompress(Aarch64SbsarefMachine.ASSET_FLASH1, format="xz") for path in [fs0_path, fs1_path]: with open(path, "ab+") as fd: @@ -56,15 +56,13 @@ timeout = 180 - ASSET_FLASH0 = Asset( - ('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/' - '20241122-189881/edk2/SBSA_FLASH0.fd.xz'), - '76eb89d42eebe324e4395329f47447cda9ac920aabcf99aca85424609c3384a5') - - ASSET_FLASH1 = Asset( - ('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/' - '20241122-189881/edk2/SBSA_FLASH1.fd.xz'), - 'f850f243bd8dbd49c51e061e0f79f1697546938f454aeb59ab7d93e5f0d412fc') + # SBSA_FLASH0.fd.xz + ASSET_FLASH0 = Asset('https://share.linaro.org/downloadFile?id=kyoMLGC9zXa4oA7', + '76eb89d42eebe324e4395329f47447cda9ac920aabcf99aca85424609c3384a5') + + # SBSA_FLASH1.fd.xz + ASSET_FLASH1 = Asset('https://share.linaro.org/downloadFile?id=Dj1HRXnDnKtU6Nj', + 'f850f243bd8dbd49c51e061e0f79f1697546938f454aeb59ab7d93e5f0d412fc') def test_sbsaref_edk2_firmware(self): diff -Nru qemu-10.0.7+ds/tests/functional/test_arm_aspeed_rainier.py qemu-10.0.8+ds/tests/functional/test_arm_aspeed_rainier.py --- qemu-10.0.7+ds/tests/functional/test_arm_aspeed_rainier.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tests/functional/test_arm_aspeed_rainier.py 2026-02-12 20:30:14.000000000 +0000 @@ -9,10 +9,8 @@ class RainierMachine(AspeedTest): - ASSET_RAINIER_EMMC = Asset( - ('https://fileserver.linaro.org/s/B6pJTwWEkzSDi36/download/' - 'mmc-p10bmc-20240617.qcow2'), - 'd523fb478d2b84d5adc5658d08502bc64b1486955683814f89c6137518acd90b') + ASSET_RAINIER_EMMC = Asset('https://kaod.org/qemu/aspeed/rainier/mmc-p10bmc-20240617.qcow2', + 'd523fb478d2b84d5adc5658d08502bc64b1486955683814f89c6137518acd90b') def test_arm_aspeed_emmc_boot(self): self.set_machine('rainier-bmc') diff -Nru qemu-10.0.7+ds/tests/functional/test_mips64el_replay.py qemu-10.0.8+ds/tests/functional/test_mips64el_replay.py --- qemu-10.0.7+ds/tests/functional/test_mips64el_replay.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tests/functional/test_mips64el_replay.py 2026-02-12 20:30:14.000000000 +0000 @@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later from qemu_test import Asset, skipUntrustedTest +from qemu_test import skipFlakyTest from replay_kernel import ReplayKernelBase @@ -16,6 +17,7 @@ 'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb'), '35eb476f03be589824b0310358f1c447d85e645b88cbcd2ac02b97ef560f9f8d') + @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2013") def test_replay_mips64el_malta(self): self.set_machine('malta') kernel_path = self.archive_extract(self.ASSET_KERNEL_2_63_2, @@ -38,6 +40,7 @@ '75ba10cd35fb44e32948eeb26974f061b703c81c4ba2fab1ebcacf1d1bec3b61') @skipUntrustedTest() + @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2013") def test_replay_mips64el_malta_5KEc_cpio(self): self.set_machine('malta') self.cpu = '5KEc' diff -Nru qemu-10.0.7+ds/tests/functional/test_mips_replay.py qemu-10.0.8+ds/tests/functional/test_mips_replay.py --- qemu-10.0.7+ds/tests/functional/test_mips_replay.py 2025-12-06 14:54:24.000000000 +0000 +++ qemu-10.0.8+ds/tests/functional/test_mips_replay.py 2026-02-12 20:30:14.000000000 +0000 @@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later from qemu_test import Asset, skipSlowTest +from qemu_test import skipFlakyTest from replay_kernel import ReplayKernelBase @@ -16,6 +17,7 @@ 'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb'), '16ca524148afb0626f483163e5edf352bc1ab0e4fc7b9f9d473252762f2c7a43') + @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2013") def test_replay_mips_malta(self): self.set_machine('malta') kernel_path = self.archive_extract(self.ASSET_KERNEL_2_63_2, diff -Nru qemu-10.0.7+ds/tests/qtest/q35-test.c qemu-10.0.8+ds/tests/qtest/q35-test.c --- qemu-10.0.7+ds/tests/qtest/q35-test.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/tests/qtest/q35-test.c 2026-02-12 20:30:14.000000000 +0000 @@ -206,12 +206,6 @@ qtest_writeb(qts, SMBASE, SMRAM_TEST_PATTERN); g_assert_cmpint(qtest_readb(qts, SMBASE), ==, SMRAM_TEST_PATTERN); - /* check that writing junk to 0x9c before before negotiating is ignored */ - for (i = 0; i < 0xff; i++) { - qpci_config_writeb(pcidev, MCH_HOST_BRIDGE_F_SMBASE, i); - g_assert(qpci_config_readb(pcidev, MCH_HOST_BRIDGE_F_SMBASE) == 0); - } - /* enable SMRAM at SMBASE */ qpci_config_writeb(pcidev, MCH_HOST_BRIDGE_F_SMBASE, 0xff); g_assert(qpci_config_readb(pcidev, MCH_HOST_BRIDGE_F_SMBASE) == 0x01); diff -Nru qemu-10.0.7+ds/tests/qtest/ufs-test.c qemu-10.0.8+ds/tests/qtest/ufs-test.c --- qemu-10.0.7+ds/tests/qtest/ufs-test.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/tests/qtest/ufs-test.c 2026-02-12 20:30:14.000000000 +0000 @@ -166,6 +166,7 @@ cqhp = ufs_rreg(ufs, ufs->cqdao[TEST_QID]); cqentry_addr = ufs->cqlba[TEST_QID] + cqhp; qtest_memread(ufs->dev.bus->qts, cqentry_addr, &cqentry, sizeof(cqentry)); + cqhp = (cqhp + sizeof(UfsCqEntry)) % (QUEUE_SIZE * sizeof(UfsCqEntry)); ufs_wreg(ufs, ufs->cqdao[TEST_QID], cqhp); return cqentry.status; @@ -208,6 +209,81 @@ return ret; } +static bool ufs_mcq_sq_has_space(QUfs *ufs) +{ + uint32_t sqhp = ufs_rreg(ufs, ufs->sqdao[TEST_QID]); + uint32_t sqtp = ufs_rreg(ufs, ufs->sqdao[TEST_QID] + 0x4); + uint32_t next_sqtp = + (sqtp + sizeof(UfsSqEntry)) % (QUEUE_SIZE * sizeof(UfsSqEntry)); + return next_sqtp != sqhp; +} + +static void +__ufs_send_transfer_request_mcq_async(QUfs *ufs, uint8_t lun, + const UtpTransferReqDesc *utrd) +{ + uint32_t sqtp; + uint64_t utrd_addr; + + /* Wait for SQ space */ + while (!ufs_mcq_sq_has_space(ufs)) { + qtest_clock_step(ufs->dev.bus->qts, 100); + } + + sqtp = ufs_rreg(ufs, ufs->sqdao[TEST_QID] + 0x4); + utrd_addr = ufs->sqlba[TEST_QID] + sqtp; + qtest_memwrite(ufs->dev.bus->qts, utrd_addr, utrd, sizeof(*utrd)); + sqtp = (sqtp + sizeof(UfsSqEntry)) % (QUEUE_SIZE * sizeof(UfsSqEntry)); + ufs_wreg(ufs, ufs->sqdao[TEST_QID] + 0x4, sqtp); +} + +static int ufs_mcq_send_nop_out_async(QUfs *ufs) +{ + int cmd_desc_slot = alloc_cmd_desc_slot(ufs); + uint64_t req_upiu_addr = + ufs->cmd_desc_addr + cmd_desc_slot * UTP_COMMAND_DESCRIPTOR_SIZE; + + /* Build up request upiu */ + UtpUpiuReq req_upiu = { 0 }; + req_upiu.header.trans_type = UFS_UPIU_TRANSACTION_NOP_OUT; + req_upiu.header.task_tag = cmd_desc_slot; + qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, + sizeof(req_upiu)); + + /* Build up utp transfer request descriptor */ + UtpTransferReqDesc utrd = + ufs_build_req_utrd(req_upiu_addr, UFS_UTP_NO_DATA_TRANSFER, 0); + + /* Send Transfer Request */ + __ufs_send_transfer_request_mcq_async(ufs, 0, &utrd); + + return cmd_desc_slot; +} + +static int ufs_mcq_poll_cq(QUfs *ufs, UfsCqEntry *cqe, uint16_t n_cqe) +{ + uint32_t cqhp, cqtp; + uint64_t cqe_addr; + int ix = 0; + + cqhp = ufs_rreg(ufs, ufs->cqdao[TEST_QID]); + cqtp = ufs_rreg(ufs, ufs->cqdao[TEST_QID] + 0x4); + + while (cqhp != cqtp && ix < n_cqe) { + /* read completion entry */ + cqe_addr = ufs->cqlba[TEST_QID] + cqhp; + qtest_memread(ufs->dev.bus->qts, cqe_addr, &cqe[ix], sizeof(cqe[ix])); + + /* advance completion queue head pointer */ + cqhp = (cqhp + sizeof(UfsCqEntry)) % (QUEUE_SIZE * sizeof(UfsCqEntry)); + ix++; + } + + ufs_wreg(ufs, ufs->cqdao[TEST_QID], cqhp); + + return ix; +} + static enum UtpOcsCodes ufs_send_query(QUfs *ufs, uint8_t query_function, uint8_t query_opcode, uint8_t idn, uint8_t index, uint8_t selector, @@ -416,6 +492,7 @@ ufs_wreg(ufs, A_UTRIACR, 0); /* Enable transfer request */ + bitmap_zero(ufs->cmd_desc_bitmap, UFS_MAX_CMD_DESC); ufs->cmd_desc_addr = guest_alloc(alloc, UFS_MAX_CMD_DESC * UTP_COMMAND_DESCRIPTOR_SIZE); ufs->data_buffer_addr = @@ -679,6 +756,53 @@ ufs_exit(ufs, alloc); } +static void ufstest_mcq_cq_wraparound(void *obj, void *data, + QGuestAllocator *alloc) +{ + QUfs *ufs = obj; + UfsCqEntry cqe[QUEUE_SIZE]; + const int num_requests = QUEUE_SIZE; + int i, completed = 0; + + ufs_init(ufs, alloc); + + /* Ensure MCQ is supported */ + g_assert_true(ufs->support_mcq); + + for (i = 0; i < num_requests; ++i) { + ufs_mcq_send_nop_out_async(ufs); + } + + while (completed != num_requests) { + int n_cqe = ufs_mcq_poll_cq(ufs, cqe, ARRAY_SIZE(cqe)); + if (!n_cqe) { + break; + } + + for (i = 0; i < n_cqe; ++i) { + uint64_t ucdba; + uint64_t rsp_upiu_addr; + UtpUpiuRsp rsp_upiu; + uint8_t tag; + + g_assert_cmpuint(cqe[i].status, ==, UFS_OCS_SUCCESS); + + ucdba = le64_to_cpu(cqe[i].utp_addr) & MAKE_64BIT_MASK(7, 57); + rsp_upiu_addr = ucdba + UTP_RESPONSE_UPIU_OFFSET; + qtest_memread(ufs->dev.bus->qts, rsp_upiu_addr, &rsp_upiu, + sizeof(rsp_upiu)); + + tag = rsp_upiu.header.task_tag; + release_cmd_desc_slot(ufs, tag); + } + + completed += n_cqe; + } + + g_assert_cmpint(completed, ==, num_requests); + ufs_exit(ufs, alloc); +} + static void ufstest_query_flag_request(void *obj, void *data, QGuestAllocator *alloc) { @@ -1129,6 +1253,8 @@ qos_add_test("init", "ufs", ufstest_init, NULL); qos_add_test("legacy-read-write", "ufs", ufstest_read_write, &io_test_opts); qos_add_test("mcq-read-write", "ufs", ufstest_read_write, &mcq_test_opts); + qos_add_test("mcq-cq-wraparound", "ufs", ufstest_mcq_cq_wraparound, + &mcq_test_opts); qos_add_test("query-flag", "ufs", ufstest_query_flag_request, &io_test_opts); qos_add_test("query-attribute", "ufs", ufstest_query_attr_request, diff -Nru qemu-10.0.7+ds/tests/tcg/multiarch/test-mmap.c qemu-10.0.8+ds/tests/tcg/multiarch/test-mmap.c --- qemu-10.0.7+ds/tests/tcg/multiarch/test-mmap.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/tests/tcg/multiarch/test-mmap.c 2026-02-12 20:30:15.000000000 +0000 @@ -22,6 +22,7 @@ * along with this program; if not, see . */ +#define _GNU_SOURCE #include #include #include @@ -41,7 +42,7 @@ } \ } while (0) -unsigned char *dummybuf; +unsigned char *dummybuf; /* length is 2*pagesize */ static unsigned int pagesize; static unsigned int pagemask; int test_fd; @@ -451,9 +452,45 @@ fail_unless(addr == MAP_FAILED); fail_unless(errno == ENOMEM); + /* Attempt to remap a region which exceeds the bounds of memory. */ + addr = mremap((void *)((uintptr_t)pagesize * 10), SIZE_MAX & ~(size_t)pagemask, pagesize, 0); + fprintf(stdout, "%s mremap addr=%p", __func__, (void *)addr); + fail_unless(addr == MAP_FAILED); + fail_unless(errno == EFAULT); + fprintf(stdout, " passed\n"); } +void check_shrink_mmaps(void) +{ + unsigned char *a, *b, *c; + a = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + b = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + c = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + fail_unless(a != MAP_FAILED); + fail_unless(b != MAP_FAILED); + fail_unless(c != MAP_FAILED); + + /* Ensure we can read the full mappings */ + memcpy(dummybuf, a, 2 * pagesize); + memcpy(dummybuf, b, 2 * pagesize); + memcpy(dummybuf, c, 2 * pagesize); + + /* Shrink the middle mapping in-place; the others should be unaffected */ + b = mremap(b, pagesize * 2, pagesize, 0); + fail_unless(b != MAP_FAILED); + + /* Ensure we can still access all valid mappings */ + memcpy(dummybuf, a, 2 * pagesize); + memcpy(dummybuf, b, pagesize); + memcpy(dummybuf, c, 2 * pagesize); + + munmap(a, 2 * pagesize); + munmap(b, pagesize); + munmap(c, 2 * pagesize); +} + int main(int argc, char **argv) { char tempname[] = "/tmp/.cmmapXXXXXX"; @@ -468,7 +505,7 @@ /* Assume pagesize is a power of two. */ pagemask = pagesize - 1; - dummybuf = malloc (pagesize); + dummybuf = malloc (pagesize * 2); printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask); test_fd = mkstemp(tempname); @@ -496,6 +533,7 @@ check_file_fixed_eof_mmaps(); check_file_unfixed_eof_mmaps(); check_invalid_mmaps(); + check_shrink_mmaps(); /* Fails at the moment. */ /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */ diff -Nru qemu-10.0.7+ds/tests/vhost-user-bridge.c qemu-10.0.8+ds/tests/vhost-user-bridge.c --- qemu-10.0.7+ds/tests/vhost-user-bridge.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/tests/vhost-user-bridge.c 2026-02-12 20:30:15.000000000 +0000 @@ -746,14 +746,12 @@ static int vubr_parse_host_port(const char **host, const char **port, const char *buf) { - char *p = strchr(buf, ':'); - - if (!p) { + g_auto(GStrv) tokens = g_strsplit(buf, ":", 2); + if (!tokens[0] || !tokens[1]) { return -1; } - *p = '\0'; - *host = strdup(buf); - *port = strdup(p + 1); + *host = g_steal_pointer(&tokens[0]); + *port = g_steal_pointer(&tokens[1]); return 0; } diff -Nru qemu-10.0.7+ds/tests/vm/freebsd qemu-10.0.8+ds/tests/vm/freebsd --- qemu-10.0.7+ds/tests/vm/freebsd 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/tests/vm/freebsd 2026-02-12 20:30:15.000000000 +0000 @@ -28,8 +28,8 @@ name = "freebsd" arch = "x86_64" - link = "https://download.freebsd.org/releases/CI-IMAGES/14.1-RELEASE/amd64/Latest/FreeBSD-14.1-RELEASE-amd64-BASIC-CI.raw.xz" - csum = "202fe27a05427f0a86d3ebb97712745186f2776ccc4f70d95466dd99a0238ba5" + link = "https://download.freebsd.org/releases/CI-IMAGES/14.3-RELEASE/amd64/Latest/FreeBSD-14.3-RELEASE-amd64-BASIC-CI.raw.xz" + csum = "ec0f5a4bbe63aa50a725d9fee0f1931f850e9a21cbebdadb991df00f168d6805" size = "20G" BUILD_SCRIPT = """ diff -Nru qemu-10.0.7+ds/ui/ui-hmp-cmds.c qemu-10.0.8+ds/ui/ui-hmp-cmds.c --- qemu-10.0.7+ds/ui/ui-hmp-cmds.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/ui/ui-hmp-cmds.c 2026-02-12 20:30:15.000000000 +0000 @@ -418,7 +418,7 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) { int i; - char *sep; + const char *sep; size_t len; if (nb_args != 2) { diff -Nru qemu-10.0.7+ds/util/log.c qemu-10.0.8+ds/util/log.c --- qemu-10.0.7+ds/util/log.c 2025-12-06 14:54:25.000000000 +0000 +++ qemu-10.0.8+ds/util/log.c 2026-02-12 20:30:15.000000000 +0000 @@ -185,7 +185,7 @@ valid_filename_template(const char *filename, bool per_thread, Error **errp) { if (filename) { - char *pidstr = strstr(filename, "%"); + const char *pidstr = strstr(filename, "%"); if (pidstr) { /* We only accept one %d, no other format strings */