diff options
97 files changed, 1684 insertions, 1513 deletions
diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml index 609c364..d70da61 100644 --- a/.gitlab-ci.d/cirrus.yml +++ b/.gitlab-ci.d/cirrus.yml @@ -63,7 +63,7 @@ x64-freebsd-13-build: NAME: freebsd-13 CIRRUS_VM_INSTANCE_TYPE: freebsd_instance CIRRUS_VM_IMAGE_SELECTOR: image_family - CIRRUS_VM_IMAGE_NAME: freebsd-13-0 + CIRRUS_VM_IMAGE_NAME: freebsd-13-1 CIRRUS_VM_CPUS: 8 CIRRUS_VM_RAM: 8G UPDATE_COMMAND: pkg update diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars b/.gitlab-ci.d/cirrus/freebsd-12.vars index 8fa5a32..1a59598 100644 --- a/.gitlab-ci.d/cirrus/freebsd-12.vars +++ b/.gitlab-ci.d/cirrus/freebsd-12.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars b/.gitlab-ci.d/cirrus/freebsd-13.vars index 8ed7e33..5e5aafd 100644 --- a/.gitlab-ci.d/cirrus/freebsd-13.vars +++ b/.gitlab-ci.d/cirrus/freebsd-13.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/.gitlab-ci.d/container-core.yml b/.gitlab-ci.d/container-core.yml index e8dd1f4..08f8450 100644 --- a/.gitlab-ci.d/container-core.yml +++ b/.gitlab-ci.d/container-core.yml @@ -10,8 +10,3 @@ amd64-fedora-container: extends: .container_job_template variables: NAME: fedora - -amd64-debian10-container: - extends: .container_job_template - variables: - NAME: debian10 diff --git a/.gitlab-ci.d/container-cross.yml b/.gitlab-ci.d/container-cross.yml index 505b267..2d560e9 100644 --- a/.gitlab-ci.d/container-cross.yml +++ b/.gitlab-ci.d/container-cross.yml @@ -1,21 +1,18 @@ alpha-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-alpha-cross amd64-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-amd64-cross amd64-debian-user-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-all-test-cross @@ -66,21 +63,18 @@ hexagon-cross-container: hppa-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-hppa-cross m68k-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-m68k-cross mips64-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-mips64-cross @@ -93,7 +87,6 @@ mips64el-debian-cross-container: mips-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-mips-cross @@ -106,7 +99,6 @@ mipsel-debian-cross-container: powerpc-test-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian11-container'] variables: NAME: debian-powerpc-test-cross @@ -128,7 +120,6 @@ riscv64-debian-cross-container: riscv64-debian-test-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian11-container'] variables: NAME: debian-riscv64-test-cross @@ -141,21 +132,18 @@ s390x-debian-cross-container: sh4-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-sh4-cross sparc64-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-sparc64-cross tricore-debian-cross-container: extends: .container_job_template stage: containers - needs: ['amd64-debian10-container'] variables: NAME: debian-tricore-cross diff --git a/.gitlab-ci.d/containers.yml b/.gitlab-ci.d/containers.yml index be34cbc..96d2a3b 100644 --- a/.gitlab-ci.d/containers.yml +++ b/.gitlab-ci.d/containers.yml @@ -7,11 +7,6 @@ amd64-alpine-container: variables: NAME: alpine -amd64-debian11-container: - extends: .container_job_template - variables: - NAME: debian11 - amd64-debian-container: extends: .container_job_template stage: containers diff --git a/.gitlab-ci.d/crossbuild-template.yml b/.gitlab-ci.d/crossbuild-template.yml index 28b2142..5e8892f 100644 --- a/.gitlab-ci.d/crossbuild-template.yml +++ b/.gitlab-ci.d/crossbuild-template.yml @@ -46,5 +46,8 @@ - cd build - PKG_CONFIG_PATH=$PKG_CONFIG_PATH ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS - --disable-system + --disable-system --target-list-exclude="aarch64_be-linux-user + alpha-linux-user cris-linux-user m68k-linux-user microblazeel-linux-user + nios2-linux-user or1k-linux-user ppc-linux-user sparc-linux-user + xtensa-linux-user $CROSS_SKIP_TARGETS" - make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml index 4a5fb6e..c4cd964 100644 --- a/.gitlab-ci.d/crossbuilds.yml +++ b/.gitlab-ci.d/crossbuilds.yml @@ -70,20 +70,6 @@ cross-i386-tci: EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user MAKE_CHECK_ARGS: check check-tcg -cross-mips-system: - extends: .cross_system_build_job - needs: - job: mips-debian-cross-container - variables: - IMAGE: debian-mips-cross - -cross-mips-user: - extends: .cross_user_build_job - needs: - job: mips-debian-cross-container - variables: - IMAGE: debian-mips-cross - cross-mipsel-system: extends: .cross_system_build_job needs: diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 15aaccc..97f99e2 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -15,6 +15,6 @@ variables: include: - local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-s390x.yml' - - local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml' - - local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch32.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/centos-stream-8-x86_64.yml' diff --git a/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch32.yml b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml index cbfa9cc..1a2f9b8 100644 --- a/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch32.yml +++ b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml @@ -1,12 +1,12 @@ -# All ubuntu-20.04 jobs should run successfully in an environment +# All ubuntu-22.04 jobs should run successfully in an environment # setup by the scripts/ci/setup/qemu/build-environment.yml task # "Install basic packages to build QEMU on Ubuntu 20.04" -ubuntu-20.04-aarch32-all: +ubuntu-22.04-aarch32-all: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch32 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' diff --git a/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml index 3d87891..ce0b18a 100644 --- a/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml +++ b/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml @@ -2,21 +2,21 @@ # setup by the scripts/ci/setup/qemu/build-environment.yml task # "Install basic packages to build QEMU on Ubuntu 20.04" -ubuntu-20.04-aarch64-all-linux-static: +ubuntu-22.04-aarch64-all-linux-static: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' - if: "$AARCH64_RUNNER_AVAILABLE" script: - # --disable-libssh is needed because of https://bugs.launchpad.net/qemu/+bug/1838763 - # --disable-glusterfs is needed because there's no static version of those libs in distro supplied packages - mkdir build - cd build - - ../configure --enable-debug --static --disable-system --disable-glusterfs --disable-libssh + # 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 --output-sync -j`nproc --ignore=40` check V=1 @@ -24,11 +24,11 @@ ubuntu-20.04-aarch64-all-linux-static: - make --output-sync -j`nproc --ignore=40` check-tcg V=1 || { cat meson-logs/testlog.txt; exit 1; } ; -ubuntu-20.04-aarch64-all: +ubuntu-22.04-aarch64-all: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' @@ -40,17 +40,17 @@ ubuntu-20.04-aarch64-all: script: - mkdir build - cd build - - ../configure --disable-libssh + - ../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 V=1 || { cat meson-logs/testlog.txt; exit 1; } ; -ubuntu-20.04-aarch64-alldbg: +ubuntu-22.04-aarch64-alldbg: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' @@ -58,18 +58,18 @@ ubuntu-20.04-aarch64-alldbg: script: - mkdir build - cd build - - ../configure --enable-debug --disable-libssh + - ../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 V=1 || { cat meson-logs/testlog.txt; exit 1; } ; -ubuntu-20.04-aarch64-clang: +ubuntu-22.04-aarch64-clang: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' @@ -87,11 +87,11 @@ ubuntu-20.04-aarch64-clang: - make --output-sync -j`nproc --ignore=40` check V=1 || { cat meson-logs/testlog.txt; exit 1; } ; -ubuntu-20.04-aarch64-tci: +ubuntu-22.04-aarch64-tci: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' @@ -103,15 +103,15 @@ ubuntu-20.04-aarch64-tci: script: - mkdir build - cd build - - ../configure --disable-libssh --enable-tcg-interpreter + - ../configure --enable-tcg-interpreter || { cat config.log meson-logs/meson-log.txt; exit 1; } - make --output-sync -j`nproc --ignore=40` -ubuntu-20.04-aarch64-notcg: +ubuntu-22.04-aarch64-notcg: needs: [] stage: build tags: - - ubuntu_20.04 + - ubuntu_22.04 - aarch64 rules: - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' @@ -123,7 +123,7 @@ ubuntu-20.04-aarch64-notcg: script: - mkdir build - cd build - - ../configure --disable-libssh --disable-tcg + - ../configure --disable-tcg || { 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 V=1 diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml index da60139..86a4339 100644 --- a/.gitlab-ci.d/windows.yml +++ b/.gitlab-ci.d/windows.yml @@ -60,7 +60,6 @@ msys2-64bit: - $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink - .\msys64\usr\bin\bash -lc './configure --target-list=x86_64-softmmu --enable-capstone --without-default-devices' - - .\msys64\usr\bin\bash -lc "sed -i '/^ROMS=/d' build/config-host.mak" - .\msys64\usr\bin\bash -lc 'make' - .\msys64\usr\bin\bash -lc 'make check' diff --git a/MAINTAINERS b/MAINTAINERS index 1729c09..738c4eb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3724,7 +3724,8 @@ GitLab custom runner (Works On Arm Sponsored) M: Alex Bennée <alex.bennee@linaro.org> M: Philippe Mathieu-Daudé <f4bug@amsat.org> S: Maintained -F: .gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml +F: .gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml +F: .gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml Documentation ------------- @@ -145,7 +145,7 @@ NINJAFLAGS = $(if $V,-v) $(if $(MAKE.n), -n) $(if $(MAKE.k), -k0) \ $(filter-out -j, $(lastword -j1 $(filter -l% -j%, $(MAKEFLAGS)))) \ -d keepdepfile ninja-cmd-goals = $(or $(MAKECMDGOALS), all) -ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g)))) +ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g)) makefile-targets := build.ninja ctags TAGS cscope dist clean uninstall # "ninja -t targets" also lists all prerequisites. If build system diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 136c8ea..5acab17 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -728,7 +728,23 @@ static bool dirty_gfn_is_dirtied(struct kvm_dirty_gfn *gfn) static void dirty_gfn_set_collected(struct kvm_dirty_gfn *gfn) { - gfn->flags = KVM_DIRTY_GFN_F_RESET; + /* + * Use a store-release so that the CPU that executes KVM_RESET_DIRTY_RINGS + * sees the full content of the ring: + * + * CPU0 CPU1 CPU2 + * ------------------------------------------------------------------------------ + * fill gfn0 + * store-rel flags for gfn0 + * load-acq flags for gfn0 + * store-rel RESET for gfn0 + * ioctl(RESET_RINGS) + * load-acq flags for gfn0 + * check if flags have RESET + * + * The synchronization goes from CPU2 to CPU0 to CPU1. + */ + qatomic_store_release(&gfn->flags, KVM_DIRTY_GFN_F_RESET); } /* @@ -3892,7 +3908,7 @@ exit: typedef struct StatsDescriptors { const char *ident; /* cache key, currently the StatsTarget */ struct kvm_stats_desc *kvm_stats_desc; - struct kvm_stats_header *kvm_stats_header; + struct kvm_stats_header kvm_stats_header; QTAILQ_ENTRY(StatsDescriptors) next; } StatsDescriptors; @@ -3923,7 +3939,7 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd descriptors = g_new0(StatsDescriptors, 1); /* Read stats header */ - kvm_stats_header = g_malloc(sizeof(*kvm_stats_header)); + kvm_stats_header = &descriptors->kvm_stats_header; ret = read(stats_fd, kvm_stats_header, sizeof(*kvm_stats_header)); if (ret != sizeof(*kvm_stats_header)) { error_setg(errp, "KVM stats: failed to read stats header: " @@ -3948,7 +3964,6 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd g_free(kvm_stats_desc); return NULL; } - descriptors->kvm_stats_header = kvm_stats_header; descriptors->kvm_stats_desc = kvm_stats_desc; descriptors->ident = ident; QTAILQ_INSERT_TAIL(&stats_descriptors, descriptors, next); @@ -3973,7 +3988,7 @@ static void query_stats(StatsResultList **result, StatsTarget target, return; } - kvm_stats_header = descriptors->kvm_stats_header; + kvm_stats_header = &descriptors->kvm_stats_header; kvm_stats_desc = descriptors->kvm_stats_desc; size_desc = sizeof(*kvm_stats_desc) + kvm_stats_header->name_size; @@ -4038,7 +4053,7 @@ static void query_stats_schema(StatsSchemaList **result, StatsTarget target, return; } - kvm_stats_header = descriptors->kvm_stats_header; + kvm_stats_header = &descriptors->kvm_stats_header; kvm_stats_desc = descriptors->kvm_stats_desc; size_desc = sizeof(*kvm_stats_desc) + kvm_stats_header->name_size; diff --git a/audio/audio.c b/audio/audio.c index 76b8735..cfa4119 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -32,6 +32,7 @@ #include "qapi/qapi-visit-audio.h" #include "qemu/cutils.h" #include "qemu/module.h" +#include "qemu/help_option.h" #include "sysemu/sysemu.h" #include "sysemu/replay.h" #include "sysemu/runstate.h" @@ -2101,10 +2102,28 @@ static void audio_validate_opts(Audiodev *dev, Error **errp) } } +void audio_help(void) +{ + int i; + + printf("Available audio drivers:\n"); + + for (i = 0; i < AUDIODEV_DRIVER__MAX; i++) { + audio_driver *driver = audio_driver_lookup(AudiodevDriver_str(i)); + if (driver) { + printf("%s\n", driver->name); + } + } +} + void audio_parse_option(const char *opt) { Audiodev *dev = NULL; + if (is_help_option(opt)) { + audio_help(); + exit(EXIT_SUCCESS); + } Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal); visit_type_Audiodev(v, NULL, &dev, &error_fatal); visit_free(v); diff --git a/audio/audio.h b/audio/audio.h index 27e6707..01bdc56 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -171,6 +171,7 @@ void audio_sample_from_uint64(void *samples, int pos, void audio_define(Audiodev *audio); void audio_parse_option(const char *opt); bool audio_init_audiodevs(void); +void audio_help(void); void audio_legacy_help(void); AudioState *audio_state_by_name(const char *name); @@ -1382,6 +1382,9 @@ elif test "$pie" = "no"; then if compile_prog "-Werror -fno-pie" "-no-pie"; then CONFIGURE_CFLAGS="-fno-pie $CONFIGURE_CFLAGS" CONFIGURE_LDFLAGS="-no-pie $CONFIGURE_LDFLAGS" + # Meson currently only handles pie as a boolean for now so if we have + # explicitly disabled PIE we need to extend our cflags because it wont. + QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS" fi elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS" diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst index a2fee53..1c1e7b9 100644 --- a/docs/about/build-platforms.rst +++ b/docs/about/build-platforms.rst @@ -41,7 +41,7 @@ Those hosts are officially supported, with various accelerators: - Accelerators * - Arm - kvm (64 bit only), tcg, xen - * - MIPS + * - MIPS (little endian only) - kvm, tcg * - PPC - kvm, tcg diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index c75a25d..a72fedb 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -213,6 +213,19 @@ MIPS ``Trap-and-Emul`` KVM support (since 6.0) The MIPS ``Trap-and-Emul`` KVM host and guest support has been removed from Linux upstream kernel, declare it deprecated. +Host Architectures +------------------ + +BE MIPS (since 7.2) +''''''''''''''''''' + +As Debian 10 ("Buster") moved into LTS the big endian 32 bit version of +MIPS moved out of support making it hard to maintain our +cross-compilation CI tests of the architecture. As we no longer have +CI coverage support may bitrot away before the deprecation process +completes. The little endian variants of MIPS (both 32 and 64 bit) are +still a supported host architecture. + QEMU API (QAPI) events ---------------------- @@ -370,3 +383,22 @@ be deleted from this tree. New deployments should use the Rust version, and existing systems should consider moving to it. The command line and feature set is very close and moving should be simple. + + +QEMU guest agent +---------------- + +``--blacklist`` command line option (since 7.2) +''''''''''''''''''''''''''''''''''''''''''''''' + +``--blacklist`` has been replaced by ``--block-rpcs`` (which is a better +wording for what this option does). The short form ``-b`` still stays +the same and thus is the preferred way for scripts that should run with +both, older and future versions of QEMU. + +``blacklist`` config file option (since 7.2) +'''''''''''''''''''''''''''''''''''''''''''' + +The ``blacklist`` config file option has been renamed to ``block-rpcs`` +(to be in sync with the renaming of the corresponding command line +option). diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index f35f117..aea5b42 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -375,7 +375,7 @@ locally by using the ``NOCACHE`` build option: .. code:: - make docker-image-debian10 NOCACHE=1 + make docker-image-debian-arm64-cross NOCACHE=1 Images ~~~~~~ diff --git a/docs/interop/qemu-ga.rst b/docs/interop/qemu-ga.rst index 3063357..a918380 100644 --- a/docs/interop/qemu-ga.rst +++ b/docs/interop/qemu-ga.rst @@ -79,10 +79,10 @@ Options Daemonize after startup (detach from terminal). -.. option:: -b, --blacklist=LIST +.. option:: -b, --block-rpcs=LIST - Comma-separated list of RPCs to disable (no spaces, ``?`` to list - available RPCs). + Comma-separated list of RPCs to disable (no spaces, use ``help`` to + list available RPCs). .. option:: -D, --dump-conf @@ -125,7 +125,7 @@ pidfile string fsfreeze-hook string statedir string verbose boolean -blacklist string list +block-rpcs string list ============= =========== See also diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index a99aa38..17d15b6 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -2,13 +2,14 @@ config LOONGARCH_VIRT bool select PCI select PCI_EXPRESS_GENERIC_BRIDGE - imply VGA_PCI imply VIRTIO_VGA imply PCI_DEVICES + imply NVDIMM select ISA_BUS select SERIAL select SERIAL_ISA select VIRTIO_PCI + select PLATFORM_BUS select LOONGARCH_IPI select LOONGARCH_PCH_PIC select LOONGARCH_PCH_MSI @@ -17,3 +18,5 @@ config LOONGARCH_VIRT select SMBIOS select ACPI_PCI select ACPI_HW_REDUCED + select FW_CFG_DMA + select DIMM diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index d0f01a6..378a6d9 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -30,6 +30,7 @@ #include "qom/qom-qobject.h" #include "hw/acpi/generic_event_device.h" +#include "hw/pci-host/gpex.h" #define ACPI_BUILD_ALIGN_SIZE 0x1000 #define ACPI_BUILD_TABLE_SIZE 0x20000 @@ -186,6 +187,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_srat_memory(table_data, VIRT_HIGHMEM_BASE, machine->ram_size - VIRT_LOWMEM_SIZE, 0, MEM_AFFINITY_ENABLED); + if (ms->device_memory) { + build_srat_memory(table_data, ms->device_memory->base, + memory_region_size(&ms->device_memory->mr), + 0, MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); + } + acpi_table_end(linker, &table); } @@ -200,108 +207,6 @@ struct AcpiBuildState { MemoryRegion *linker_mr; } AcpiBuildState; -static void build_gpex_pci0_int(Aml *table) -{ - Aml *sb_scope = aml_scope("_SB"); - Aml *pci0_scope = aml_scope("PCI0"); - Aml *prt_pkg = aml_varpackage(128); - int slot, pin; - - for (slot = 0; slot < PCI_SLOT_MAX; slot++) { - for (pin = 0; pin < PCI_NUM_PINS; pin++) { - Aml *pkg = aml_package(4); - aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); - aml_append(pkg, aml_int(pin)); - aml_append(pkg, aml_int(0)); - aml_append(pkg, aml_int(80 + (slot + pin) % 4)); - aml_append(prt_pkg, pkg); - } - } - aml_append(pci0_scope, aml_name_decl("_PRT", prt_pkg)); - aml_append(sb_scope, pci0_scope); - aml_append(table, sb_scope); -} - -static void build_dbg_aml(Aml *table) -{ - Aml *field; - Aml *method; - Aml *while_ctx; - Aml *scope = aml_scope("\\"); - Aml *buf = aml_local(0); - Aml *len = aml_local(1); - Aml *idx = aml_local(2); - - aml_append(scope, - aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01)); - field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); - aml_append(field, aml_named_field("DBGB", 8)); - aml_append(scope, field); - - method = aml_method("DBUG", 1, AML_NOTSERIALIZED); - - aml_append(method, aml_to_hexstring(aml_arg(0), buf)); - aml_append(method, aml_to_buffer(buf, buf)); - aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); - aml_append(method, aml_store(aml_int(0), idx)); - - while_ctx = aml_while(aml_lless(idx, len)); - aml_append(while_ctx, - aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); - aml_append(while_ctx, aml_increment(idx)); - aml_append(method, while_ctx); - aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); - aml_append(scope, method); - aml_append(table, scope); -} - -static Aml *build_osc_method(void) -{ - Aml *if_ctx; - Aml *if_ctx2; - Aml *else_ctx; - Aml *method; - Aml *a_cwd1 = aml_name("CDW1"); - Aml *a_ctrl = aml_local(0); - - method = aml_method("_OSC", 4, AML_NOTSERIALIZED); - aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); - - if_ctx = aml_if(aml_equal( - aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); - aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); - aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); - aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); - - /* - * Always allow native PME, AER (no dependencies) - * Allow SHPC (PCI bridges can have SHPC controller) - */ - aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); - - if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); - /* Unknown revision */ - aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); - aml_append(if_ctx, if_ctx2); - - if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); - /* Capabilities bits were masked */ - aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); - aml_append(if_ctx, if_ctx2); - - /* Update DWORD3 in the buffer */ - aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); - aml_append(method, if_ctx); - - else_ctx = aml_else(); - /* Unrecognized UUID */ - aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); - aml_append(method, else_ctx); - - aml_append(method, aml_return(aml_arg(3))); - return method; -} - static void build_uart_device_aml(Aml *table) { Aml *dev; @@ -335,61 +240,55 @@ static void build_uart_device_aml(Aml *table) aml_append(table, scope); } +static void +build_la_ged_aml(Aml *dsdt, MachineState *machine) +{ + uint32_t event; + LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); + + build_ged_aml(dsdt, "\\_SB."GED_DEVICE, + HOTPLUG_HANDLER(lams->acpi_ged), + VIRT_SCI_IRQ, AML_SYSTEM_MEMORY, + VIRT_GED_EVT_ADDR); + event = object_property_get_uint(OBJECT(lams->acpi_ged), + "ged-event", &error_abort); + if (event & ACPI_GED_MEM_HOTPLUG_EVT) { + build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL, + AML_SYSTEM_MEMORY, + VIRT_GED_MEM_ADDR); + } +} + +static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) +{ + struct GPEXConfig cfg = { + .mmio64.base = VIRT_PCI_MEM_BASE, + .mmio64.size = VIRT_PCI_MEM_SIZE, + .pio.base = VIRT_PCI_IO_BASE, + .pio.size = VIRT_PCI_IO_SIZE, + .ecam.base = VIRT_PCI_CFG_BASE, + .ecam.size = VIRT_PCI_CFG_SIZE, + .irq = PCH_PIC_IRQ_OFFSET + VIRT_DEVICE_IRQS, + .bus = lams->pci_bus, + }; + + acpi_dsdt_add_gpex(scope, &cfg); +} + /* build DSDT */ static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) { - Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; - int root_bus_limit = 0x7F; + Aml *dsdt, *scope, *pkg; LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id, .oem_table_id = lams->oem_table_id }; acpi_table_begin(&table, table_data); - dsdt = init_aml_allocator(); - - build_dbg_aml(dsdt); - - sb_scope = aml_scope("_SB"); - dev = aml_device("PCI0"); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); - aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); - aml_append(dev, aml_name_decl("_ADR", aml_int(0))); - aml_append(dev, aml_name_decl("_BBN", aml_int(0))); - aml_append(dev, aml_name_decl("_UID", aml_int(1))); - aml_append(dev, build_osc_method()); - aml_append(sb_scope, dev); - aml_append(dsdt, sb_scope); - - build_gpex_pci0_int(dsdt); build_uart_device_aml(dsdt); - if (lams->acpi_ged) { - build_ged_aml(dsdt, "\\_SB."GED_DEVICE, - HOTPLUG_HANDLER(lams->acpi_ged), - VIRT_SCI_IRQ - PCH_PIC_IRQ_OFFSET, AML_SYSTEM_MEMORY, - VIRT_GED_EVT_ADDR); - } - - scope = aml_scope("\\_SB.PCI0"); - /* Build PCI0._CRS */ - crs = aml_resource_template(); - aml_append(crs, - aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, - 0x0000, 0x0, root_bus_limit, - 0x0000, root_bus_limit + 1)); - aml_append(crs, - aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, - AML_POS_DECODE, AML_ENTIRE_RANGE, - 0x0000, 0x0000, 0xFFFF, 0x18000000, 0x10000)); - aml_append(crs, - aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, - AML_CACHEABLE, AML_READ_WRITE, - 0, VIRT_PCI_MEM_BASE, - VIRT_PCI_MEM_BASE + VIRT_PCI_MEM_SIZE - 1, - 0, VIRT_PCI_MEM_BASE)); - aml_append(scope, aml_name_decl("_CRS", crs)); - aml_append(dsdt, scope); + build_pci_device_aml(dsdt, lams); + build_la_ged_aml(dsdt, machine); /* System State Package */ scope = aml_scope("\\"); diff --git a/hw/loongarch/fw_cfg.c b/hw/loongarch/fw_cfg.c index f6503d5..f15a174 100644 --- a/hw/loongarch/fw_cfg.c +++ b/hw/loongarch/fw_cfg.c @@ -23,7 +23,8 @@ FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms) int max_cpus = ms->smp.max_cpus; int smp_cpus = ms->smp.cpus; - fw_cfg = fw_cfg_init_mem_wide(VIRT_FWCFG_BASE + 8, VIRT_FWCFG_BASE, 8, 0, NULL); + fw_cfg = fw_cfg_init_mem_wide(VIRT_FWCFG_BASE + 8, VIRT_FWCFG_BASE, 8, + VIRT_FWCFG_BASE + 16, &address_space_memory); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 5cc0b05..29df997 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -37,6 +37,10 @@ #include "hw/mem/nvdimm.h" #include "sysemu/device_tree.h" #include <libfdt.h> +#include "hw/core/sysbus-fdt.h" +#include "hw/platform-bus.h" +#include "hw/display/ramfb.h" +#include "hw/mem/pc-dimm.h" static void create_fdt(LoongArchMachineState *lams) { @@ -118,7 +122,7 @@ static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams) qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "qemu,fw-cfg-mmio"); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", - 2, base, 2, 0x8); + 2, base, 2, 0x18); qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); } @@ -158,6 +162,33 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams) qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size); } +static void fdt_add_irqchip_node(LoongArchMachineState *lams) +{ + MachineState *ms = MACHINE(lams); + char *nodename; + uint32_t irqchip_phandle; + + irqchip_phandle = qemu_fdt_alloc_phandle(ms->fdt); + qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", irqchip_phandle); + + nodename = g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3); + qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2); + qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0); + + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", + "loongarch,ls7a"); + + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", + 2, VIRT_IOAPIC_REG_BASE, + 2, PCH_PIC_ROUTE_ENTRY_OFFSET); + + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", irqchip_phandle); + g_free(nodename); +} #define PM_BASE 0x10080000 #define PM_SIZE 0x100 @@ -318,6 +349,31 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState return dev; } +static DeviceState *create_platform_bus(DeviceState *pch_pic) +{ + DeviceState *dev; + SysBusDevice *sysbus; + int i, irq; + MemoryRegion *sysmem = get_system_memory(); + + dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); + dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); + qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); + qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + sysbus = SYS_BUS_DEVICE(dev); + for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { + irq = VIRT_PLATFORM_BUS_IRQ - PCH_PIC_IRQ_OFFSET + i; + sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq)); + } + + memory_region_add_subregion(sysmem, + VIRT_PLATFORM_BUS_BASEADDRESS, + sysbus_mmio_get_region(sysbus, 0)); + return dev; +} + static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams) { DeviceState *gpex_dev; @@ -331,6 +387,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * d = SYS_BUS_DEVICE(gpex_dev); sysbus_realize_and_unref(d, &error_fatal); pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus; + lams->pci_bus = pci_bus; /* Map only part size_ecam bytes of ECAM space */ ecam_alias = g_new0(MemoryRegion, 1); @@ -378,9 +435,6 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); } - /* VGA setup */ - pci_vga_init(pci_bus); - /* * There are some invalid guest memory access. * Create some unimplemented devices to emulate this. @@ -396,6 +450,8 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem); /* acpi ged */ lams->acpi_ged = create_acpi_ged(pch_pic, lams); + /* platform bus */ + lams->platform_bus_dev = create_platform_bus(pch_pic); } static void loongarch_irq_init(LoongArchMachineState *lams) @@ -664,6 +720,35 @@ static void loongarch_init(MachineState *machine) machine->ram, offset, highram_size); memory_region_add_subregion(address_space_mem, 0x90000000, &lams->highmem); memmap_add_entry(0x90000000, highram_size, 1); + + /* initialize device memory address space */ + if (machine->ram_size < machine->maxram_size) { + machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); + ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size; + + if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) { + error_report("unsupported amount of memory slots: %"PRIu64, + machine->ram_slots); + exit(EXIT_FAILURE); + } + + if (QEMU_ALIGN_UP(machine->maxram_size, + TARGET_PAGE_SIZE) != machine->maxram_size) { + error_report("maximum memory size must by aligned to multiple of " + "%d bytes", TARGET_PAGE_SIZE); + exit(EXIT_FAILURE); + } + /* device memory base is the top of high memory address. */ + machine->device_memory->base = 0x90000000 + highram_size; + machine->device_memory->base = + ROUND_UP(machine->device_memory->base, 1 * GiB); + + memory_region_init(&machine->device_memory->mr, OBJECT(lams), + "device-memory", device_mem_size); + memory_region_add_subregion(address_space_mem, machine->device_memory->base, + &machine->device_memory->mr); + } + /* Add isa io region */ memory_region_init_alias(&lams->isa_io, NULL, "isa-io", get_system_io(), 0, VIRT_ISA_IO_SIZE); @@ -700,6 +785,11 @@ static void loongarch_init(MachineState *machine) } /* Initialize the IO interrupt subsystem */ loongarch_irq_init(lams); + fdt_add_irqchip_node(lams); + platform_bus_add_all_fdt_nodes(machine->fdt, "/intc", + VIRT_PLATFORM_BUS_BASEADDRESS, + VIRT_PLATFORM_BUS_SIZE, + VIRT_PLATFORM_BUS_IRQ); lams->machine_done.notify = virt_machine_done; qemu_add_machine_init_done_notifier(&lams->machine_done); fdt_add_pcie_node(lams); @@ -745,9 +835,105 @@ static void loongarch_machine_initfn(Object *obj) lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); } +static bool memhp_type_supported(DeviceState *dev) +{ + /* we only support pc dimm now */ + return object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) && + !object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); +} + +static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp); +} + +static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (memhp_type_supported(dev)) { + virt_mem_pre_plug(hotplug_dev, dev, errp); + } +} + +static void virt_mem_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + + /* the acpi ged is always exist */ + hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev, + errp); +} + +static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (memhp_type_supported(dev)) { + virt_mem_unplug_request(hotplug_dev, dev, errp); + } +} + +static void virt_mem_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + + hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp); + pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams)); + qdev_unrealize(dev); +} + +static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (memhp_type_supported(dev)) { + virt_mem_unplug(hotplug_dev, dev, errp); + } +} + +static void virt_mem_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + + pc_dimm_plug(PC_DIMM(dev), MACHINE(lams)); + hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged), + dev, &error_abort); +} + +static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); + MachineClass *mc = MACHINE_GET_CLASS(lams); + + if (device_is_dynamic_sysbus(mc, dev)) { + if (lams->platform_bus_dev) { + platform_bus_link_device(PLATFORM_BUS_DEVICE(lams->platform_bus_dev), + SYS_BUS_DEVICE(dev)); + } + } else if (memhp_type_supported(dev)) { + virt_mem_plug(hotplug_dev, dev, errp); + } +} + +static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, + DeviceState *dev) +{ + MachineClass *mc = MACHINE_GET_CLASS(machine); + + if (device_is_dynamic_sysbus(mc, dev) || + memhp_type_supported(dev)) { + return HOTPLUG_HANDLER(machine); + } + return NULL; +} + static void loongarch_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); mc->desc = "Loongson-3A5000 LS7A1000 machine"; mc->init = loongarch_init; @@ -760,12 +946,18 @@ static void loongarch_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_VIRTIO; mc->default_boot_order = "c"; mc->no_cdrom = 1; + mc->get_hotplug_handler = virt_machine_get_hotplug_handler; + hc->plug = loongarch_machine_device_plug_cb; + hc->pre_plug = virt_machine_device_pre_plug; + hc->unplug_request = virt_machine_device_unplug_request; + hc->unplug = virt_machine_device_unplug; object_class_property_add(oc, "acpi", "OnOffAuto", loongarch_get_acpi, loongarch_set_acpi, NULL, NULL); object_class_property_set_description(oc, "acpi", "Enable ACPI"); + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); } static const TypeInfo loongarch_machine_types[] = { @@ -775,6 +967,10 @@ static const TypeInfo loongarch_machine_types[] = { .instance_size = sizeof(LoongArchMachineState), .class_init = loongarch_class_init, .instance_init = loongarch_machine_initfn, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { } + }, } }; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 67e9d46..57c8a4f 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -800,6 +800,7 @@ static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev) } /* Construct and read from host device tree the loc-code */ + g_free(path); path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", devspec); if (!g_file_get_contents(path, &buf, NULL, NULL)) { return NULL; diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 60349ee..4c9f664 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -1205,13 +1205,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp) return; } - if (test_bit(header->type, have_fields_bitmap)) { - error_setg(errp, - "can't load type %d struct, fields already specified!", - header->type); - return; + if (header->type <= SMBIOS_MAX_TYPE) { + if (test_bit(header->type, have_fields_bitmap)) { + error_setg(errp, + "can't load type %d struct, fields already specified!", + header->type); + return; + } + set_bit(header->type, have_binfile_bitmap); } - set_bit(header->type, have_binfile_bitmap); if (header->type == 4) { smbios_type4_count++; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 92b84de..09f1c88 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -49,6 +49,8 @@ struct LoongArchMachineState { char *oem_table_id; DeviceState *acpi_ged; int fdt_size; + DeviceState *platform_bus_dev; + PCIBus *pci_bus; }; #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h index cdde0af..9bd875c 100644 --- a/include/hw/pci-host/ls7a.h +++ b/include/hw/pci-host/ls7a.h @@ -42,4 +42,9 @@ #define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100) #define VIRT_RTC_LEN 0x100 #define VIRT_SCI_IRQ (PCH_PIC_IRQ_OFFSET + 4) + +#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 +#define VIRT_PLATFORM_BUS_SIZE 0x2000000 +#define VIRT_PLATFORM_BUS_NUM_IRQS 2 +#define VIRT_PLATFORM_BUS_IRQ 69 #endif diff --git a/meson.build b/meson.build index c2adb7c..3885fc1 100644 --- a/meson.build +++ b/meson.build @@ -1878,7 +1878,7 @@ config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage') config_host_data.set('CONFIG_GPROF', get_option('gprof')) config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed()) config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) -config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed()) +config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) # has_header config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) diff --git a/qemu-options.hx b/qemu-options.hx index 1bb0236..d8b5ce5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -704,10 +704,11 @@ SRST ``-audio [driver=]driver,model=value[,prop[=value][,...]]`` This option is a shortcut for configuring both the guest audio hardware and the host audio backend in one go. - The host backend options are the same as with the corresponding - ``-audiodev`` options below. The guest hardware model can be set with - ``model=modelname``. Use ``model=help`` to list the available device - types. + The driver option is the same as with the corresponding ``-audiodev`` option below. + The guest hardware model can be set with ``model=modelname``. + + Use ``driver=help`` to list the available drivers, + and ``model=help`` to list the available device types. The following two example do exactly the same, to show how ``-audio`` can be used to shorten the command line length: @@ -721,6 +722,7 @@ ERST DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, "-audiodev [driver=]driver,id=id[,prop[=value][,...]]\n" " specifies the audio backend to use\n" + " Use ``-audiodev help`` to list the available drivers\n" " id= identifier of the backend\n" " timer-period= timer period in microseconds\n" " in|out.mixing-engine= use mixing engine to mix streams inside QEMU\n" diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 954efed..eea819c 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -3356,8 +3356,8 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) } #endif -/* add unsupported commands to the blacklist */ -GList *ga_command_blacklist_init(GList *blacklist) +/* add unsupported commands to the list of blocked RPCs */ +GList *ga_command_init_blockedrpcs(GList *blockedrpcs) { #if !defined(__linux__) { @@ -3370,13 +3370,13 @@ GList *ga_command_blacklist_init(GList *blacklist) char **p = (char **)list; while (*p) { - blacklist = g_list_append(blacklist, g_strdup(*p++)); + blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); } } #endif #if !defined(HAVE_GETIFADDRS) - blacklist = g_list_append(blacklist, + blockedrpcs = g_list_append(blockedrpcs, g_strdup("guest-network-get-interfaces")); #endif @@ -3390,18 +3390,18 @@ GList *ga_command_blacklist_init(GList *blacklist) char **p = (char **)list; while (*p) { - blacklist = g_list_append(blacklist, g_strdup(*p++)); + blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); } } #endif #if !defined(CONFIG_FSTRIM) - blacklist = g_list_append(blacklist, g_strdup("guest-fstrim")); + blockedrpcs = g_list_append(blockedrpcs, g_strdup("guest-fstrim")); #endif - blacklist = g_list_append(blacklist, g_strdup("guest-get-devices")); + blockedrpcs = g_list_append(blockedrpcs, g_strdup("guest-get-devices")); - return blacklist; + return blockedrpcs; } /* register init/cleanup routines for stateful command groups */ diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 7ed7664..ec9f55b 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -2005,8 +2005,8 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) return NULL; } -/* add unsupported commands to the blacklist */ -GList *ga_command_blacklist_init(GList *blacklist) +/* add unsupported commands to the list of blocked RPCs */ +GList *ga_command_init_blockedrpcs(GList *blockedrpcs) { const char *list_unsupported[] = { "guest-suspend-hybrid", @@ -2017,7 +2017,7 @@ GList *ga_command_blacklist_init(GList *blacklist) char **p = (char **)list_unsupported; while (*p) { - blacklist = g_list_append(blacklist, g_strdup(*p++)); + blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); } if (!vss_init(true)) { @@ -2028,11 +2028,11 @@ GList *ga_command_blacklist_init(GList *blacklist) p = (char **)list; while (*p) { - blacklist = g_list_append(blacklist, g_strdup(*p++)); + blockedrpcs = g_list_append(blockedrpcs, g_strdup(*p++)); } } - return blacklist; + return blockedrpcs; } /* register init/cleanup routines for stateful command groups */ diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index 29cd504..b4e7c52 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -24,7 +24,7 @@ typedef struct GACommandState GACommandState; extern GAState *ga_state; extern QmpCommandList ga_commands; -GList *ga_command_blacklist_init(GList *blacklist); +GList *ga_command_init_blockedrpcs(GList *blockedrpcs); void ga_command_state_init(GAState *s, GACommandState *cs); void ga_command_state_add(GACommandState *cs, void (*init)(void), @@ -87,7 +87,7 @@ struct GAState { #endif bool delimit_response; bool frozen; - GList *blacklist; + GList *blockedrpcs; char *state_filepath_isfrozen; struct { const char *log_filepath; @@ -107,7 +107,7 @@ struct GAState *ga_state; QmpCommandList ga_commands; /* commands that are safe to issue while filesystems are frozen */ -static const char *ga_freeze_whitelist[] = { +static const char *ga_freeze_allowlist[] = { "guest-ping", "guest-info", "guest-sync", @@ -260,8 +260,8 @@ QEMU_COPYRIGHT "\n" #ifdef _WIN32 " -s, --service service commands: install, uninstall, vss-install, vss-uninstall\n" #endif -" -b, --blacklist comma-separated list of RPCs to disable (no spaces, \"?\"\n" -" to list available RPCs)\n" +" -b, --block-rpcs comma-separated list of RPCs to disable (no spaces,\n" +" use \"help\" to list available RPCs)\n" " -D, --dump-conf dump a qemu-ga config file based on current config\n" " options / command-line parameters to stdout\n" " -r, --retry-path attempt re-opening path if it's unavailable or closed\n" @@ -363,31 +363,31 @@ static gint ga_strcmp(gconstpointer str1, gconstpointer str2) } /* disable commands that aren't safe for fsfreeze */ -static void ga_disable_non_whitelisted(const QmpCommand *cmd, void *opaque) +static void ga_disable_not_allowed(const QmpCommand *cmd, void *opaque) { - bool whitelisted = false; + bool allowed = false; int i = 0; const char *name = qmp_command_name(cmd); - while (ga_freeze_whitelist[i] != NULL) { - if (strcmp(name, ga_freeze_whitelist[i]) == 0) { - whitelisted = true; + while (ga_freeze_allowlist[i] != NULL) { + if (strcmp(name, ga_freeze_allowlist[i]) == 0) { + allowed = true; } i++; } - if (!whitelisted) { + if (!allowed) { g_debug("disabling command: %s", name); qmp_disable_command(&ga_commands, name, "the agent is in frozen state"); } } -/* [re-]enable all commands, except those explicitly blacklisted by user */ -static void ga_enable_non_blacklisted(const QmpCommand *cmd, void *opaque) +/* [re-]enable all commands, except those explicitly blocked by user */ +static void ga_enable_non_blocked(const QmpCommand *cmd, void *opaque) { - GList *blacklist = opaque; + GList *blockedrpcs = opaque; const char *name = qmp_command_name(cmd); - if (g_list_find_custom(blacklist, name, ga_strcmp) == NULL && + if (g_list_find_custom(blockedrpcs, name, ga_strcmp) == NULL && !qmp_command_is_enabled(cmd)) { g_debug("enabling command: %s", name); qmp_enable_command(&ga_commands, name); @@ -426,8 +426,8 @@ void ga_set_frozen(GAState *s) if (ga_is_frozen(s)) { return; } - /* disable all non-whitelisted (for frozen state) commands */ - qmp_for_each_command(&ga_commands, ga_disable_non_whitelisted, NULL); + /* disable all forbidden (for frozen state) commands */ + qmp_for_each_command(&ga_commands, ga_disable_not_allowed, NULL); g_warning("disabling logging due to filesystem freeze"); ga_disable_logging(s); s->frozen = true; @@ -465,8 +465,8 @@ void ga_unset_frozen(GAState *s) s->deferred_options.pid_filepath = NULL; } - /* enable all disabled, non-blacklisted commands */ - qmp_for_each_command(&ga_commands, ga_enable_non_blacklisted, s->blacklist); + /* enable all disabled, non-blocked commands */ + qmp_for_each_command(&ga_commands, ga_enable_non_blocked, s->blockedrpcs); s->frozen = false; if (!ga_delete_file(s->state_filepath_isfrozen)) { g_warning("unable to delete %s, fsfreeze may not function properly", @@ -896,7 +896,8 @@ int64_t ga_get_fd_handle(GAState *s, Error **errp) int64_t handle; g_assert(s->pstate_filepath); - /* we blacklist commands and avoid operations that potentially require + /* + * We block commands and avoid operations that potentially require * writing to disk when we're in a frozen state. this includes opening * new files, so we should never get here in that situation */ @@ -950,8 +951,8 @@ struct GAConfig { #ifdef _WIN32 const char *service; #endif - gchar *bliststr; /* blacklist may point to this string */ - GList *blacklist; + gchar *bliststr; /* blockedrpcs may point to this string */ + GList *blockedrpcs; int daemonize; GLogLevelFlags log_level; int dumpconf; @@ -963,6 +964,7 @@ static void config_load(GAConfig *config) GError *gerr = NULL; GKeyFile *keyfile; g_autofree char *conf = g_strdup(g_getenv("QGA_CONF")) ?: get_relocated_path(QGA_CONF_DEFAULT); + const gchar *blockrpcs_key = "block-rpcs"; /* read system config */ keyfile = g_key_file_new(); @@ -1009,10 +1011,16 @@ static void config_load(GAConfig *config) config->retry_path = g_key_file_get_boolean(keyfile, "general", "retry-path", &gerr); } + if (g_key_file_has_key(keyfile, "general", "blacklist", NULL)) { + g_warning("config using deprecated 'blacklist' key, should be replaced" + " with the 'block-rpcs' key."); + blockrpcs_key = "blacklist"; + } + if (g_key_file_has_key(keyfile, "general", blockrpcs_key, NULL)) { config->bliststr = - g_key_file_get_string(keyfile, "general", "blacklist", &gerr); - config->blacklist = g_list_concat(config->blacklist, + g_key_file_get_string(keyfile, "general", blockrpcs_key, &gerr); + config->blockedrpcs = g_list_concat(config->blockedrpcs, split_list(config->bliststr, ",")); } @@ -1072,8 +1080,8 @@ static void config_dump(GAConfig *config) config->log_level == G_LOG_LEVEL_MASK); g_key_file_set_boolean(keyfile, "general", "retry-path", config->retry_path); - tmp = list_join(config->blacklist, ','); - g_key_file_set_string(keyfile, "general", "blacklist", tmp); + tmp = list_join(config->blockedrpcs, ','); + g_key_file_set_string(keyfile, "general", "block-rpcs", tmp); g_free(tmp); tmp = g_key_file_to_data(keyfile, NULL, &error); @@ -1105,7 +1113,8 @@ static void config_parse(GAConfig *config, int argc, char **argv) { "method", 1, NULL, 'm' }, { "path", 1, NULL, 'p' }, { "daemonize", 0, NULL, 'd' }, - { "blacklist", 1, NULL, 'b' }, + { "block-rpcs", 1, NULL, 'b' }, + { "blacklist", 1, NULL, 'b' }, /* deprecated alias for 'block-rpcs' */ #ifdef _WIN32 { "service", 1, NULL, 's' }, #endif @@ -1163,8 +1172,8 @@ static void config_parse(GAConfig *config, int argc, char **argv) qmp_for_each_command(&ga_commands, ga_print_cmd, NULL); exit(EXIT_SUCCESS); } - config->blacklist = g_list_concat(config->blacklist, - split_list(optarg, ",")); + config->blockedrpcs = g_list_concat(config->blockedrpcs, + split_list(optarg, ",")); break; } #ifdef _WIN32 @@ -1218,7 +1227,7 @@ static void config_free(GAConfig *config) #ifdef CONFIG_FSFREEZE g_free(config->fsfreeze_hook); #endif - g_list_free_full(config->blacklist, g_free); + g_list_free_full(config->blockedrpcs, g_free); g_free(config); } @@ -1302,7 +1311,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) s->deferred_options.log_filepath = config->log_filepath; } ga_disable_logging(s); - qmp_for_each_command(&ga_commands, ga_disable_non_whitelisted, NULL); + qmp_for_each_command(&ga_commands, ga_disable_not_allowed, NULL); } else { if (config->daemonize) { become_daemon(config->pid_filepath); @@ -1326,10 +1335,10 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) return NULL; } - config->blacklist = ga_command_blacklist_init(config->blacklist); - if (config->blacklist) { - GList *l = config->blacklist; - s->blacklist = config->blacklist; + config->blockedrpcs = ga_command_init_blockedrpcs(config->blockedrpcs); + if (config->blockedrpcs) { + GList *l = config->blockedrpcs; + s->blockedrpcs = config->blockedrpcs; do { g_debug("disabling command: %s", (char *)l->data); qmp_disable_command(&ga_commands, l->data, NULL); diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 869399e..026a56f 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -16,8 +16,8 @@ { 'pragma': { 'doc-required': true } } -# Whitelists to permit QAPI rule violations; think twice before you -# add to them! +# Lists with items allowed to permit QAPI rule violations; think twice +# before you add to them! { 'pragma': { # Types whose member names may use '_' 'member-name-exceptions': [ diff --git a/roms/qboot b/roms/qboot -Subproject a5300c4949b8d4de2d34bedfaed66793f48ec94 +Subproject 8ca302e86d685fa05b16e2b208888243da31994 diff --git a/scripts/coverity-scan/COMPONENTS.md b/scripts/coverity-scan/COMPONENTS.md index 3aad9cd..0e6ab49 100644 --- a/scripts/coverity-scan/COMPONENTS.md +++ b/scripts/coverity-scan/COMPONENTS.md @@ -22,7 +22,7 @@ i386 ~ (/qemu)?((/include)?/hw/i386/.*|/target/i386/.*|/hw/intc/[^/]*apic[^/]*\.c) m68k - ~ (/qemu)?((/include)?/hw/m68k/.*|/target/m68k/.*|(/include)?/hw(/.*)?/mcf.*) + ~ (/qemu)?((/include)?/hw/m68k/.*|/target/m68k/.*|(/include)?/hw(/.*)?/mcf.*|(/include)?/hw/nubus/.*) microblaze ~ (/qemu)?((/include)?/hw/microblaze/.*|/target/microblaze/.*) @@ -146,3 +146,6 @@ tests loongarch ~ (/qemu)?((/include)?/hw/(loongarch/.*|.*/loongarch.*)|/target/loongarch/.*) + +riscv + ~ (/qemu)?((/include)?/hw/riscv/.*|/target/riscv/.*|/hw/.*/(riscv_|ibex_|sifive_).*) diff --git a/softmmu/vl.c b/softmmu/vl.c index 263f029..e62b9cc 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2842,11 +2842,16 @@ void qemu_init(int argc, char **argv, char **envp) audio_parse_option(optarg); break; case QEMU_OPTION_audio: { - QDict *dict = keyval_parse(optarg, "driver", NULL, &error_fatal); + bool help; char *model; Audiodev *dev = NULL; Visitor *v; - + QDict *dict = keyval_parse(optarg, "driver", &help, &error_fatal); + if (help || (qdict_haskey(dict, "driver") && + is_help_option(qdict_get_str(dict, "driver")))) { + audio_help(); + exit(EXIT_SUCCESS); + } if (!qdict_haskey(dict, "id")) { qdict_put_str(dict, "id", "audiodev0"); } diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h index c0766de..7bf8bb9 100644 --- a/target/i386/ops_sse.h +++ b/target/i386/ops_sse.h @@ -926,7 +926,7 @@ static inline uint64_t helper_extrq(uint64_t src, int shift, int len) void helper_extrq_r(CPUX86State *env, ZMMReg *d, ZMMReg *s) { - d->ZMM_Q(0) = helper_extrq(d->ZMM_Q(0), s->ZMM_B(1), s->ZMM_B(0)); + d->ZMM_Q(0) = helper_extrq(d->ZMM_Q(0), s->ZMM_B(1) & 63, s->ZMM_B(0) & 63); } void helper_extrq_i(CPUX86State *env, ZMMReg *d, int index, int length) @@ -934,7 +934,7 @@ void helper_extrq_i(CPUX86State *env, ZMMReg *d, int index, int length) d->ZMM_Q(0) = helper_extrq(d->ZMM_Q(0), index, length); } -static inline uint64_t helper_insertq(uint64_t src, int shift, int len) +static inline uint64_t helper_insertq(uint64_t dest, uint64_t src, int shift, int len) { uint64_t mask; @@ -943,17 +943,17 @@ static inline uint64_t helper_insertq(uint64_t src, int shift, int len) } else { mask = (1ULL << len) - 1; } - return (src & ~(mask << shift)) | ((src & mask) << shift); + return (dest & ~(mask << shift)) | ((src & mask) << shift); } void helper_insertq_r(CPUX86State *env, ZMMReg *d, ZMMReg *s) { - d->ZMM_Q(0) = helper_insertq(s->ZMM_Q(0), s->ZMM_B(9), s->ZMM_B(8)); + d->ZMM_Q(0) = helper_insertq(d->ZMM_Q(0), s->ZMM_Q(0), s->ZMM_B(9) & 63, s->ZMM_B(8) & 63); } -void helper_insertq_i(CPUX86State *env, ZMMReg *d, int index, int length) +void helper_insertq_i(CPUX86State *env, ZMMReg *d, ZMMReg *s, int index, int length) { - d->ZMM_Q(0) = helper_insertq(d->ZMM_Q(0), index, length); + d->ZMM_Q(0) = helper_insertq(d->ZMM_Q(0), s->ZMM_Q(0), index, length); } #endif diff --git a/target/i386/ops_sse_header.h b/target/i386/ops_sse_header.h index d99464a..400b24c0 100644 --- a/target/i386/ops_sse_header.h +++ b/target/i386/ops_sse_header.h @@ -193,7 +193,7 @@ DEF_HELPER_3(rcpss, void, env, ZMMReg, ZMMReg) DEF_HELPER_3(extrq_r, void, env, ZMMReg, ZMMReg) DEF_HELPER_4(extrq_i, void, env, ZMMReg, int, int) DEF_HELPER_3(insertq_r, void, env, ZMMReg, ZMMReg) -DEF_HELPER_4(insertq_i, void, env, ZMMReg, int, int) +DEF_HELPER_5(insertq_i, void, env, ZMMReg, ZMMReg, int, int) DEF_HELPER_3(glue(haddps, SUFFIX), void, env, ZMMReg, ZMMReg) DEF_HELPER_3(glue(haddpd, SUFFIX), void, env, ZMMReg, ZMMReg) DEF_HELPER_3(glue(hsubps, SUFFIX), void, env, ZMMReg, ZMMReg) diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c index c1ffa1c..7c3c8dc 100644 --- a/target/i386/tcg/excp_helper.c +++ b/target/i386/tcg/excp_helper.c @@ -140,3 +140,16 @@ G_NORETURN void raise_exception_ra(CPUX86State *env, int exception_index, { raise_interrupt2(env, exception_index, 0, 0, 0, retaddr); } + +G_NORETURN void handle_unaligned_access(CPUX86State *env, vaddr vaddr, + MMUAccessType access_type, + uintptr_t retaddr) +{ + /* + * Unaligned accesses are currently only triggered by SSE/AVX + * instructions that impose alignment requirements on memory + * operands. These instructions raise #GP(0) upon accessing an + * unaligned address. + */ + raise_exception_ra(env, EXCP0D_GPF, retaddr); +} diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h index 34167e2..cd17233 100644 --- a/target/i386/tcg/helper-tcg.h +++ b/target/i386/tcg/helper-tcg.h @@ -42,17 +42,6 @@ void x86_cpu_do_interrupt(CPUState *cpu); bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req); #endif -/* helper.c */ -#ifdef CONFIG_USER_ONLY -void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr, - MMUAccessType access_type, - bool maperr, uintptr_t ra); -#else -bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); -#endif - void breakpoint_handler(CPUState *cs); /* n must be a constant to be efficient */ @@ -78,6 +67,23 @@ G_NORETURN void raise_exception_err_ra(CPUX86State *env, int exception_index, int error_code, uintptr_t retaddr); G_NORETURN void raise_interrupt(CPUX86State *nenv, int intno, int is_int, int error_code, int next_eip_addend); +G_NORETURN void handle_unaligned_access(CPUX86State *env, vaddr vaddr, + MMUAccessType access_type, + uintptr_t retaddr); +#ifdef CONFIG_USER_ONLY +void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr, + MMUAccessType access_type, + bool maperr, uintptr_t ra); +void x86_cpu_record_sigbus(CPUState *cs, vaddr addr, + MMUAccessType access_type, uintptr_t ra); +#else +bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr); +G_NORETURN void x86_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, + MMUAccessType access_type, + int mmu_idx, uintptr_t retaddr); +#endif /* cc_helper.c */ extern const uint8_t parity_table[256]; diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index 48feba7..796dc2a 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -439,3 +439,11 @@ bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, } return true; } + +G_NORETURN void x86_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, + MMUAccessType access_type, + int mmu_idx, uintptr_t retaddr) +{ + X86CPU *cpu = X86_CPU(cs); + handle_unaligned_access(&cpu->env, vaddr, access_type, retaddr); +} diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index 6fdfdf9..d3c2b8f 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -75,10 +75,12 @@ static const struct TCGCPUOps x86_tcg_ops = { #ifdef CONFIG_USER_ONLY .fake_user_interrupt = x86_cpu_do_interrupt, .record_sigsegv = x86_cpu_record_sigsegv, + .record_sigbus = x86_cpu_record_sigbus, #else .tlb_fill = x86_cpu_tlb_fill, .do_interrupt = x86_cpu_do_interrupt, .cpu_exec_interrupt = x86_cpu_exec_interrupt, + .do_unaligned_access = x86_cpu_do_unaligned_access, .debug_excp_handler = breakpoint_handler, .debug_check_breakpoint = x86_debug_check_breakpoint, #endif /* !CONFIG_USER_ONLY */ diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index d6420df..44af8c1 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -2289,6 +2289,31 @@ static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, } } +static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot) +{ + target_ulong ret; + + switch (ot) { + case MO_8: + ret = x86_ldub_code(env, s); + break; + case MO_16: + ret = x86_lduw_code(env, s); + break; + case MO_32: + ret = x86_ldl_code(env, s); + break; +#ifdef TARGET_X86_64 + case MO_64: + ret = x86_ldq_code(env, s); + break; +#endif + default: + g_assert_not_reached(); + } + return ret; +} + static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) { uint32_t ret; @@ -2738,21 +2763,23 @@ static inline void gen_stq_env_A0(DisasContext *s, int offset) tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ); } -static inline void gen_ldo_env_A0(DisasContext *s, int offset) +static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align) { int mem_index = s->mem_index; - tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, MO_LEUQ); + tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, + MO_LEUQ | (align ? MO_ALIGN_16 : 0)); tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0))); tcg_gen_addi_tl(s->tmp0, s->A0, 8); tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1))); } -static inline void gen_sto_env_A0(DisasContext *s, int offset) +static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align) { int mem_index = s->mem_index; tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0))); - tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, MO_LEUQ); + tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, + MO_LEUQ | (align ? MO_ALIGN_16 : 0)); tcg_gen_addi_tl(s->tmp0, s->A0, 8); tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1))); tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ); @@ -3131,7 +3158,7 @@ static const struct SSEOpHelper_table6 sse_op_table6[256] = { [0x25] = UNARY_OP(pmovsxdq, SSE41, SSE_OPF_MMX), [0x28] = BINARY_OP(pmuldq, SSE41, SSE_OPF_MMX), [0x29] = BINARY_OP(pcmpeqq, SSE41, SSE_OPF_MMX), - [0x2a] = SPECIAL_OP(SSE41), /* movntqda */ + [0x2a] = SPECIAL_OP(SSE41), /* movntdqa */ [0x2b] = BINARY_OP(packusdw, SSE41, SSE_OPF_MMX), [0x30] = UNARY_OP(pmovzxbw, SSE41, SSE_OPF_MMX), [0x31] = UNARY_OP(pmovzxbd, SSE41, SSE_OPF_MMX), @@ -3294,17 +3321,17 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x1e7: /* movntdq */ case 0x02b: /* movntps */ - case 0x12b: /* movntps */ + case 0x12b: /* movntpd */ if (mod == 3) goto illegal_op; gen_lea_modrm(env, s, modrm); - gen_sto_env_A0(s, ZMM_OFFSET(reg)); + gen_sto_env_A0(s, ZMM_OFFSET(reg), true); break; case 0x3f0: /* lddqu */ if (mod == 3) goto illegal_op; gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, ZMM_OFFSET(reg)); + gen_ldo_env_A0(s, ZMM_OFFSET(reg), false); break; case 0x22b: /* movntss */ case 0x32b: /* movntsd */ @@ -3373,7 +3400,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x26f: /* movdqu xmm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, ZMM_OFFSET(reg)); + gen_ldo_env_A0(s, ZMM_OFFSET(reg), + /* movaps, movapd, movdqa */ + b == 0x028 || b == 0x128 || b == 0x16f); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(s, ZMM_OFFSET(reg), ZMM_OFFSET(rm)); @@ -3432,7 +3461,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x212: /* movsldup */ if (mod != 3) { gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, ZMM_OFFSET(reg)); + gen_ldo_env_A0(s, ZMM_OFFSET(reg), true); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)), @@ -3474,7 +3503,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x216: /* movshdup */ if (mod != 3) { gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, ZMM_OFFSET(reg)); + gen_ldo_env_A0(s, ZMM_OFFSET(reg), true); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)), @@ -3502,10 +3531,20 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, gen_helper_extrq_i(cpu_env, s->ptr0, tcg_const_i32(bit_index), tcg_const_i32(field_length)); - else - gen_helper_insertq_i(cpu_env, s->ptr0, + else { + if (mod != 3) { + gen_lea_modrm(env, s, modrm); + op2_offset = offsetof(CPUX86State, xmm_t0); + gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0))); + } else { + rm = (modrm & 7) | REX_B(s); + op2_offset = ZMM_OFFSET(rm); + } + tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset); + gen_helper_insertq_i(cpu_env, s->ptr0, s->ptr1, tcg_const_i32(bit_index), tcg_const_i32(field_length)); + } } break; case 0x7e: /* movd ea, mm */ @@ -3568,7 +3607,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x27f: /* movdqu ea, xmm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); - gen_sto_env_A0(s, ZMM_OFFSET(reg)); + gen_sto_env_A0(s, ZMM_OFFSET(reg), + /* movaps, movapd, movdqa */ + b == 0x029 || b == 0x129 || b == 0x17f); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(s, ZMM_OFFSET(rm), ZMM_OFFSET(reg)); @@ -3724,7 +3765,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if (mod != 3) { gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,xmm_t0); - gen_ldo_env_A0(s, op2_offset); + /* FIXME: should be 64-bit access if b1 == 0. */ + gen_ldo_env_A0(s, op2_offset, !!b1); } else { rm = (modrm & 7) | REX_B(s); op2_offset = ZMM_OFFSET(rm); @@ -3913,11 +3955,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_st16_tl(s->tmp0, cpu_env, op2_offset + offsetof(ZMMReg, ZMM_W(0))); break; - case 0x2a: /* movntqda */ - gen_ldo_env_A0(s, op1_offset); + case 0x2a: /* movntdqa */ + gen_ldo_env_A0(s, op1_offset, true); return; default: - gen_ldo_env_A0(s, op2_offset); + gen_ldo_env_A0(s, op2_offset, true); } } if (!op6->fn[b1].op1) { @@ -4499,7 +4541,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } else { op2_offset = offsetof(CPUX86State, xmm_t0); gen_lea_modrm(env, s, modrm); - gen_ldo_env_A0(s, op2_offset); + gen_ldo_env_A0(s, op2_offset, true); } val = x86_ldub_code(env, s); @@ -4606,7 +4648,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; default: /* 128 bit access */ - gen_ldo_env_A0(s, op2_offset); + gen_ldo_env_A0(s, op2_offset, true); break; } } else { @@ -4716,9 +4758,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) switch (b) { case 0xf3: prefixes |= PREFIX_REPZ; + prefixes &= ~PREFIX_REPNZ; goto next_byte; case 0xf2: prefixes |= PREFIX_REPNZ; + prefixes &= ~PREFIX_REPZ; goto next_byte; case 0xf0: prefixes |= PREFIX_LOCK; @@ -5832,16 +5876,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) target_ulong offset_addr; ot = mo_b_d(b, dflag); - switch (s->aflag) { -#ifdef TARGET_X86_64 - case MO_64: - offset_addr = x86_ldq_code(env, s); - break; -#endif - default: - offset_addr = insn_get(env, s, s->aflag); - break; - } + offset_addr = insn_get_addr(env, s, s->aflag); tcg_gen_movi_tl(s->A0, offset_addr); gen_add_A0_ds_seg(s); if ((b & 2) == 0) { diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp_helper.c index cd507e2..b3bdb78 100644 --- a/target/i386/tcg/user/excp_helper.c +++ b/target/i386/tcg/user/excp_helper.c @@ -48,3 +48,10 @@ void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr, cpu_loop_exit_restore(cs, ra); } + +void x86_cpu_record_sigbus(CPUState *cs, vaddr addr, + MMUAccessType access_type, uintptr_t ra) +{ + X86CPU *cpu = X86_CPU(cs); + handle_unaligned_access(&cpu->env, addr, access_type, ra); +} diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py index 5f1d3e5..910f3ba 100644 --- a/tests/avocado/avocado_qemu/__init__.py +++ b/tests/avocado/avocado_qemu/__init__.py @@ -229,7 +229,7 @@ def exec_command_and_wait_for_pattern(test, command, class QemuBaseTest(avocado.Test): # default timeout for all tests, can be overridden - timeout = 900 + timeout = 120 def _get_unique_tag_val(self, tag_name): """ diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py index ee584d2..b7522ad 100644 --- a/tests/avocado/boot_linux.py +++ b/tests/avocado/boot_linux.py @@ -63,6 +63,7 @@ class BootLinuxAarch64(LinuxTest): :avocado: tags=machine:virt :avocado: tags=machine:gic-version=2 """ + timeout = 240 def add_common_args(self): self.vm.add_args('-bios', @@ -114,6 +115,8 @@ class BootLinuxPPC64(LinuxTest): :avocado: tags=arch:ppc64 """ + timeout = 180 + def test_pseries_tcg(self): """ :avocado: tags=machine:pseries @@ -129,6 +132,8 @@ class BootLinuxS390X(LinuxTest): :avocado: tags=arch:s390x """ + timeout = 240 + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_s390_ccw_virtio_tcg(self): """ diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index 6b1533c..f26e036 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -335,13 +335,13 @@ class BootLinuxConsole(LinuxKernelTest): """ images_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/' 'bionic-updates/main/installer-arm64/' - '20101020ubuntu543.15/images/') + '20101020ubuntu543.19/images/') kernel_url = images_url + 'netboot/ubuntu-installer/arm64/linux' - kernel_hash = '5bfc54cf7ed8157d93f6e5b0241e727b6dc22c50' + kernel_hash = 'e167757620640eb26de0972f578741924abb3a82' kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) initrd_url = images_url + 'netboot/ubuntu-installer/arm64/initrd.gz' - initrd_hash = 'd385d3e88d53e2004c5d43cbe668b458a094f772' + initrd_hash = 'cab5cb3fcefca8408aa5aae57f24574bfce8bdb9' initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) self.vm.set_console() diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py index 65d38f4..0f64eb6 100644 --- a/tests/avocado/machine_aspeed.py +++ b/tests/avocado/machine_aspeed.py @@ -6,12 +6,14 @@ # later. See the COPYING file in the top-level directory. import time +import os from avocado_qemu import QemuSystemTest from avocado_qemu import wait_for_console_pattern from avocado_qemu import exec_command from avocado_qemu import exec_command_and_wait_for_pattern from avocado.utils import archive +from avocado import skipIf class AST1030Machine(QemuSystemTest): @@ -176,6 +178,20 @@ class AST2x00Machine(QemuSystemTest): self.do_test_arm_aspeed_buidroot_poweroff() +class AST2x00MachineSDK(QemuSystemTest): + + # FIXME: Although these tests boot a whole distro they are still + # slower than comparable machine models. There may be some + # optimisations which bring down the runtime. In the meantime they + # have generous timeouts and are disable for CI which aims for all + # tests to run in less than 60 seconds. + timeout = 240 + + def wait_for_console_pattern(self, success_message, vm=None): + wait_for_console_pattern(self, success_message, + failure_message='Kernel panic - not syncing', + vm=vm) + def do_test_arm_aspeed_sdk_start(self, image, cpu_id): self.vm.set_console() self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', @@ -187,6 +203,7 @@ class AST2x00Machine(QemuSystemTest): self.wait_for_console_pattern('Starting kernel ...') self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id) + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_arm_ast2500_evb_sdk(self): """ :avocado: tags=arch:arm @@ -204,6 +221,7 @@ class AST2x00Machine(QemuSystemTest): self.workdir + '/ast2500-default/image-bmc', '0x0') self.wait_for_console_pattern('ast2500-default login:') + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_arm_ast2600_evb_sdk(self): """ :avocado: tags=arch:arm diff --git a/tests/data/test-qga-config b/tests/data/test-qga-config index 4bb721a..b6b7bc9 100644 --- a/tests/data/test-qga-config +++ b/tests/data/test-qga-config @@ -5,4 +5,4 @@ path=/path/to/org.qemu.guest_agent.0 pidfile=/var/foo/qemu-ga.pid statedir=/var/state verbose=true -blacklist=guest-ping;guest-get-time +block-rpcs=guest-ping;guest-get-time diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 9a45e88..270e997 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -69,40 +69,24 @@ docker-binfmt-image-debian-%: $(DOCKER_FILES_DIR)/debian-bootstrap.docker { echo "You will need to build $(EXECUTABLE)"; exit 1;},\ "CHECK", "debian-$* exists")) -# Enforce dependencies for composite images -# we don't run tests on intermediate images (used as base by another image) -DOCKER_PARTIAL_IMAGES := debian10 debian11 +# Special case cross-compiling x86_64 on non-x86_64 systems. ifeq ($(HOST_ARCH),x86_64) -docker-image-debian-amd64: docker-image-debian10 DOCKER_PARTIAL_IMAGES += debian-amd64-cross else -docker-image-debian-amd64-cross: docker-image-debian10 DOCKER_PARTIAL_IMAGES += debian-amd64 endif # For non-x86 hosts not all cross-compilers have been packaged ifneq ($(HOST_ARCH),x86_64) -DOCKER_PARTIAL_IMAGES += debian-mips-cross debian-mipsel-cross debian-mips64el-cross +DOCKER_PARTIAL_IMAGES += debian-mipsel-cross debian-mips64el-cross DOCKER_PARTIAL_IMAGES += debian-ppc64el-cross DOCKER_PARTIAL_IMAGES += debian-s390x-cross DOCKER_PARTIAL_IMAGES += fedora endif -docker-image-debian-alpha-cross: docker-image-debian10 -docker-image-debian-hppa-cross: docker-image-debian10 -docker-image-debian-m68k-cross: docker-image-debian10 -docker-image-debian-mips-cross: docker-image-debian10 -docker-image-debian-mips64-cross: docker-image-debian10 -docker-image-debian-sh4-cross: docker-image-debian10 -docker-image-debian-sparc64-cross: docker-image-debian10 - # The native build should never use the registry docker-image-debian-native: DOCKER_REGISTRY= -# base images should not add a local user -docker-image-debian10: NOUSER=1 -docker-image-debian11: NOUSER=1 - # alpine has no adduser docker-image-alpine: NOUSER=1 @@ -137,15 +121,6 @@ docker-image-debian-nios2-cross: $(DOCKER_FILES_DIR)/debian-toolchain.docker \ $(DOCKER_FILES_DIR)/debian-nios2-cross.d/build-toolchain.sh $(call debian-toolchain, $@) -# Specialist build images, sometimes very limited tools -docker-image-debian-tricore-cross: docker-image-debian10 -docker-image-debian-all-test-cross: docker-image-debian10 -docker-image-debian-loongarch-cross: docker-image-debian11 -docker-image-debian-microblaze-cross: docker-image-debian10 -docker-image-debian-nios2-cross: docker-image-debian10 -docker-image-debian-powerpc-test-cross: docker-image-debian11 -docker-image-debian-riscv64-test-cross: docker-image-debian11 - # These images may be good enough for building tests but not for test builds DOCKER_PARTIAL_IMAGES += debian-alpha-cross DOCKER_PARTIAL_IMAGES += debian-powerpc-test-cross @@ -153,6 +128,7 @@ DOCKER_PARTIAL_IMAGES += debian-hppa-cross DOCKER_PARTIAL_IMAGES += debian-loongarch-cross DOCKER_PARTIAL_IMAGES += debian-m68k-cross debian-mips64-cross DOCKER_PARTIAL_IMAGES += debian-microblaze-cross +DOCKER_PARTIAL_IMAGES += debian-mips-cross DOCKER_PARTIAL_IMAGES += debian-nios2-cross DOCKER_PARTIAL_IMAGES += debian-riscv64-test-cross DOCKER_PARTIAL_IMAGES += debian-sh4-cross debian-sparc64-cross diff --git a/tests/docker/docker.py b/tests/docker/docker.py index d0af286..3a1ed7c 100755 --- a/tests/docker/docker.py +++ b/tests/docker/docker.py @@ -205,22 +205,17 @@ def _read_qemu_dockerfile(img_name): return _read_dockerfile(df) -def _dockerfile_preprocess(df): - out = "" +def _dockerfile_verify_flat(df): + "Verify we do not include other qemu/ layers" for l in df.splitlines(): if len(l.strip()) == 0 or l.startswith("#"): continue from_pref = "FROM qemu/" if l.startswith(from_pref): - # TODO: Alternatively we could replace this line with "FROM $ID" - # where $ID is the image's hex id obtained with - # $ docker images $IMAGE --format="{{.Id}}" - # but unfortunately that's not supported by RHEL 7. - inlining = _read_qemu_dockerfile(l[len(from_pref):]) - out += _dockerfile_preprocess(inlining) - continue - out += l + "\n" - return out + print("We no longer support multiple QEMU layers.") + print("Dockerfiles should be flat, ideally created by lcitool") + return False + return True class Docker(object): @@ -309,23 +304,10 @@ class Docker(object): if argv is None: argv = [] - # pre-calculate the docker checksum before any - # substitutions we make for caching - checksum = _text_checksum(_dockerfile_preprocess(dockerfile)) + if not _dockerfile_verify_flat(dockerfile): + return -1 - if registry is not None: - sources = re.findall("FROM qemu\/(.*)", dockerfile) - # Fetch any cache layers we can, may fail - for s in sources: - pull_args = ["pull", "%s/qemu/%s" % (registry, s)] - if self._do(pull_args, quiet=quiet) != 0: - registry = None - break - # Make substitutions - if registry is not None: - dockerfile = dockerfile.replace("FROM qemu/", - "FROM %s/qemu/" % - (registry)) + checksum = _text_checksum(dockerfile) tmp_df = tempfile.NamedTemporaryFile(mode="w+t", encoding='utf-8', @@ -371,7 +353,7 @@ class Docker(object): checksum = self.get_image_dockerfile_checksum(tag) except Exception: return False - return checksum == _text_checksum(_dockerfile_preprocess(dockerfile)) + return checksum == _text_checksum(dockerfile) def run(self, cmd, keep, quiet, as_user=False): label = uuid.uuid4().hex diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker b/tests/docker/dockerfiles/debian-all-test-cross.docker index dedcea5..2beb077 100644 --- a/tests/docker/dockerfiles/debian-all-test-cross.docker +++ b/tests/docker/dockerfiles/debian-all-test-cross.docker @@ -6,16 +6,24 @@ # basic compilers for as many targets as possible. We shall use this # to build and run linux-user tests on GitLab # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -# What we need to build QEMU itself -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ +# Duplicate deb line as deb-src +RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ apt build-dep -yy qemu -# Add the foreign architecture we want and install dependencies +# Add extra build tools and as many cross compilers as we can for testing RUN DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ + ccache \ + clang \ + git \ + ninja-build \ gcc-aarch64-linux-gnu \ libc6-dev-arm64-cross \ gcc-alpha-linux-gnu \ diff --git a/tests/docker/dockerfiles/debian-alpha-cross.docker b/tests/docker/dockerfiles/debian-alpha-cross.docker index 10fe30d..4eeb43c 100644 --- a/tests/docker/dockerfiles/debian-alpha-cross.docker +++ b/tests/docker/dockerfiles/debian-alpha-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-alpha-linux-gnu \ libc6.1-dev-alpha-cross diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker index 870109e..7d2feb7 100644 --- a/tests/docker/dockerfiles/debian-amd64-cross.docker +++ b/tests/docker/dockerfiles/debian-amd64-cross.docker @@ -1,22 +1,168 @@ +# THIS FILE WAS AUTO-GENERATED # -# Docker x86_64 cross target +# $ lcitool dockerfile --layers all --cross x86_64 debian-11 qemu # -# This docker target is used on non-x86_64 machines which need the -# x86_64 cross compilers installed. -# -FROM qemu/debian10 -MAINTAINER Alex Bennée <alex.bennee@linaro.org> +# https://gitlab.com/libvirt/libvirt-ci + +FROM docker.io/library/debian:11-slim + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ + bash \ + bc \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libpcre2-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ + eatmydata apt-get autoremove -y && \ + eatmydata apt-get autoclean -y && \ + sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ + dpkg-reconfigure locales + +ENV LANG "en_US.UTF-8" +ENV MAKE "/usr/bin/make" +ENV NINJA "/usr/bin/ninja" +ENV PYTHON "/usr/bin/python3" +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" -# Add the foreign architecture we want and install dependencies -RUN dpkg --add-architecture amd64 -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - crossbuild-essential-amd64 -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt build-dep -yy -a amd64 --arch-only qemu +RUN export DEBIAN_FRONTEND=noninteractive && \ + dpkg --add-architecture amd64 && \ + eatmydata apt-get update && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ + eatmydata apt-get install --no-install-recommends -y \ + g++-x86-64-linux-gnu \ + gcc-x86-64-linux-gnu \ + libaio-dev:amd64 \ + libasan5:amd64 \ + libasound2-dev:amd64 \ + libattr1-dev:amd64 \ + libbpf-dev:amd64 \ + libbrlapi-dev:amd64 \ + libbz2-dev:amd64 \ + libc6-dev:amd64 \ + libcacard-dev:amd64 \ + libcap-ng-dev:amd64 \ + libcapstone-dev:amd64 \ + libcmocka-dev:amd64 \ + libcurl4-gnutls-dev:amd64 \ + libdaxctl-dev:amd64 \ + libdrm-dev:amd64 \ + libepoxy-dev:amd64 \ + libfdt-dev:amd64 \ + libffi-dev:amd64 \ + libfuse3-dev:amd64 \ + libgbm-dev:amd64 \ + libgcrypt20-dev:amd64 \ + libglib2.0-dev:amd64 \ + libglusterfs-dev:amd64 \ + libgnutls28-dev:amd64 \ + libgtk-3-dev:amd64 \ + libibumad-dev:amd64 \ + libibverbs-dev:amd64 \ + libiscsi-dev:amd64 \ + libjemalloc-dev:amd64 \ + libjpeg62-turbo-dev:amd64 \ + libjson-c-dev:amd64 \ + liblttng-ust-dev:amd64 \ + liblzo2-dev:amd64 \ + libncursesw5-dev:amd64 \ + libnfs-dev:amd64 \ + libnuma-dev:amd64 \ + libpam0g-dev:amd64 \ + libpixman-1-dev:amd64 \ + libpmem-dev:amd64 \ + libpng-dev:amd64 \ + libpulse-dev:amd64 \ + librbd-dev:amd64 \ + librdmacm-dev:amd64 \ + libsasl2-dev:amd64 \ + libsdl2-dev:amd64 \ + libsdl2-image-dev:amd64 \ + libseccomp-dev:amd64 \ + libselinux1-dev:amd64 \ + libslirp-dev:amd64 \ + libsnappy-dev:amd64 \ + libspice-server-dev:amd64 \ + libssh-gcrypt-dev:amd64 \ + libsystemd-dev:amd64 \ + libtasn1-6-dev:amd64 \ + libubsan1:amd64 \ + libudev-dev:amd64 \ + liburing-dev:amd64 \ + libusb-1.0-0-dev:amd64 \ + libusbredirhost-dev:amd64 \ + libvdeplug-dev:amd64 \ + libvirglrenderer-dev:amd64 \ + libvte-2.91-dev:amd64 \ + libxen-dev:amd64 \ + libzstd-dev:amd64 \ + nettle-dev:amd64 \ + systemtap-sdt-dev:amd64 \ + xfslibs-dev:amd64 \ + zlib1g-dev:amd64 && \ + eatmydata apt-get autoremove -y && \ + eatmydata apt-get autoclean -y && \ + mkdir -p /usr/local/share/meson/cross && \ + echo "[binaries]\n\ +c = '/usr/bin/x86_64-linux-gnu-gcc'\n\ +ar = '/usr/bin/x86_64-linux-gnu-gcc-ar'\n\ +strip = '/usr/bin/x86_64-linux-gnu-strip'\n\ +pkgconfig = '/usr/bin/x86_64-linux-gnu-pkg-config'\n\ +\n\ +[host_machine]\n\ +system = 'linux'\n\ +cpu_family = 'x86_64'\n\ +cpu = 'x86_64'\n\ +endian = 'little'" > /usr/local/share/meson/cross/x86_64-linux-gnu && \ + dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \ + mkdir -p /usr/libexec/ccache-wrappers && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-linux-gnu-c++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-linux-gnu-cc && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-linux-gnu-g++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-linux-gnu-gcc -# Specify the cross prefix for this image (see tests/docker/common.rc) +ENV ABI "x86_64-linux-gnu" +ENV MESON_OPTS "--cross-file=x86_64-linux-gnu" ENV QEMU_CONFIGURE_OPTS --cross-prefix=x86_64-linux-gnu- ENV DEF_TARGET_LIST x86_64-softmmu,x86_64-linux-user,i386-softmmu,i386-linux-user diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker index d5dc299..8d219bb 100644 --- a/tests/docker/dockerfiles/debian-hexagon-cross.docker +++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker @@ -2,12 +2,10 @@ # Docker Hexagon cross-compiler target # # This docker target is used for building hexagon tests. As it also -# needs to be able to build QEMU itself in CI we include it's -# build-deps. It is also a "stand-alone" image so as not to be -# triggered by re-builds on other base images given it takes a long -# time to build. +# needs to be able to build QEMU itself in CI we include its +# build-deps. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim # Install common build utilities RUN apt update && \ @@ -15,11 +13,18 @@ RUN apt update && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ bison \ + ca-certificates \ + clang \ cmake \ flex \ + gcc \ lld \ + make \ + ninja-build \ + python3 \ rsync \ - wget + wget \ + xz-utils ENV TOOLCHAIN_INSTALL /usr/local ENV ROOTFS /usr/local @@ -32,7 +37,7 @@ ADD build-toolchain.sh /root/hexagon-toolchain/build-toolchain.sh RUN cd /root/hexagon-toolchain && ./build-toolchain.sh -FROM debian:buster-slim +FROM docker.io/library/debian:11-slim # Duplicate deb line as deb-src RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list # Install QEMU build deps for use in CI diff --git a/tests/docker/dockerfiles/debian-hppa-cross.docker b/tests/docker/dockerfiles/debian-hppa-cross.docker index 3d6c65a..af1c840 100644 --- a/tests/docker/dockerfiles/debian-hppa-cross.docker +++ b/tests/docker/dockerfiles/debian-hppa-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-hppa-linux-gnu \ libc6-dev-hppa-cross diff --git a/tests/docker/dockerfiles/debian-loongarch-cross.docker b/tests/docker/dockerfiles/debian-loongarch-cross.docker index ca2469d..a8e8e98 100644 --- a/tests/docker/dockerfiles/debian-loongarch-cross.docker +++ b/tests/docker/dockerfiles/debian-loongarch-cross.docker @@ -1,11 +1,13 @@ # # Docker cross-compiler target # -# This docker target builds on the debian11 base image, -# using a prebuilt toolchains for LoongArch64 from: +# This docker target uses prebuilt toolchains for LoongArch64 from: # https://github.com/loongson/build-tools/releases # -FROM qemu/debian11 +FROM docker.io/library/debian:11-slim + +# Duplicate deb line as deb-src +RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ diff --git a/tests/docker/dockerfiles/debian-m68k-cross.docker b/tests/docker/dockerfiles/debian-m68k-cross.docker index fcb10e3..dded71c 100644 --- a/tests/docker/dockerfiles/debian-m68k-cross.docker +++ b/tests/docker/dockerfiles/debian-m68k-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-m68k-linux-gnu \ libc6-dev-m68k-cross diff --git a/tests/docker/dockerfiles/debian-mips-cross.docker b/tests/docker/dockerfiles/debian-mips-cross.docker index 26c1540..7b55f0f 100644 --- a/tests/docker/dockerfiles/debian-mips-cross.docker +++ b/tests/docker/dockerfiles/debian-mips-cross.docker @@ -1,32 +1,14 @@ # # Docker mips cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 - -MAINTAINER Philippe Mathieu-Daudé <f4bug@amsat.org> - -# Add the foreign architecture we want and install dependencies -RUN dpkg --add-architecture mips -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - gcc-mips-linux-gnu - -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt build-dep -yy -a mips --arch-only qemu - -# Specify the cross prefix for this image (see tests/docker/common.rc) -ENV QEMU_CONFIGURE_OPTS --cross-prefix=mips-linux-gnu- -ENV DEF_TARGET_LIST mips-softmmu,mipsel-linux-user - -# Install extra libraries to increase code coverage -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - libbz2-dev:mips \ - liblzo2-dev:mips \ - librdmacm-dev:mips \ - libsnappy-dev:mips +FROM docker.io/library/debian:11-slim + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ + gcc-mips-linux-gnu \ + libc6-dev-mips-cross diff --git a/tests/docker/dockerfiles/debian-mips64-cross.docker b/tests/docker/dockerfiles/debian-mips64-cross.docker index 09c2ba5..afcff97 100644 --- a/tests/docker/dockerfiles/debian-mips64-cross.docker +++ b/tests/docker/dockerfiles/debian-mips64-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-mips64-linux-gnuabi64 \ libc6-dev-mips64-cross diff --git a/tests/docker/dockerfiles/debian-powerpc-test-cross.docker b/tests/docker/dockerfiles/debian-powerpc-test-cross.docker index 36b336f..d6b2909 100644 --- a/tests/docker/dockerfiles/debian-powerpc-test-cross.docker +++ b/tests/docker/dockerfiles/debian-powerpc-test-cross.docker @@ -1,13 +1,15 @@ # # Docker powerpc/ppc64/ppc64le cross-compiler target # -# This docker target builds on the debian Bullseye base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian11 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-powerpc-linux-gnu \ libc6-dev-powerpc-cross \ gcc-10-powerpc64-linux-gnu \ diff --git a/tests/docker/dockerfiles/debian-riscv64-test-cross.docker b/tests/docker/dockerfiles/debian-riscv64-test-cross.docker index 1d90901..e5f83a5 100644 --- a/tests/docker/dockerfiles/debian-riscv64-test-cross.docker +++ b/tests/docker/dockerfiles/debian-riscv64-test-cross.docker @@ -3,10 +3,12 @@ # # This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian11 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-riscv64-linux-gnu \ libc6-dev-riscv64-cross diff --git a/tests/docker/dockerfiles/debian-sh4-cross.docker b/tests/docker/dockerfiles/debian-sh4-cross.docker index fd3af89..d48ed90 100644 --- a/tests/docker/dockerfiles/debian-sh4-cross.docker +++ b/tests/docker/dockerfiles/debian-sh4-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-sh4-linux-gnu \ libc6-dev-sh4-cross diff --git a/tests/docker/dockerfiles/debian-sparc64-cross.docker b/tests/docker/dockerfiles/debian-sparc64-cross.docker index f4bb9b5..8d3d306 100644 --- a/tests/docker/dockerfiles/debian-sparc64-cross.docker +++ b/tests/docker/dockerfiles/debian-sparc64-cross.docker @@ -1,12 +1,14 @@ # # Docker cross-compiler target # -# This docker target builds on the debian Buster base image. +# This docker target builds on the Debian Bullseye base image. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y eatmydata && \ + eatmydata apt-get dist-upgrade -y && \ + eatmydata apt-get install --no-install-recommends -y \ gcc-sparc64-linux-gnu \ libc6-dev-sparc64-cross diff --git a/tests/docker/dockerfiles/debian-toolchain.docker b/tests/docker/dockerfiles/debian-toolchain.docker index 738d808..d3d4d33 100644 --- a/tests/docker/dockerfiles/debian-toolchain.docker +++ b/tests/docker/dockerfiles/debian-toolchain.docker @@ -4,7 +4,7 @@ # This dockerfile is used for building a cross-compiler toolchain. # The script for building the toolchain is supplied via extra-files. # -FROM qemu/debian10 +FROM docker.io/library/debian:11-slim # Install build utilities for building gcc and glibc. # ??? The build-dep isn't working, missing a number of @@ -15,6 +15,7 @@ RUN apt update && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ bison \ + ca-certificates \ flex \ gawk \ libmpc-dev \ @@ -32,5 +33,5 @@ RUN cd /root && ./build-toolchain.sh # Throw away the extra toolchain build deps, the downloaded source, # and the build trees by restoring the original debian10 image, # then copying the built toolchain from stage 0. -FROM qemu/debian10 +FROM docker.io/library/debian:bullseye-slim COPY --from=0 /usr/local /usr/local diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker deleted file mode 100644 index 03be923..0000000 --- a/tests/docker/dockerfiles/debian10.docker +++ /dev/null @@ -1,38 +0,0 @@ -# -# Docker multiarch cross-compiler target -# -# This docker target is builds on Debian cross compiler targets to build distro -# with a selection of cross compilers for building test binaries. -# -# On its own you can't build much but the docker-foo-cross targets -# build on top of the base debian image. -# -FROM docker.io/library/debian:buster-slim - -# Duplicate deb line as deb-src -RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list - -# Install common build utilities -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt install -y --no-install-recommends \ - bc \ - build-essential \ - ca-certificates \ - ccache \ - clang \ - dbus \ - gdb-multiarch \ - gettext \ - git \ - libffi-dev \ - libncurses5-dev \ - ninja-build \ - pkg-config \ - psmisc \ - python3 \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - $(apt-get -s build-dep --arch-only qemu | egrep ^Inst | fgrep '[all]' | cut -d\ -f2) diff --git a/tests/docker/dockerfiles/debian11.docker b/tests/docker/dockerfiles/debian11.docker deleted file mode 100644 index febf884..0000000 --- a/tests/docker/dockerfiles/debian11.docker +++ /dev/null @@ -1,18 +0,0 @@ -# -# Docker multiarch cross-compiler target -# -# This docker target uses the current development version of Debian as -# a base for cross compilers for building test binaries. We won't -# attempt to build QEMU on it yet given it is still in development. -# -# On its own you can't build much but the docker-foo-cross targets -# build on top of the base debian image. -# -FROM docker.io/library/debian:bullseye-slim - -# Duplicate deb line as deb-src -RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.list - -# Install common build utilities -RUN apt update && \ - DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker index 047a435..041cf9c 100644 --- a/tests/docker/dockerfiles/opensuse-leap.docker +++ b/tests/docker/dockerfiles/opensuse-leap.docker @@ -66,6 +66,7 @@ RUN zypper update -y && \ librbd-devel \ libseccomp-devel \ libselinux-devel \ + libslirp-devel \ libspice-server-devel \ libssh-devel \ libtasn1-devel \ @@ -127,7 +128,7 @@ RUN zypper update -y && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc -RUN pip3 install meson==0.56.0 +RUN /usr/bin/pip3 install meson==0.56.0 ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index 99803b3..e1f4ed7 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -137,7 +137,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc -RUN pip3 install meson==0.56.0 +RUN /usr/bin/pip3 install meson==0.56.0 ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci -Subproject 324355cf62e86fb551408575afb123bac989ac3 +Subproject e3712b79122180fdb3b7a7ea8cbee47ece253f9 diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh index 2a59150..fc604d8 100755 --- a/tests/lcitool/refresh +++ b/tests/lcitool/refresh @@ -119,6 +119,13 @@ try: # # Cross compiling builds # + generate_dockerfile("debian-amd64-cross", "debian-11", + cross="x86_64", + trailer=debian_cross_build("x86_64-linux-gnu-", + "x86_64-softmmu," + "x86_64-linux-user," + "i386-softmmu,i386-linux-user")) + generate_dockerfile("debian-arm64-cross", "debian-11", cross="aarch64", trailer=debian_cross_build("aarch64-linux-gnu-", diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index 3678396..46a46fe 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1671,7 +1671,7 @@ static void test_oem_fields(test_data *data) } } -static void test_acpi_oem_fields_pc(void) +static void test_acpi_piix4_oem_fields(void) { test_data data; char *args; @@ -1691,7 +1691,7 @@ static void test_acpi_oem_fields_pc(void) g_free(args); } -static void test_acpi_oem_fields_q35(void) +static void test_acpi_q35_oem_fields(void) { test_data data; char *args; @@ -1711,7 +1711,7 @@ static void test_acpi_oem_fields_q35(void) g_free(args); } -static void test_acpi_oem_fields_microvm(void) +static void test_acpi_microvm_oem_fields(void) { test_data data; char *args; @@ -1728,7 +1728,7 @@ static void test_acpi_oem_fields_microvm(void) g_free(args); } -static void test_acpi_oem_fields_virt(void) +static void test_acpi_virt_oem_fields(void) { test_data data = { .machine = "virt", @@ -1766,85 +1766,102 @@ int main(int argc, char *argv[]) if (ret) { return ret; } - qtest_add_func("acpi/q35/oem-fields", test_acpi_oem_fields_q35); - if (tpm_model_is_available("-machine q35", "tpm-tis")) { - qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis); - qtest_add_func("acpi/q35/tpm12-tis", test_acpi_q35_tcg_tpm12_tis); - } - qtest_add_func("acpi/piix4", test_acpi_piix4_tcg); - qtest_add_func("acpi/oem-fields", test_acpi_oem_fields_pc); - qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge); - qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug", - test_acpi_piix4_no_root_hotplug); - qtest_add_func("acpi/piix4/pci-hotplug/no_bridge_hotplug", - test_acpi_piix4_no_bridge_hotplug); - qtest_add_func("acpi/piix4/pci-hotplug/off", - test_acpi_piix4_no_acpi_pci_hotplug); - qtest_add_func("acpi/q35", test_acpi_q35_tcg); - qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge); - qtest_add_func("acpi/q35/multif-bridge", test_acpi_q35_multif_bridge); - qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64); - qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi); - qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi); - qtest_add_func("acpi/q35/smbus/ipmi", test_acpi_q35_tcg_smbus_ipmi); - qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp); - qtest_add_func("acpi/q35/cpuhp", test_acpi_q35_tcg_cphp); - qtest_add_func("acpi/piix4/memhp", test_acpi_piix4_tcg_memhp); - qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp); - qtest_add_func("acpi/piix4/numamem", test_acpi_piix4_tcg_numamem); - qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem); - qtest_add_func("acpi/piix4/nosmm", test_acpi_piix4_tcg_nosmm); - qtest_add_func("acpi/piix4/smm-compat", - test_acpi_piix4_tcg_smm_compat); - qtest_add_func("acpi/piix4/smm-compat-nosmm", - test_acpi_piix4_tcg_smm_compat_nosmm); - qtest_add_func("acpi/piix4/nohpet", test_acpi_piix4_tcg_nohpet); - qtest_add_func("acpi/q35/nosmm", test_acpi_q35_tcg_nosmm); - qtest_add_func("acpi/q35/smm-compat", - test_acpi_q35_tcg_smm_compat); - qtest_add_func("acpi/q35/smm-compat-nosmm", - test_acpi_q35_tcg_smm_compat_nosmm); - qtest_add_func("acpi/q35/nohpet", test_acpi_q35_tcg_nohpet); - qtest_add_func("acpi/piix4/dimmpxm", test_acpi_piix4_tcg_dimm_pxm); - qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); - qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat); - qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat); + if (qtest_has_machine(MACHINE_PC)) { + qtest_add_func("acpi/piix4", test_acpi_piix4_tcg); + qtest_add_func("acpi/piix4/oem-fields", test_acpi_piix4_oem_fields); + qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge); + qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug", + test_acpi_piix4_no_root_hotplug); + qtest_add_func("acpi/piix4/pci-hotplug/no_bridge_hotplug", + test_acpi_piix4_no_bridge_hotplug); + qtest_add_func("acpi/piix4/pci-hotplug/off", + test_acpi_piix4_no_acpi_pci_hotplug); + qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi); + qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp); + qtest_add_func("acpi/piix4/memhp", test_acpi_piix4_tcg_memhp); + qtest_add_func("acpi/piix4/numamem", test_acpi_piix4_tcg_numamem); + qtest_add_func("acpi/piix4/nosmm", test_acpi_piix4_tcg_nosmm); + qtest_add_func("acpi/piix4/smm-compat", + test_acpi_piix4_tcg_smm_compat); + qtest_add_func("acpi/piix4/smm-compat-nosmm", + test_acpi_piix4_tcg_smm_compat_nosmm); + qtest_add_func("acpi/piix4/nohpet", test_acpi_piix4_tcg_nohpet); + qtest_add_func("acpi/piix4/dimmpxm", test_acpi_piix4_tcg_dimm_pxm); + qtest_add_func("acpi/piix4/acpihmat", + test_acpi_piix4_tcg_acpi_hmat); #ifdef CONFIG_POSIX - qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst); - qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst); + qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst); #endif - qtest_add_func("acpi/q35/applesmc", test_acpi_q35_applesmc); - qtest_add_func("acpi/q35/pvpanic-isa", test_acpi_q35_pvpanic_isa); - qtest_add_func("acpi/microvm", test_acpi_microvm_tcg); - qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg); - qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg); - qtest_add_func("acpi/microvm/ioapic2", test_acpi_microvm_ioapic2_tcg); - qtest_add_func("acpi/microvm/oem-fields", test_acpi_oem_fields_microvm); - if (has_tcg) { - qtest_add_func("acpi/q35/ivrs", test_acpi_q35_tcg_ivrs); - if (strcmp(arch, "x86_64") == 0) { - qtest_add_func("acpi/microvm/pcie", test_acpi_microvm_pcie_tcg); + } + if (qtest_has_machine(MACHINE_Q35)) { + qtest_add_func("acpi/q35", test_acpi_q35_tcg); + qtest_add_func("acpi/q35/oem-fields", test_acpi_q35_oem_fields); + if (tpm_model_is_available("-machine q35", "tpm-tis")) { + qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis); + qtest_add_func("acpi/q35/tpm12-tis", + test_acpi_q35_tcg_tpm12_tis); + } + qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge); + qtest_add_func("acpi/q35/multif-bridge", + test_acpi_q35_multif_bridge); + qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64); + qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi); + qtest_add_func("acpi/q35/smbus/ipmi", test_acpi_q35_tcg_smbus_ipmi); + qtest_add_func("acpi/q35/cpuhp", test_acpi_q35_tcg_cphp); + qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp); + qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem); + qtest_add_func("acpi/q35/nosmm", test_acpi_q35_tcg_nosmm); + qtest_add_func("acpi/q35/smm-compat", + test_acpi_q35_tcg_smm_compat); + qtest_add_func("acpi/q35/smm-compat-nosmm", + test_acpi_q35_tcg_smm_compat_nosmm); + qtest_add_func("acpi/q35/nohpet", test_acpi_q35_tcg_nohpet); + qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); + qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat); #ifdef CONFIG_POSIX - qtest_add_func("acpi/microvm/acpierst", test_acpi_microvm_acpi_erst); + qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst); #endif + qtest_add_func("acpi/q35/applesmc", test_acpi_q35_applesmc); + qtest_add_func("acpi/q35/pvpanic-isa", test_acpi_q35_pvpanic_isa); + if (has_tcg) { + qtest_add_func("acpi/q35/ivrs", test_acpi_q35_tcg_ivrs); } + if (has_kvm) { + qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); + qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); + } + qtest_add_func("acpi/q35/viot", test_acpi_q35_viot); +#ifdef CONFIG_POSIX + qtest_add_func("acpi/q35/cxl", test_acpi_q35_cxl); +#endif + qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); } - if (has_kvm) { - qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); - qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); - } - qtest_add_func("acpi/q35/viot", test_acpi_q35_viot); + if (qtest_has_machine("microvm")) { + qtest_add_func("acpi/microvm", test_acpi_microvm_tcg); + qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg); + qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg); + qtest_add_func("acpi/microvm/ioapic2", + test_acpi_microvm_ioapic2_tcg); + qtest_add_func("acpi/microvm/oem-fields", + test_acpi_microvm_oem_fields); + if (has_tcg) { + if (strcmp(arch, "x86_64") == 0) { + qtest_add_func("acpi/microvm/pcie", + test_acpi_microvm_pcie_tcg); #ifdef CONFIG_POSIX - qtest_add_func("acpi/q35/cxl", test_acpi_q35_cxl); + qtest_add_func("acpi/microvm/acpierst", + test_acpi_microvm_acpi_erst); #endif - qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); + } + } + } } else if (strcmp(arch, "aarch64") == 0) { if (has_tcg) { qtest_add_func("acpi/virt", test_acpi_virt_tcg); qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp); qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb); - qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt); + qtest_add_func("acpi/virt/oem-fields", test_acpi_virt_oem_fields); qtest_add_func("acpi/virt/viot", test_acpi_virt_viot); } } diff --git a/tests/qtest/e1000-test.c b/tests/qtest/e1000-test.c index c387984..4e0d7a5 100644 --- a/tests/qtest/e1000-test.c +++ b/tests/qtest/e1000-test.c @@ -35,7 +35,7 @@ static void *e1000_get_driver(void *obj, const char *interface) return &e1000->dev; } - fprintf(stderr, "%s not present in e1000e\n", interface); + fprintf(stderr, "%s not present in e1000\n", interface); g_assert_not_reached(); } diff --git a/tests/qtest/es1370-test.c b/tests/qtest/es1370-test.c index adccdac..97ab65c 100644 --- a/tests/qtest/es1370-test.c +++ b/tests/qtest/es1370-test.c @@ -28,7 +28,7 @@ static void *es1370_get_driver(void *obj, const char *interface) return &es1370->dev; } - fprintf(stderr, "%s not present in e1000e\n", interface); + fprintf(stderr, "%s not present in es1370\n", interface); g_assert_not_reached(); } diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c index b23d3ec..434c16b 100644 --- a/tests/qtest/fuzz-lsi53c895a-test.c +++ b/tests/qtest/fuzz-lsi53c895a-test.c @@ -21,7 +21,7 @@ static void test_lsi_do_msgout_cancel_req(void) return; } - s = qtest_init("-M q35 -m 4G -display none -nodefaults " + s = qtest_init("-M q35 -m 2G -display none -nodefaults " "-device lsi53c895a,id=scsi " "-device scsi-hd,drive=disk0 " "-drive file=null-co://,id=disk0,if=none,format=raw"); diff --git a/tests/qtest/fuzz-sb16-test.c b/tests/qtest/fuzz-sb16-test.c index a65826b..add2a2a 100644 --- a/tests/qtest/fuzz-sb16-test.c +++ b/tests/qtest/fuzz-sb16-test.c @@ -57,9 +57,13 @@ int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); - qtest_add_func("fuzz/test_fuzz_sb16/1c", test_fuzz_sb16_0x1c); - qtest_add_func("fuzz/test_fuzz_sb16/91", test_fuzz_sb16_0x91); - qtest_add_func("fuzz/test_fuzz_sb16/d4", test_fuzz_sb16_0xd4); + if (qtest_has_machine("q35")) { + qtest_add_func("fuzz/test_fuzz_sb16/1c", test_fuzz_sb16_0x1c); + } + if (qtest_has_machine("pc")) { + qtest_add_func("fuzz/test_fuzz_sb16/91", test_fuzz_sb16_0x91); + qtest_add_func("fuzz/test_fuzz_sb16/d4", test_fuzz_sb16_0xd4); + } return g_test_run(); } diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c index a58c98e..d4a8db6 100644 --- a/tests/qtest/intel-hda-test.c +++ b/tests/qtest/intel-hda-test.c @@ -18,7 +18,7 @@ /* Tests only initialization so far. TODO: Replace with functional tests */ static void ich6_test(void) { - qtest_start("-device intel-hda,id=" HDA_ID CODEC_DEVICES); + qtest_start("-machine pc -device intel-hda,id=" HDA_ID CODEC_DEVICES); qtest_end(); } @@ -65,9 +65,12 @@ static void test_issue542_ich6(void) int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); - qtest_add_func("/intel-hda/ich6", ich6_test); - qtest_add_func("/intel-hda/ich9", ich9_test); - qtest_add_func("/intel-hda/fuzz/issue542", test_issue542_ich6); - + if (qtest_has_machine("pc")) { + qtest_add_func("/intel-hda/ich6", ich6_test); + } + if (qtest_has_machine("q35")) { + qtest_add_func("/intel-hda/ich9", ich9_test); + qtest_add_func("/intel-hda/fuzz/issue542", test_issue542_ich6); + } return g_test_run(); } diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c index c373d24..b046f1d 100644 --- a/tests/qtest/npcm7xx_emc-test.c +++ b/tests/qtest/npcm7xx_emc-test.c @@ -381,7 +381,8 @@ static void test_init(gconstpointer test_data) #undef CHECK_REG - for (i = 0; i < NUM_CAMML_REGS; ++i) { + /* Skip over the MAC address registers, which is BASE+0 */ + for (i = 1; i < NUM_CAMML_REGS; ++i) { g_assert_cmpuint(emc_read(qts, mod, REG_CAMM_BASE + i * 2), ==, 0); g_assert_cmpuint(emc_read(qts, mod, REG_CAML_BASE + i * 2), ==, diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target index be21b81..599f192 100644 --- a/tests/tcg/i386/Makefile.target +++ b/tests/tcg/i386/Makefile.target @@ -7,8 +7,8 @@ VPATH += $(I386_SRC) I386_SRCS=$(notdir $(wildcard $(I386_SRC)/*.c)) ALL_X86_TESTS=$(I386_SRCS:.c=) -SKIP_I386_TESTS=test-i386-ssse3 test-avx -X86_64_TESTS:=$(filter test-i386-bmi2 test-i386-ssse3 test-avx, $(ALL_X86_TESTS)) +SKIP_I386_TESTS=test-i386-ssse3 test-avx test-3dnow test-mmx +X86_64_TESTS:=$(filter test-i386-bmi2 $(SKIP_I386_TESTS), $(ALL_X86_TESTS)) test-i386-sse-exceptions: CFLAGS += -msse4.1 -mfpmath=sse run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max @@ -82,9 +82,27 @@ run-plugin-sha512-sse-with-%: QEMU_OPTS+=-cpu max TESTS+=sha512-sse -CLEANFILES += test-avx.h +CLEANFILES += test-avx.h test-mmx.h test-3dnow.h +test-3dnow.h: test-mmx.py x86.csv + $(PYTHON) $(I386_SRC)/test-mmx.py $(I386_SRC)/x86.csv $@ 3DNOW + +test-mmx.h: test-mmx.py x86.csv + $(PYTHON) $(I386_SRC)/test-mmx.py $(I386_SRC)/x86.csv $@ MMX SSE SSE2 SSE3 SSSE3 + test-avx.h: test-avx.py x86.csv $(PYTHON) $(I386_SRC)/test-avx.py $(I386_SRC)/x86.csv $@ +test-3dnow: CFLAGS += -masm=intel -O -I. +run-test-3dnow: QEMU_OPTS += -cpu max +run-plugin-test-3dnow: QEMU_OPTS += -cpu max +test-3dnow: test-3dnow.h + +test-mmx: CFLAGS += -masm=intel -O -I. +run-test-mmx: QEMU_OPTS += -cpu max +run-plugin-test-mmx: QEMU_OPTS += -cpu max +test-mmx: test-mmx.h + test-avx: CFLAGS += -masm=intel -O -I. +run-test-avx: QEMU_OPTS += -cpu max +run-plugin-test-avx: QEMU_OPTS += -cpu max test-avx: test-avx.h diff --git a/tests/tcg/i386/test-3dnow.c b/tests/tcg/i386/test-3dnow.c new file mode 100644 index 0000000..67abc68 --- /dev/null +++ b/tests/tcg/i386/test-3dnow.c @@ -0,0 +1,3 @@ +#define EMMS "femms" +#define TEST_FILE "test-3dnow.h" +#include "test-mmx.c" diff --git a/tests/tcg/i386/test-avx.py b/tests/tcg/i386/test-avx.py index 6eb455a..e16a3d8 100755 --- a/tests/tcg/i386/test-avx.py +++ b/tests/tcg/i386/test-avx.py @@ -7,7 +7,6 @@ import sys from fnmatch import fnmatch archs = [ - # TODO: MMX? "SSE", "SSE2", "SSE3", "SSSE3", "SSE4_1", "SSE4_2", ] @@ -104,7 +103,11 @@ class XMMArg(): class MMArg(): isxmm = True - ismem = False # TODO + def __init__(self, mw): + if mw not in [0, 32, 64]: + raise Exception("Bad mem width: %s" % mw) + self.mw = mw + self.ismem = mw != 0 def regstr(self, n): return "mm%d" % (n & 7) @@ -170,6 +173,9 @@ class ArgMem(): def regstr(self, n): return mem_w(self.w) +class SkipInstruction(Exception): + pass + def ArgGenerator(arg, op): if arg[:3] == 'xmm' or arg[:3] == "ymm": if "/" in arg: @@ -180,7 +186,13 @@ def ArgGenerator(arg, op): else: return XMMArg(arg[0], 0); elif arg[:2] == 'mm': - return MMArg(); + if "/" in arg: + r, m = arg.split('/') + if (m[0] != 'm'): + raise Exception("Expected /m: %s", arg) + return MMArg(int(m[1:])); + else: + return MMArg(0); elif arg[:4] == 'imm8': return ArgImm8u(op); elif arg == '<XMM0>': @@ -218,8 +230,12 @@ class InsnGenerator: try: self.args = list(ArgGenerator(a, op) for a in args) + if not any((x.isxmm for x in self.args)): + raise SkipInstruction if len(self.args) > 0 and self.args[-1] is None: self.args = self.args[:-1] + except SkipInstruction: + raise except Exception as e: raise Exception("Bad arg %s: %s" % (op, e)) @@ -340,10 +356,13 @@ def main(): continue cpuid = row[6] if cpuid in archs: - g = InsnGenerator(insn[0], insn[1:]) - for insn in g.gen(): - outf.write('TEST(%d, "%s", %s)\n' % (n, insn, g.optype)) - n += 1 + try: + g = InsnGenerator(insn[0], insn[1:]) + for insn in g.gen(): + outf.write('TEST(%d, "%s", %s)\n' % (n, insn, g.optype)) + n += 1 + except SkipInstruction: + pass outf.write("#undef TEST\n") csvfile.close() diff --git a/tests/tcg/i386/test-i386.c b/tests/tcg/i386/test-i386.c index e6b308a..864c4e6 100644 --- a/tests/tcg/i386/test-i386.c +++ b/tests/tcg/i386/test-i386.c @@ -34,15 +34,8 @@ #endif //#define LINUX_VM86_IOPL_FIX //#define TEST_P4_FLAGS -#ifdef __SSE__ -#define TEST_SSE #define TEST_CMOV 1 #define TEST_FCOMI 1 -#else -#undef TEST_SSE -#define TEST_CMOV 1 -#define TEST_FCOMI 1 -#endif #if defined(__x86_64__) #define FMT64X "%016lx" @@ -2104,568 +2097,6 @@ static void test_enter(void) TEST_ENTER("w", uint16_t, 31); } -#ifdef TEST_SSE - -typedef int __m64 __attribute__ ((vector_size(8))); -typedef float __m128 __attribute__ ((vector_size(16))); - -typedef union { - double d[2]; - float s[4]; - uint32_t l[4]; - uint64_t q[2]; - __m128 dq; -} XMMReg; - -static uint64_t __attribute__((aligned(16))) test_values[4][2] = { - { 0x456723c698694873, 0xdc515cff944a58ec }, - { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 }, - { 0x007c62c2085427f8, 0x231be9e8cde7438d }, - { 0x0f76255a085427f8, 0xc233e9e8c4c9439a }, -}; - -#define SSE_OP(op)\ -{\ - asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - b.q[1], b.q[0],\ - r.q[1], r.q[0]);\ -} - -#define SSE_OP2(op)\ -{\ - int i;\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - a.q[1] = test_values[2*i][1];\ - b.q[0] = test_values[2*i+1][0];\ - b.q[1] = test_values[2*i+1][1];\ - SSE_OP(op);\ - }\ -} - -#define MMX_OP2(op)\ -{\ - int i;\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - b.q[0] = test_values[2*i+1][0];\ - asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\ - printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\ - #op,\ - a.q[0],\ - b.q[0],\ - r.q[0]);\ - }\ - SSE_OP2(op);\ -} - -#define SHUF_OP(op, ib)\ -{\ - a.q[0] = test_values[0][0];\ - a.q[1] = test_values[0][1];\ - b.q[0] = test_values[1][0];\ - b.q[1] = test_values[1][1];\ - asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - b.q[1], b.q[0],\ - ib,\ - r.q[1], r.q[0]);\ -} - -#define PSHUF_OP(op, ib)\ -{\ - int i;\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - a.q[1] = test_values[2*i][1];\ - asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - ib,\ - r.q[1], r.q[0]);\ - }\ -} - -#define SHIFT_IM(op, ib)\ -{\ - int i;\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - a.q[1] = test_values[2*i][1];\ - asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - ib,\ - r.q[1], r.q[0]);\ - }\ -} - -#define SHIFT_OP(op, ib)\ -{\ - int i;\ - SHIFT_IM(op, ib);\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - a.q[1] = test_values[2*i][1];\ - b.q[0] = ib;\ - b.q[1] = 0;\ - asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - b.q[1], b.q[0],\ - r.q[1], r.q[0]);\ - }\ -} - -#define MOVMSK(op)\ -{\ - int i, reg;\ - for(i=0;i<2;i++) {\ - a.q[0] = test_values[2*i][0];\ - a.q[1] = test_values[2*i][1];\ - asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ - #op,\ - a.q[1], a.q[0],\ - reg);\ - }\ -} - -#define SSE_OPS(a) \ -SSE_OP(a ## ps);\ -SSE_OP(a ## ss); - -#define SSE_OPD(a) \ -SSE_OP(a ## pd);\ -SSE_OP(a ## sd); - -#define SSE_COMI(op, field)\ -{\ - unsigned long eflags;\ - XMMReg a, b;\ - a.field[0] = a1;\ - b.field[0] = b1;\ - asm volatile (#op " %2, %1\n"\ - "pushf\n"\ - "pop %0\n"\ - : "=rm" (eflags)\ - : "x" (a.dq), "x" (b.dq));\ - printf("%-9s: a=%f b=%f cc=%04lx\n",\ - #op, a1, b1,\ - eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\ -} - -void test_sse_comi(double a1, double b1) -{ - SSE_COMI(ucomiss, s); - SSE_COMI(ucomisd, d); - SSE_COMI(comiss, s); - SSE_COMI(comisd, d); -} - -#define CVT_OP_XMM(op)\ -{\ - asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - r.q[1], r.q[0]);\ -} - -/* Force %xmm0 usage to avoid the case where both register index are 0 - to test instruction decoding more extensively */ -#define CVT_OP_XMM2MMX(op)\ -{\ - asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \ - : "%xmm0"); \ - asm volatile("emms\n"); \ - printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\ - #op,\ - a.q[1], a.q[0],\ - r.q[0]);\ -} - -#define CVT_OP_MMX2XMM(op)\ -{\ - asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\ - asm volatile("emms\n"); \ - printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.q[0],\ - r.q[1], r.q[0]);\ -} - -#define CVT_OP_REG2XMM(op)\ -{\ - asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\ - printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\ - #op,\ - a.l[0],\ - r.q[1], r.q[0]);\ -} - -#define CVT_OP_XMM2REG(op)\ -{\ - asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\ - printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\ - #op,\ - a.q[1], a.q[0],\ - r.l[0]);\ -} - -struct fpxstate { - uint16_t fpuc; - uint16_t fpus; - uint16_t fptag; - uint16_t fop; - uint32_t fpuip; - uint16_t cs_sel; - uint16_t dummy0; - uint32_t fpudp; - uint16_t ds_sel; - uint16_t dummy1; - uint32_t mxcsr; - uint32_t mxcsr_mask; - uint8_t fpregs1[8 * 16]; - uint8_t xmm_regs[8 * 16]; - uint8_t dummy2[224]; -}; - -static struct fpxstate fpx_state __attribute__((aligned(16))); -static struct fpxstate fpx_state2 __attribute__((aligned(16))); - -void test_fxsave(void) -{ - struct fpxstate *fp = &fpx_state; - struct fpxstate *fp2 = &fpx_state2; - int i, nb_xmm; - XMMReg a, b; - a.q[0] = test_values[0][0]; - a.q[1] = test_values[0][1]; - b.q[0] = test_values[1][0]; - b.q[1] = test_values[1][1]; - - asm("movdqa %2, %%xmm0\n" - "movdqa %3, %%xmm7\n" -#if defined(__x86_64__) - "movdqa %2, %%xmm15\n" -#endif - " fld1\n" - " fldpi\n" - " fldln2\n" - " fxsave %0\n" - " fxrstor %0\n" - " fxsave %1\n" - " fninit\n" - : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp) - : "m" (a), "m" (b)); - printf("fpuc=%04x\n", fp->fpuc); - printf("fpus=%04x\n", fp->fpus); - printf("fptag=%04x\n", fp->fptag); - for(i = 0; i < 3; i++) { - printf("ST%d: " FMT64X " %04x\n", - i, - *(uint64_t *)&fp->fpregs1[i * 16], - *(uint16_t *)&fp->fpregs1[i * 16 + 8]); - } - printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80); -#if defined(__x86_64__) - nb_xmm = 16; -#else - nb_xmm = 8; -#endif - for(i = 0; i < nb_xmm; i++) { - printf("xmm%d: " FMT64X "" FMT64X "\n", - i, - *(uint64_t *)&fp->xmm_regs[i * 16], - *(uint64_t *)&fp->xmm_regs[i * 16 + 8]); - } -} - -void test_sse(void) -{ - XMMReg r, a, b; - int i; - - MMX_OP2(punpcklbw); - MMX_OP2(punpcklwd); - MMX_OP2(punpckldq); - MMX_OP2(packsswb); - MMX_OP2(pcmpgtb); - MMX_OP2(pcmpgtw); - MMX_OP2(pcmpgtd); - MMX_OP2(packuswb); - MMX_OP2(punpckhbw); - MMX_OP2(punpckhwd); - MMX_OP2(punpckhdq); - MMX_OP2(packssdw); - MMX_OP2(pcmpeqb); - MMX_OP2(pcmpeqw); - MMX_OP2(pcmpeqd); - - MMX_OP2(paddq); - MMX_OP2(pmullw); - MMX_OP2(psubusb); - MMX_OP2(psubusw); - MMX_OP2(pminub); - MMX_OP2(pand); - MMX_OP2(paddusb); - MMX_OP2(paddusw); - MMX_OP2(pmaxub); - MMX_OP2(pandn); - - MMX_OP2(pmulhuw); - MMX_OP2(pmulhw); - - MMX_OP2(psubsb); - MMX_OP2(psubsw); - MMX_OP2(pminsw); - MMX_OP2(por); - MMX_OP2(paddsb); - MMX_OP2(paddsw); - MMX_OP2(pmaxsw); - MMX_OP2(pxor); - MMX_OP2(pmuludq); - MMX_OP2(pmaddwd); - MMX_OP2(psadbw); - MMX_OP2(psubb); - MMX_OP2(psubw); - MMX_OP2(psubd); - MMX_OP2(psubq); - MMX_OP2(paddb); - MMX_OP2(paddw); - MMX_OP2(paddd); - - MMX_OP2(pavgb); - MMX_OP2(pavgw); - - asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678)); - printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]); - - asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678)); - printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]); - - a.q[0] = test_values[0][0]; - a.q[1] = test_values[0][1]; - asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0])); - printf("%-9s: r=%08x\n", "pextrw", r.l[0]); - - asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq)); - printf("%-9s: r=%08x\n", "pextrw", r.l[0]); - - asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0])); - printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]); - - asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq)); - printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]); - - { - r.q[0] = -1; - r.q[1] = -1; - - a.q[0] = test_values[0][0]; - a.q[1] = test_values[0][1]; - b.q[0] = test_values[1][0]; - b.q[1] = test_values[1][1]; - asm volatile("maskmovq %1, %0" : - : "y" (a.q[0]), "y" (b.q[0]), "D" (&r) - : "memory"); - printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n", - "maskmov", - r.q[0], - a.q[0], - b.q[0]); - asm volatile("maskmovdqu %1, %0" : - : "x" (a.dq), "x" (b.dq), "D" (&r) - : "memory"); - printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n", - "maskmov", - r.q[1], r.q[0], - a.q[1], a.q[0], - b.q[1], b.q[0]); - } - - asm volatile ("emms"); - - SSE_OP2(punpcklqdq); - SSE_OP2(punpckhqdq); - SSE_OP2(andps); - SSE_OP2(andpd); - SSE_OP2(andnps); - SSE_OP2(andnpd); - SSE_OP2(orps); - SSE_OP2(orpd); - SSE_OP2(xorps); - SSE_OP2(xorpd); - - SSE_OP2(unpcklps); - SSE_OP2(unpcklpd); - SSE_OP2(unpckhps); - SSE_OP2(unpckhpd); - - SHUF_OP(shufps, 0x78); - SHUF_OP(shufpd, 0x02); - - PSHUF_OP(pshufd, 0x78); - PSHUF_OP(pshuflw, 0x78); - PSHUF_OP(pshufhw, 0x78); - - SHIFT_OP(psrlw, 7); - SHIFT_OP(psrlw, 16); - SHIFT_OP(psraw, 7); - SHIFT_OP(psraw, 16); - SHIFT_OP(psllw, 7); - SHIFT_OP(psllw, 16); - - SHIFT_OP(psrld, 7); - SHIFT_OP(psrld, 32); - SHIFT_OP(psrad, 7); - SHIFT_OP(psrad, 32); - SHIFT_OP(pslld, 7); - SHIFT_OP(pslld, 32); - - SHIFT_OP(psrlq, 7); - SHIFT_OP(psrlq, 32); - SHIFT_OP(psllq, 7); - SHIFT_OP(psllq, 32); - - SHIFT_IM(psrldq, 16); - SHIFT_IM(psrldq, 7); - SHIFT_IM(pslldq, 16); - SHIFT_IM(pslldq, 7); - - MOVMSK(movmskps); - MOVMSK(movmskpd); - - /* FPU specific ops */ - - { - uint32_t mxcsr; - asm volatile("stmxcsr %0" : "=m" (mxcsr)); - printf("mxcsr=%08x\n", mxcsr & 0x1f80); - asm volatile("ldmxcsr %0" : : "m" (mxcsr)); - } - - test_sse_comi(2, -1); - test_sse_comi(2, 2); - test_sse_comi(2, 3); - test_sse_comi(2, q_nan.d); - test_sse_comi(q_nan.d, -1); - - for(i = 0; i < 2; i++) { - a.s[0] = 2.7; - a.s[1] = 3.4; - a.s[2] = 4; - a.s[3] = -6.3; - b.s[0] = 45.7; - b.s[1] = 353.4; - b.s[2] = 4; - b.s[3] = 56.3; - if (i == 1) { - a.s[0] = q_nan.d; - b.s[3] = q_nan.d; - } - - SSE_OPS(add); - SSE_OPS(mul); - SSE_OPS(sub); - SSE_OPS(min); - SSE_OPS(div); - SSE_OPS(max); - SSE_OPS(sqrt); - SSE_OPS(cmpeq); - SSE_OPS(cmplt); - SSE_OPS(cmple); - SSE_OPS(cmpunord); - SSE_OPS(cmpneq); - SSE_OPS(cmpnlt); - SSE_OPS(cmpnle); - SSE_OPS(cmpord); - - - a.d[0] = 2.7; - a.d[1] = -3.4; - b.d[0] = 45.7; - b.d[1] = -53.4; - if (i == 1) { - a.d[0] = q_nan.d; - b.d[1] = q_nan.d; - } - SSE_OPD(add); - SSE_OPD(mul); - SSE_OPD(sub); - SSE_OPD(min); - SSE_OPD(div); - SSE_OPD(max); - SSE_OPD(sqrt); - SSE_OPD(cmpeq); - SSE_OPD(cmplt); - SSE_OPD(cmple); - SSE_OPD(cmpunord); - SSE_OPD(cmpneq); - SSE_OPD(cmpnlt); - SSE_OPD(cmpnle); - SSE_OPD(cmpord); - } - - /* float to float/int */ - a.s[0] = 2.7; - a.s[1] = 3.4; - a.s[2] = 4; - a.s[3] = -6.3; - CVT_OP_XMM(cvtps2pd); - CVT_OP_XMM(cvtss2sd); - CVT_OP_XMM2MMX(cvtps2pi); - CVT_OP_XMM2MMX(cvttps2pi); - CVT_OP_XMM2REG(cvtss2si); - CVT_OP_XMM2REG(cvttss2si); - CVT_OP_XMM(cvtps2dq); - CVT_OP_XMM(cvttps2dq); - - a.d[0] = 2.6; - a.d[1] = -3.4; - CVT_OP_XMM(cvtpd2ps); - CVT_OP_XMM(cvtsd2ss); - CVT_OP_XMM2MMX(cvtpd2pi); - CVT_OP_XMM2MMX(cvttpd2pi); - CVT_OP_XMM2REG(cvtsd2si); - CVT_OP_XMM2REG(cvttsd2si); - CVT_OP_XMM(cvtpd2dq); - CVT_OP_XMM(cvttpd2dq); - - /* sse/mmx moves */ - CVT_OP_XMM2MMX(movdq2q); - CVT_OP_MMX2XMM(movq2dq); - - /* int to float */ - a.l[0] = -6; - a.l[1] = 2; - a.l[2] = 100; - a.l[3] = -60000; - CVT_OP_MMX2XMM(cvtpi2ps); - CVT_OP_MMX2XMM(cvtpi2pd); - CVT_OP_REG2XMM(cvtsi2ss); - CVT_OP_REG2XMM(cvtsi2sd); - CVT_OP_XMM(cvtdq2ps); - CVT_OP_XMM(cvtdq2pd); - - /* XXX: test PNI insns */ -#if 0 - SSE_OP2(movshdup); -#endif - asm volatile ("emms"); -} - -#endif - #define TEST_CONV_RAX(op)\ {\ unsigned long a, r;\ @@ -2756,9 +2187,5 @@ int main(int argc, char **argv) #endif test_enter(); test_conv(); -#ifdef TEST_SSE - test_sse(); - test_fxsave(); -#endif return 0; } diff --git a/tests/tcg/i386/test-mmx.c b/tests/tcg/i386/test-mmx.c new file mode 100644 index 0000000..09e5d58 --- /dev/null +++ b/tests/tcg/i386/test-mmx.c @@ -0,0 +1,315 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#ifndef TEST_FILE +#define TEST_FILE "test-mmx.h" +#endif +#ifndef EMMS +#define EMMS "emms" +#endif + +typedef void (*testfn)(void); + +typedef struct { + uint64_t q0, q1; +} __attribute__((aligned(16))) v2di; + +typedef struct { + uint64_t mm[8]; + v2di xmm[8]; + uint64_t r[16]; + uint64_t flags; + uint32_t ff; + uint64_t pad; + v2di mem[4]; + v2di mem0[4]; +} reg_state; + +typedef struct { + int n; + testfn fn; + const char *s; + reg_state *init; +} TestDef; + +reg_state initI; +reg_state initF32; +reg_state initF64; + +static void dump_mmx(int n, const uint64_t *r, int ff) +{ + if (ff == 32) { + float v[2]; + memcpy(v, r, sizeof(v)); + printf("MM%d = %016lx %8g %8g\n", n, *r, v[1], v[0]); + } else { + printf("MM%d = %016lx\n", n, *r); + } +} + +static void dump_xmm(const char *name, int n, const v2di *r, int ff) +{ + printf("%s%d = %016lx %016lx\n", + name, n, r->q1, r->q0); + if (ff == 32) { + float v[4]; + memcpy(v, r, sizeof(v)); + printf(" %8g %8g %8g %8g\n", + v[3], v[2], v[1], v[0]); + } +} + +static void dump_regs(reg_state *s, int ff) +{ + int i; + + for (i = 0; i < 8; i++) { + dump_mmx(i, &s->mm[i], ff); + } + for (i = 0; i < 4; i++) { + dump_xmm("mem", i, &s->mem0[i], 0); + } +} + +static void compare_state(const reg_state *a, const reg_state *b) +{ + int i; + for (i = 0; i < 8; i++) { + if (a->mm[i] != b->mm[i]) { + printf("MM%d = %016lx\n", i, b->mm[i]); + } + } + for (i = 0; i < 16; i++) { + if (a->r[i] != b->r[i]) { + printf("r%d = %016lx\n", i, b->r[i]); + } + } + for (i = 0; i < 8; i++) { + if (memcmp(&a->xmm[i], &b->xmm[i], 8)) { + dump_xmm("xmm", i, &b->xmm[i], a->ff); + } + } + for (i = 0; i < 4; i++) { + if (memcmp(&a->mem0[i], &a->mem[i], 16)) { + dump_xmm("mem", i, &a->mem[i], a->ff); + } + } + if (a->flags != b->flags) { + printf("FLAGS = %016lx\n", b->flags); + } +} + +#define LOADMM(r, o) "movq " #r ", " #o "[%0]\n\t" +#define LOADXMM(r, o) "movdqa " #r ", " #o "[%0]\n\t" +#define STOREMM(r, o) "movq " #o "[%1], " #r "\n\t" +#define STOREXMM(r, o) "movdqa " #o "[%1], " #r "\n\t" +#define MMREG(F) \ + F(mm0, 0x00) \ + F(mm1, 0x08) \ + F(mm2, 0x10) \ + F(mm3, 0x18) \ + F(mm4, 0x20) \ + F(mm5, 0x28) \ + F(mm6, 0x30) \ + F(mm7, 0x38) +#define XMMREG(F) \ + F(xmm0, 0x040) \ + F(xmm1, 0x050) \ + F(xmm2, 0x060) \ + F(xmm3, 0x070) \ + F(xmm4, 0x080) \ + F(xmm5, 0x090) \ + F(xmm6, 0x0a0) \ + F(xmm7, 0x0b0) +#define LOADREG(r, o) "mov " #r ", " #o "[rax]\n\t" +#define STOREREG(r, o) "mov " #o "[rax], " #r "\n\t" +#define REG(F) \ + F(rbx, 0xc8) \ + F(rcx, 0xd0) \ + F(rdx, 0xd8) \ + F(rsi, 0xe0) \ + F(rdi, 0xe8) \ + F(r8, 0x100) \ + F(r9, 0x108) \ + F(r10, 0x110) \ + F(r11, 0x118) \ + F(r12, 0x120) \ + F(r13, 0x128) \ + F(r14, 0x130) \ + F(r15, 0x138) \ + +static void run_test(const TestDef *t) +{ + reg_state result; + reg_state *init = t->init; + memcpy(init->mem, init->mem0, sizeof(init->mem)); + printf("%5d %s\n", t->n, t->s); + asm volatile( + MMREG(LOADMM) + XMMREG(LOADXMM) + "sub rsp, 128\n\t" + "push rax\n\t" + "push rbx\n\t" + "push rcx\n\t" + "push rdx\n\t" + "push %1\n\t" + "push %2\n\t" + "mov rax, %0\n\t" + "pushf\n\t" + "pop rbx\n\t" + "shr rbx, 8\n\t" + "shl rbx, 8\n\t" + "mov rcx, 0x140[rax]\n\t" + "and rcx, 0xff\n\t" + "or rbx, rcx\n\t" + "push rbx\n\t" + "popf\n\t" + REG(LOADREG) + "mov rax, 0xc0[rax]\n\t" + "call [rsp]\n\t" + "mov [rsp], rax\n\t" + "mov rax, 8[rsp]\n\t" + REG(STOREREG) + "mov rbx, [rsp]\n\t" + "mov 0xc0[rax], rbx\n\t" + "mov rbx, 0\n\t" + "mov 0xf0[rax], rbx\n\t" + "mov 0xf8[rax], rbx\n\t" + "pushf\n\t" + "pop rbx\n\t" + "and rbx, 0xff\n\t" + "mov 0x140[rax], rbx\n\t" + "add rsp, 16\n\t" + "pop rdx\n\t" + "pop rcx\n\t" + "pop rbx\n\t" + "pop rax\n\t" + "add rsp, 128\n\t" + MMREG(STOREMM) + EMMS "\n\t" + XMMREG(STOREXMM) + : : "r"(init), "r"(&result), "r"(t->fn) + : "memory", "cc", + "rsi", "rdi", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", + "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", + "xmm12", "xmm13", "xmm14", "xmm15" + ); + compare_state(init, &result); +} + +#define TEST(n, cmd, type) \ +static void __attribute__((naked)) test_##n(void) \ +{ \ + asm volatile(cmd); \ + asm volatile("ret"); \ +} +#include TEST_FILE + + +static const TestDef test_table[] = { +#define TEST(n, cmd, type) {n, test_##n, cmd, &init##type}, +#include TEST_FILE + {-1, NULL, "", NULL} +}; + +static void run_all(void) +{ + const TestDef *t; + for (t = test_table; t->fn; t++) { + run_test(t); + } +} + +#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0])) + +float val_f32[] = {2.0, -1.0, 4.8, 0.8, 3, -42.0, 5e6, 7.5, 8.3}; +uint64_t val_i64[] = { + 0x3d6b3b6a9e4118f2lu, 0x355ae76d2774d78clu, + 0xd851c54a56bf1f29lu, 0x4a84d1d50bf4c4fflu, + 0x5826475e2c5fd799lu, 0xfd32edc01243f5e9lu, +}; + +v2di deadbeef = {0xa5a5a5a5deadbeefull, 0xa5a5a5a5deadbeefull}; + +void init_f32reg(uint64_t *r) +{ + static int n; + float v[2]; + int i; + for (i = 0; i < 2; i++) { + v[i] = val_f32[n++]; + if (n == ARRAY_LEN(val_f32)) { + n = 0; + } + } + memcpy(r, v, sizeof(*r)); +} + +void init_intreg(uint64_t *r) +{ + static uint64_t mask; + static int n; + + *r = val_i64[n] ^ mask; + n++; + if (n == ARRAY_LEN(val_i64)) { + n = 0; + mask *= 0x104C11DB7; + } +} + +static void init_all(reg_state *s) +{ + int i; + + for (i = 0; i < 16; i++) { + init_intreg(&s->r[i]); + } + s->r[3] = (uint64_t)&s->mem[0]; /* rdx */ + s->r[5] = (uint64_t)&s->mem[2]; /* rdi */ + s->r[6] = 0; + s->r[7] = 0; + s->flags = 2; + for (i = 0; i < 8; i++) { + s->xmm[i] = deadbeef; + memcpy(&s->mm[i], &s->xmm[i], sizeof(s->mm[i])); + } + for (i = 0; i < 2; i++) { + s->mem0[i] = deadbeef; + } +} + +int main(int argc, char *argv[]) +{ + init_all(&initI); + init_intreg(&initI.mm[5]); + init_intreg(&initI.mm[6]); + init_intreg(&initI.mm[7]); + init_intreg(&initI.mem0[1].q0); + init_intreg(&initI.mem0[1].q1); + printf("Int:\n"); + dump_regs(&initI, 0); + + init_all(&initF32); + init_f32reg(&initF32.mm[5]); + init_f32reg(&initF32.mm[6]); + init_f32reg(&initF32.mm[7]); + init_f32reg(&initF32.mem0[1].q0); + init_f32reg(&initF32.mem0[1].q1); + initF32.ff = 32; + printf("F32:\n"); + dump_regs(&initF32, 32); + + if (argc > 1) { + int n = atoi(argv[1]); + run_test(&test_table[n]); + } else { + run_all(); + } + return 0; +} diff --git a/tests/tcg/i386/test-mmx.py b/tests/tcg/i386/test-mmx.py new file mode 100755 index 0000000..392315e --- /dev/null +++ b/tests/tcg/i386/test-mmx.py @@ -0,0 +1,244 @@ +#! /usr/bin/env python3 + +# Generate test-avx.h from x86.csv + +import csv +import sys +from fnmatch import fnmatch + +ignore = set(["EMMS", "FEMMS", "FISTTP", + "LDMXCSR", "VLDMXCSR", "STMXCSR", "VSTMXCSR"]) + +imask = { + 'PALIGNR': 0x3f, + 'PEXTRB': 0x0f, + 'PEXTRW': 0x07, + 'PEXTRD': 0x03, + 'PEXTRQ': 0x01, + 'PINSRB': 0x0f, + 'PINSRW': 0x07, + 'PINSRD': 0x03, + 'PINSRQ': 0x01, + 'PSHUF[DW]': 0xff, + 'PSHUF[LH]W': 0xff, + 'PS[LR][AL][WDQ]': 0x3f, +} + +def strip_comments(x): + for l in x: + if l != '' and l[0] != '#': + yield l + +def reg_w(w): + if w == 8: + return 'al' + elif w == 16: + return 'ax' + elif w == 32: + return 'eax' + elif w == 64: + return 'rax' + raise Exception("bad reg_w %d" % w) + +def mem_w(w): + if w == 8: + t = "BYTE" + elif w == 16: + t = "WORD" + elif w == 32: + t = "DWORD" + elif w == 64: + t = "QWORD" + else: + raise Exception() + + return t + " PTR 32[rdx]" + +class MMArg(): + isxmm = True + + def __init__(self, mw): + if mw not in [0, 32, 64]: + raise Exception("Bad /m width: %s" % w) + self.mw = mw + self.ismem = mw != 0 + def regstr(self, n): + if n < 0: + return mem_w(self.mw) + else: + return "mm%d" % (n, ) + +def match(op, pattern): + return fnmatch(op, pattern) + +class ArgImm8u(): + isxmm = False + ismem = False + def __init__(self, op): + for k, v in imask.items(): + if match(op, k): + self.mask = imask[k]; + return + raise Exception("Unknown immediate") + def vals(self): + mask = self.mask + yield 0 + n = 0 + while n != mask: + n += 1 + while (n & ~mask) != 0: + n += (n & ~mask) + yield n + +class ArgRM(): + isxmm = False + def __init__(self, rw, mw): + if rw not in [8, 16, 32, 64]: + raise Exception("Bad r/w width: %s" % w) + if mw not in [0, 8, 16, 32, 64]: + raise Exception("Bad r/w width: %s" % w) + self.rw = rw + self.mw = mw + self.ismem = mw != 0 + def regstr(self, n): + if n < 0: + return mem_w(self.mw) + else: + return reg_w(self.rw) + +class ArgMem(): + isxmm = False + ismem = True + def __init__(self, w): + if w not in [8, 16, 32, 64, 128, 256]: + raise Exception("Bad mem width: %s" % w) + self.w = w + def regstr(self, n): + return mem_w(self.w) + +class SkipInstruction(Exception): + pass + +def ArgGenerator(arg, op): + if arg[:2] == 'mm': + if "/" in arg: + r, m = arg.split('/') + if (m[0] != 'm'): + raise Exception("Expected /m: %s", arg) + return MMArg(int(m[1:])); + else: + return MMArg(0); + elif arg[:4] == 'imm8': + return ArgImm8u(op); + elif arg[0] == 'r': + if '/m' in arg: + r, m = arg.split('/') + if (m[0] != 'm'): + raise Exception("Expected /m: %s", arg) + mw = int(m[1:]) + if r == 'r': + rw = mw + else: + rw = int(r[1:]) + return ArgRM(rw, mw) + + return ArgRM(int(arg[1:]), 0); + elif arg[0] == 'm': + return ArgMem(int(arg[1:])) + else: + raise SkipInstruction + +class InsnGenerator: + def __init__(self, op, args): + self.op = op + if op[0:2] == "PF": + self.optype = 'F32' + else: + self.optype = 'I' + + try: + self.args = list(ArgGenerator(a, op) for a in args) + if len(self.args) > 0 and self.args[-1] is None: + self.args = self.args[:-1] + except SkipInstruction: + raise + except Exception as e: + raise Exception("Bad arg %s: %s" % (op, e)) + + def gen(self): + regs = (5, 6, 7) + dest = 4 + + nreg = len(self.args) + if nreg == 0: + yield self.op + return + if isinstance(self.args[-1], ArgImm8u): + nreg -= 1 + immarg = self.args[-1] + else: + immarg = None + memarg = -1 + for n, arg in enumerate(self.args): + if arg.ismem: + memarg = n + + if nreg == 1: + regset = [(regs[0],)] + if memarg == 0: + regset += [(-1,)] + elif nreg == 2: + regset = [ + (regs[0], regs[1]), + (regs[0], regs[0]), + ] + if memarg == 0: + regset += [(-1, regs[0])] + elif memarg == 1: + regset += [(dest, -1)] + else: + raise Exception("Too many regs: %s(%d)" % (self.op, nreg)) + + for regv in regset: + argstr = [] + for i in range(nreg): + arg = self.args[i] + argstr.append(arg.regstr(regv[i])) + if immarg is None: + yield self.op + ' ' + ','.join(argstr) + else: + for immval in immarg.vals(): + yield self.op + ' ' + ','.join(argstr) + ',' + str(immval) + +def split0(s): + if s == '': + return [] + return s.split(',') + +def main(): + n = 0 + if len(sys.argv) <= 3: + print("Usage: test-mmx.py x86.csv test-mmx.h CPUID...") + exit(1) + csvfile = open(sys.argv[1], 'r', newline='') + archs = sys.argv[3:] + with open(sys.argv[2], "w") as outf: + outf.write("// Generated by test-mmx.py. Do not edit.\n") + for row in csv.reader(strip_comments(csvfile)): + insn = row[0].replace(',', '').split() + if insn[0] in ignore: + continue + cpuid = row[6] + if cpuid in archs: + try: + g = InsnGenerator(insn[0], insn[1:]) + for insn in g.gen(): + outf.write('TEST(%d, "%s", %s)\n' % (n, insn, g.optype)) + n += 1 + except SkipInstruction: + pass + outf.write("#undef TEST\n") + csvfile.close() + +if __name__ == "__main__": + main() diff --git a/tests/tcg/i386/x86.csv b/tests/tcg/i386/x86.csv index d5d0c17..c43bf42 100644 --- a/tests/tcg/i386/x86.csv +++ b/tests/tcg/i386/x86.csv @@ -1469,16 +1469,16 @@ "PFCMPEQ mm1, mm2/m64","PFCMPEQ mm2/m64, mm1","pfcmpeq mm2/m64, mm1","0F 0F B0 /r","V","V","3DNOW","amd","rw,r","","" "PFCMPGE mm1, mm2/m64","PFCMPGE mm2/m64, mm1","pfcmpge mm2/m64, mm1","0F 0F 90 /r","V","V","3DNOW","amd","rw,r","","" "PFCMPGT mm1, mm2/m64","PFCMPGT mm2/m64, mm1","pfcmpgt mm2/m64, mm1","0F 0F A0 /r","V","V","3DNOW","amd","rw,r","","" -"PFCPIT1 mm1, mm2/m64","PFCPIT1 mm2/m64, mm1","pfcpit1 mm2/m64, mm1","0F 0F A6 /r","V","V","3DNOW","amd","rw,r","","" "PFMAX mm1, mm2/m64","PFMAX mm2/m64, mm1","pfmax mm2/m64, mm1","0F 0F A4 /r","V","V","3DNOW","amd","rw,r","","" "PFMIN mm1, mm2/m64","PFMIN mm2/m64, mm1","pfmin mm2/m64, mm1","0F 0F 94 /r","V","V","3DNOW","amd","rw,r","","" "PFMUL mm1, mm2/m64","PFMUL mm2/m64, mm1","pfmul mm2/m64, mm1","0F 0F B4 /r","V","V","3DNOW","amd","rw,r","","" "PFNACC mm1, mm2/m64","PFNACC mm2/m64, mm1","pfnacc mm2/m64, mm1","0F 0F 8A /r","V","V","3DNOW","amd","rw,r","","" "PFPNACC mm1, mm2/m64","PFPNACC mm2/m64, mm1","pfpnacc mm2/m64, mm1","0F 0F 8E /r","V","V","3DNOW","amd","rw,r","","" "PFRCP mm1, mm2/m64","PFRCP mm2/m64, mm1","pfrcp mm2/m64, mm1","0F 0F 96 /r","V","V","3DNOW","amd","rw,r","","" +"PFRCPIT1 mm1, mm2/m64","PFRCPIT1 mm2/m64, mm1","pfrcpit1 mm2/m64, mm1","0F 0F A6 /r","V","V","3DNOW","amd","rw,r","","" "PFRCPIT2 mm1, mm2/m64","PFRCPIT2 mm2/m64, mm1","pfrcpit2 mm2/m64, mm1","0F 0F B6 /r","V","V","3DNOW","amd","rw,r","","" "PFRSQIT1 mm1, mm2/m64","PFRSQIT1 mm2/m64, mm1","pfrsqit1 mm2/m64, mm1","0F 0F A7 /r","V","V","3DNOW","amd","rw,r","","" -"PFSQRT mm1, mm2/m64","PFSQRT mm2/m64, mm1","pfsqrt mm2/m64, mm1","0F 0F 97 /r","V","V","3DNOW","amd","rw,r","","" +"PFRSQRT mm1, mm2/m64","PFRSQRT mm2/m64, mm1","pfrsqrt mm2/m64, mm1","0F 0F 97 /r","V","V","3DNOW","amd","rw,r","","" "PFSUB mm1, mm2/m64","PFSUB mm2/m64, mm1","pfsub mm2/m64, mm1","0F 0F 9A /r","V","V","3DNOW","amd","rw,r","","" "PFSUBR mm1, mm2/m64","PFSUBR mm2/m64, mm1","pfsubr mm2/m64, mm1","0F 0F AA /r","V","V","3DNOW","amd","rw,r","","" "PHADDD mm1, mm2/m64","PHADDD mm2/m64, mm1","phaddd mm2/m64, mm1","0F 38 02 /r","V","V","SSSE3","","rw,r","","" diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target index 861a096..6895db1 100644 --- a/tests/tcg/x86_64/Makefile.target +++ b/tests/tcg/x86_64/Makefile.target @@ -17,7 +17,6 @@ TESTS=$(MULTIARCH_TESTS) endif run-test-i386-ssse3: QEMU_OPTS += -cpu max -run-test-avx: QEMU_OPTS += -cpu max run-plugin-test-i386-ssse3-%: QEMU_OPTS += -cpu max test-x86_64: LDFLAGS+=-lm -lc diff --git a/tests/unit/check-block-qdict.c b/tests/unit/check-block-qdict.c index 5a25825..751c58e 100644 --- a/tests/unit/check-block-qdict.c +++ b/tests/unit/check-block-qdict.c @@ -504,7 +504,7 @@ static void qdict_crumple_test_empty(void) src = qdict_new(); dst = qobject_to(QDict, qdict_crumple(src, &error_abort)); - + g_assert(dst); g_assert_cmpint(qdict_size(dst), ==, 0); qobject_unref(src); diff --git a/tests/unit/test-io-channel-command.c b/tests/unit/test-io-channel-command.c index 99056e0..aa09c55 100644 --- a/tests/unit/test-io-channel-command.c +++ b/tests/unit/test-io-channel-command.c @@ -41,7 +41,8 @@ static void test_io_channel_command_fifo(bool async) unlink(TEST_FIFO); if (access("/bin/socat", X_OK) < 0) { - return; /* Pretend success if socat is not present */ + g_test_skip("socat is missing"); + return; } if (mkfifo(TEST_FIFO, 0600) < 0) { abort(); diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c index a05a462..b6ea7c7 100644 --- a/tests/unit/test-qga.c +++ b/tests/unit/test-qga.c @@ -32,6 +32,7 @@ static int connect_qga(char *path) g_usleep(G_USEC_PER_SEC); } if (i++ == 10) { + close(s); return -1; } } while (ret == -1); @@ -729,7 +730,7 @@ static void test_qga_config(gconstpointer data) g_assert_true(g_key_file_get_boolean(kf, "general", "verbose", &error)); g_assert_no_error(error); - strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error); + strv = g_key_file_get_string_list(kf, "general", "block-rpcs", &n, &error); g_assert_cmpint(n, ==, 2); g_assert_true(g_strv_contains((const char * const *)strv, "guest-ping")); diff --git a/tests/unit/test-visitor-serialization.c b/tests/unit/test-visitor-serialization.c index 907263d..667e8fe 100644 --- a/tests/unit/test-visitor-serialization.c +++ b/tests/unit/test-visitor-serialization.c @@ -427,131 +427,117 @@ static void test_primitive_lists(gconstpointer opaque) ops->deserialize((void **)&pl_copy_ptr, serialize_data, visit_primitive_list, &error_abort); - i = 0; + + switch (pl_copy.type) { + case PTYPE_STRING: + cur_head = pl_copy.value.strings; + break; + case PTYPE_INTEGER: + cur_head = pl_copy.value.integers; + break; + case PTYPE_S8: + cur_head = pl_copy.value.s8_integers; + break; + case PTYPE_S16: + cur_head = pl_copy.value.s16_integers; + break; + case PTYPE_S32: + cur_head = pl_copy.value.s32_integers; + break; + case PTYPE_S64: + cur_head = pl_copy.value.s64_integers; + break; + case PTYPE_U8: + cur_head = pl_copy.value.u8_integers; + break; + case PTYPE_U16: + cur_head = pl_copy.value.u16_integers; + break; + case PTYPE_U32: + cur_head = pl_copy.value.u32_integers; + break; + case PTYPE_U64: + cur_head = pl_copy.value.u64_integers; + break; + case PTYPE_NUMBER: + cur_head = pl_copy.value.numbers; + break; + case PTYPE_BOOLEAN: + cur_head = pl_copy.value.booleans; + break; + default: + g_assert_not_reached(); + } /* compare our deserialized list of primitives to the original */ - do { + i = 0; + while (cur_head) { switch (pl_copy.type) { case PTYPE_STRING: { - strList *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.strings; - } + strList *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpstr(pt->value.string, ==, ptr->value); break; } case PTYPE_INTEGER: { - intList *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.integers; - } + intList *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.integer, ==, ptr->value); break; } case PTYPE_S8: { - int8List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.s8_integers; - } + int8List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.s8, ==, ptr->value); break; } case PTYPE_S16: { - int16List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.s16_integers; - } + int16List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.s16, ==, ptr->value); break; } case PTYPE_S32: { - int32List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.s32_integers; - } + int32List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.s32, ==, ptr->value); break; } case PTYPE_S64: { - int64List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.s64_integers; - } + int64List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.s64, ==, ptr->value); break; } case PTYPE_U8: { - uint8List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.u8_integers; - } + uint8List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.u8, ==, ptr->value); break; } case PTYPE_U16: { - uint16List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.u16_integers; - } + uint16List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.u16, ==, ptr->value); break; } case PTYPE_U32: { - uint32List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.u32_integers; - } + uint32List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.u32, ==, ptr->value); break; } case PTYPE_U64: { - uint64List *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.u64_integers; - } + uint64List *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(pt->value.u64, ==, ptr->value); break; } case PTYPE_NUMBER: { - numberList *ptr; GString *double_expected = g_string_new(""); GString *double_actual = g_string_new(""); - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.numbers; - } + numberList *ptr = cur_head; + cur_head = ptr->next; /* we serialize with %f for our reference visitors, so rather than * fuzzy floating math to test "equality", just compare the * formatted values @@ -564,13 +550,8 @@ static void test_primitive_lists(gconstpointer opaque) break; } case PTYPE_BOOLEAN: { - boolList *ptr; - if (cur_head) { - ptr = cur_head; - cur_head = ptr->next; - } else { - cur_head = ptr = pl_copy.value.booleans; - } + boolList *ptr = cur_head; + cur_head = ptr->next; g_assert_cmpint(!!pt->value.boolean, ==, !!ptr->value); break; } @@ -578,9 +559,9 @@ static void test_primitive_lists(gconstpointer opaque) g_assert_not_reached(); } i++; - } while (cur_head); + } - g_assert_cmpint(i, ==, 33); + g_assert_cmpint(i, ==, 32); ops->cleanup(serialize_data); dealloc_helper(&pl, visit_primitive_list, &error_abort); diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index 8d2a164..2cc2203 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -15,7 +15,7 @@ endif EFI_AARCH64 = $(wildcard $(BUILD_DIR)/pc-bios/edk2-aarch64-code.fd) -X86_IMAGES := freebsd netbsd openbsd fedora haiku.x86_64 +X86_IMAGES := freebsd netbsd openbsd haiku.x86_64 ifneq ($(GENISOIMAGE),) X86_IMAGES += centos ifneq ($(EFI_AARCH64),) @@ -45,7 +45,6 @@ vm-help vm-test: @echo " vm-build-freebsd - Build QEMU in FreeBSD VM" @echo " vm-build-netbsd - Build QEMU in NetBSD VM" @echo " vm-build-openbsd - Build QEMU in OpenBSD VM" - @echo " vm-build-fedora - Build QEMU in Fedora VM" ifneq ($(GENISOIMAGE),) @echo " vm-build-centos - Build QEMU in CentOS VM, with Docker" ifneq ($(EFI_AARCH64),) diff --git a/tests/vm/fedora b/tests/vm/fedora deleted file mode 100755 index 12eca91..0000000 --- a/tests/vm/fedora +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -# -# Fedora VM image -# -# Copyright 2019 Red Hat Inc. -# -# Authors: -# Gerd Hoffmann <kraxel@redhat.com> -# -# This code is licensed under the GPL version 2 or later. See -# the COPYING file in the top-level directory. -# - -import os -import re -import sys -import time -import socket -import subprocess -import basevm - -class FedoraVM(basevm.BaseVM): - name = "fedora" - arch = "x86_64" - - base = "https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/30/" - link = base + "Server/x86_64/iso/Fedora-Server-netinst-x86_64-30-1.2.iso" - repo = base + "Server/x86_64/os/" - full = base + "Everything/x86_64/os/" - csum = "5e4eac4566d8c572bfb3bcf54b7d6c82006ec3c6c882a2c9235c6d3494d7b100" - size = "20G" - pkgs = [ - # tools - 'git-core', - 'gcc', 'binutils', 'make', 'ninja-build', - - # perl - 'perl', - - # libs: usb - '"pkgconfig(libusb-1.0)"', - '"pkgconfig(libusbredirparser-0.5)"', - - # libs: crypto - '"pkgconfig(gnutls)"', - - # libs: ui - '"pkgconfig(sdl2)"', - '"pkgconfig(gtk+-3.0)"', - '"pkgconfig(ncursesw)"', - - # libs: audio - '"pkgconfig(libpulse)"', - '"pkgconfig(alsa)"', - - # libs: migration - '"pkgconfig(libzstd)"', -] - - BUILD_SCRIPT = """ - set -e; - rm -rf /home/qemu/qemu-test.* - cd $(mktemp -d /home/qemu/qemu-test.XXXXXX); - mkdir src build; cd src; - tar -xf /dev/vdb; - cd ../build - ../src/configure --python=python3 {configure_opts}; - gmake --output-sync -j{jobs} {target} {verbose}; - """ - - def build_image(self, img): - self.print_step("Downloading install iso") - cimg = self._download_with_cache(self.link, sha256sum=self.csum) - img_tmp = img + ".tmp" - iso = img + ".install.iso" - - self.print_step("Preparing iso and disk image") - subprocess.check_call(["cp", "-f", cimg, iso]) - self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) - self.print_step("Booting installer") - self.boot(img_tmp, extra_args = [ - "-machine", "graphics=off", - "-device", "VGA", - "-cdrom", iso - ]) - self.console_init(300) - self.console_wait("installation process.") - time.sleep(0.3) - self.console_send("\t") - time.sleep(0.3) - self.console_send(" console=ttyS0") - proxy = os.environ.get("http_proxy") - if not proxy is None: - self.console_send(" proxy=%s" % proxy) - self.console_send(" inst.proxy=%s" % proxy) - self.console_send(" inst.repo=%s" % self.repo) - self.console_send("\n") - - self.console_wait_send("2) Use text mode", "2\n") - - self.console_wait_send("5) [!] Installation Dest", "5\n") - self.console_wait_send("1) [x]", "c\n") - self.console_wait_send("2) [ ] Use All Space", "2\n") - self.console_wait_send("2) [x] Use All Space", "c\n") - self.console_wait_send("1) [ ] Standard Part", "1\n") - self.console_wait_send("1) [x] Standard Part", "c\n") - - self.console_wait_send("7) [!] Root password", "7\n") - self.console_wait("Password:") - self.console_send("%s\n" % self._config["root_pass"]) - self.console_wait("Password (confirm):") - self.console_send("%s\n" % self._config["root_pass"]) - - self.console_wait_send("8) [ ] User creation", "8\n") - self.console_wait_send("1) [ ] Create user", "1\n") - self.console_wait_send("3) User name", "3\n") - self.console_wait_send("ENTER:", "%s\n" % self._config["guest_user"]) - self.console_wait_send("4) [ ] Use password", "4\n") - self.console_wait_send("5) Password", "5\n") - self.console_wait("Password:") - self.console_send("%s\n" % self._config["guest_pass"]) - self.console_wait("Password (confirm):") - self.console_send("%s\n" % self._config["guest_pass"]) - self.console_wait_send("7) Groups", "c\n") - - while True: - good = self.console_wait("3) [x] Installation", - "3) [!] Installation") - self.console_send("r\n") - if good: - break - time.sleep(10) - - while True: - good = self.console_wait("4) [x] Software", - "4) [!] Software") - self.console_send("r\n") - if good: - break - time.sleep(10) - self.console_send("r\n" % self._config["guest_pass"]) - - self.console_wait_send("'b' to begin install", "b\n") - - self.print_step("Installation started now, this will take a while") - - self.console_wait_send("Installation complete", "\n") - self.print_step("Installation finished, rebooting") - - # setup qemu user - prompt = " ~]$" - self.console_ssh_init(prompt, self._config["guest_user"], - self._config["guest_pass"]) - self.console_wait_send(prompt, "exit\n") - - # setup root user - prompt = " ~]#" - self.console_ssh_init(prompt, "root", self._config["root_pass"]) - self.console_sshd_config(prompt) - - # setup virtio-blk #1 (tarfile) - self.console_wait(prompt) - self.console_send("echo 'KERNEL==\"vdb\" MODE=\"666\"' >> %s\n" % - "/etc/udev/rules.d/99-qemu.rules") - - self.print_step("Configuration finished, rebooting") - self.console_wait_send(prompt, "reboot\n") - self.console_wait("login:") - self.wait_ssh() - - self.print_step("Installing packages") - self.ssh_root_check("rm -vf /etc/yum.repos.d/fedora*.repo\n") - self.ssh_root_check("echo '[fedora]' >> /etc/yum.repos.d/qemu.repo\n") - self.ssh_root_check("echo 'baseurl=%s' >> /etc/yum.repos.d/qemu.repo\n" % self.full) - self.ssh_root_check("echo 'gpgcheck=0' >> /etc/yum.repos.d/qemu.repo\n") - self.ssh_root_check("dnf install -y %s\n" % " ".join(self.pkgs)) - - # shutdown - self.ssh_root(self.poweroff) - self.console_wait("sleep state S5") - self.wait() - - if os.path.exists(img): - os.remove(img) - os.rename(img_tmp, img) - os.remove(iso) - self.print_step("All done") - -if __name__ == "__main__": - sys.exit(basevm.main(FedoraVM)) diff --git a/tests/vm/netbsd b/tests/vm/netbsd index da6773f..aa54338 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -22,8 +22,8 @@ class NetBSDVM(basevm.BaseVM): name = "netbsd" arch = "x86_64" - link = "https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.2/images/NetBSD-9.2-amd64.iso" - csum = "5ee0ea101f73386b9b424f5d1041e371db3c42fdd6f4e4518dc79c4a08f31d43091ebe93425c9f0dcaaed2b51131836fe6774f33f89030b58d64709b35fda72f" + link = "https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.3/images/NetBSD-9.3-amd64.iso" + csum = "2bfce544f762a579f61478e7106c436fc48731ff25cf6f79b392ba5752e6f5ec130364286f7471716290a5f033637cf56aacee7fedb91095face59adf36300c3" size = "20G" pkgs = [ # tools |