diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml index 22045add80..278a5ea966 100644 --- a/.gitlab-ci.d/buildtest-template.yml +++ b/.gitlab-ci.d/buildtest-template.yml @@ -26,10 +26,10 @@ then pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ; fi || exit 1; - - make -j"$JOBS" + - $MAKE -j"$JOBS" - if test -n "$MAKE_CHECK_ARGS"; then - make -j"$JOBS" $MAKE_CHECK_ARGS ; + $MAKE -j"$JOBS" $MAKE_CHECK_ARGS ; fi - ccache --show-stats @@ -60,7 +60,7 @@ - cd build - find . -type f -exec touch {} + # Avoid recompiling by hiding ninja with NINJA=":" - - make NINJA=":" $MAKE_CHECK_ARGS + - $MAKE NINJA=":" $MAKE_CHECK_ARGS .native_test_job_template: extends: .common_test_job_template diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index cfdff175c3..8440bc8ef6 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -158,9 +158,9 @@ build-system-centos: - .native_build_job_template - .native_build_artifact_template needs: - job: amd64-centos8-container + job: amd64-centos9-container variables: - IMAGE: centos8 + IMAGE: centos9 CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-vfio-user-server --enable-modules --enable-trace-backends=dtrace --enable-docs TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu @@ -242,7 +242,7 @@ check-system-centos: - job: build-system-centos artifacts: true variables: - IMAGE: centos8 + IMAGE: centos9 MAKE_CHECK_ARGS: check avocado-system-centos: @@ -251,7 +251,7 @@ avocado-system-centos: - job: build-system-centos artifacts: true variables: - IMAGE: centos8 + IMAGE: centos9 MAKE_CHECK_ARGS: check-avocado AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx arch:sh4 arch:nios2 @@ -327,9 +327,9 @@ avocado-system-flaky: build-tcg-disabled: extends: .native_build_job_template needs: - job: amd64-centos8-container + job: amd64-centos9-container variables: - IMAGE: centos8 + IMAGE: centos9 script: - mkdir build - cd build @@ -575,6 +575,9 @@ tsan-build: CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++ --enable-trace-backends=ust --disable-slirp TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user + # Remove when we switch to a distro with clang >= 18 + # https://github.com/google/sanitizers/issues/1716 + MAKE: setarch -R make # gcov is a GCC features gcov: @@ -651,9 +654,9 @@ build-tci: build-without-defaults: extends: .native_build_job_template needs: - job: amd64-centos8-container + job: amd64-centos9-container variables: - IMAGE: centos8 + IMAGE: centos9 CONFIGURE_ARGS: --without-default-devices --without-default-features diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml index 4671f069c3..49f86fadaf 100644 --- a/.gitlab-ci.d/cirrus.yml +++ b/.gitlab-ci.d/cirrus.yml @@ -57,6 +57,7 @@ x64-freebsd-13-build: CIRRUS_VM_RAM: 8G UPDATE_COMMAND: pkg update; pkg upgrade -y INSTALL_COMMAND: pkg install -y + CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu TEST_TARGETS: check aarch64-macos-13-base-build: @@ -72,6 +73,7 @@ aarch64-macos-13-base-build: INSTALL_COMMAND: brew install PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig + CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblazeel-softmmu,mips64-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4-softmmu,xtensaeb-softmmu TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64 aarch64-macos-14-base-build: diff --git a/.gitlab-ci.d/container-core.yml b/.gitlab-ci.d/container-core.yml index 08f8450fa1..5459447676 100644 --- a/.gitlab-ci.d/container-core.yml +++ b/.gitlab-ci.d/container-core.yml @@ -1,10 +1,10 @@ include: - local: '/.gitlab-ci.d/container-template.yml' -amd64-centos8-container: +amd64-centos9-container: extends: .container_job_template variables: - NAME: centos8 + NAME: centos9 amd64-fedora-container: extends: .container_job_template diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml index 94834269ec..fec51de2d4 100644 --- a/.gitlab-ci.d/windows.yml +++ b/.gitlab-ci.d/windows.yml @@ -1,9 +1,7 @@ msys2-64bit: extends: .base_job_template tags: - - shared-windows - - windows - - windows-1809 + - saas-windows-medium-amd64 cache: key: "$CI_JOB_NAME" paths: diff --git a/VERSION b/VERSION index f7ee06693c..3beeadd423 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -9.0.0 +9.0.2 diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index de20e7da15..e777371e51 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -712,7 +712,7 @@ static void tb_record(TranslationBlock *tb) tb_page_addr_t paddr0 = tb_page_addr0(tb); tb_page_addr_t paddr1 = tb_page_addr1(tb); tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS; - tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS; + tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS; assert(paddr0 != -1); if (unlikely(paddr1 != -1) && pindex0 != pindex1) { @@ -744,7 +744,7 @@ static void tb_remove(TranslationBlock *tb) tb_page_addr_t paddr0 = tb_page_addr0(tb); tb_page_addr_t paddr1 = tb_page_addr1(tb); tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS; - tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS; + tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS; assert(paddr0 != -1); if (unlikely(paddr1 != -1) && pindex0 != pindex1) { diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c index a514bbb310..940104ee55 100644 --- a/backends/cryptodev-builtin.c +++ b/backends/cryptodev-builtin.c @@ -23,6 +23,7 @@ #include "qemu/osdep.h" #include "sysemu/cryptodev.h" +#include "qemu/error-report.h" #include "qapi/error.h" #include "standard-headers/linux/virtio_crypto.h" #include "crypto/cipher.h" @@ -396,8 +397,8 @@ static int cryptodev_builtin_create_session( case VIRTIO_CRYPTO_HASH_CREATE_SESSION: case VIRTIO_CRYPTO_MAC_CREATE_SESSION: default: - error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", - sess_info->op_code); + error_report("Unsupported opcode :%" PRIu32 "", + sess_info->op_code); return -VIRTIO_CRYPTO_NOTSUPP; } @@ -554,8 +555,8 @@ static int cryptodev_builtin_operation( if (op_info->session_id >= MAX_NUM_SESSIONS || builtin->sessions[op_info->session_id] == NULL) { - error_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "", - op_info->session_id); + error_report("Cannot find a valid session id: %" PRIu64 "", + op_info->session_id); return -VIRTIO_CRYPTO_INVSESS; } diff --git a/block.c b/block.c index 468cf5e67d..50bdd197b7 100644 --- a/block.c +++ b/block.c @@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, BlockDriverState *parent, const BdrvChildClass *child_class, BdrvChildRole child_role, + bool parse_filename, Error **errp); static bool bdrv_recurse_has_child(BlockDriverState *bs, @@ -2058,7 +2059,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename, * block driver has been specified explicitly. */ static int bdrv_fill_options(QDict **options, const char *filename, - int *flags, Error **errp) + int *flags, bool allow_parse_filename, + Error **errp) { const char *drvname; bool protocol = *flags & BDRV_O_PROTOCOL; @@ -2100,7 +2102,7 @@ static int bdrv_fill_options(QDict **options, const char *filename, if (protocol && filename) { if (!qdict_haskey(*options, "filename")) { qdict_put_str(*options, "filename", filename); - parse_filename = true; + parse_filename = allow_parse_filename; } else { error_setg(errp, "Can't specify 'file' and 'filename' options at " "the same time"); @@ -3663,7 +3665,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, } backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs, - &child_of_bds, bdrv_backing_role(bs), errp); + &child_of_bds, bdrv_backing_role(bs), true, + errp); if (!backing_hd) { bs->open_flags |= BDRV_O_NO_BACKING; error_prepend(errp, "Could not open backing file: "); @@ -3697,7 +3700,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, static BlockDriverState * bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, BlockDriverState *parent, const BdrvChildClass *child_class, - BdrvChildRole child_role, bool allow_none, Error **errp) + BdrvChildRole child_role, bool allow_none, + bool parse_filename, Error **errp) { BlockDriverState *bs = NULL; QDict *image_options; @@ -3728,7 +3732,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, } bs = bdrv_open_inherit(filename, reference, image_options, 0, - parent, child_class, child_role, errp); + parent, child_class, child_role, parse_filename, + errp); if (!bs) { goto done; } @@ -3738,6 +3743,33 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, return bs; } +static BdrvChild *bdrv_open_child_common(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState *parent, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + bool allow_none, bool parse_filename, + Error **errp) +{ + BlockDriverState *bs; + BdrvChild *child; + + GLOBAL_STATE_CODE(); + + bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, + child_role, allow_none, parse_filename, errp); + if (bs == NULL) { + return NULL; + } + + bdrv_graph_wrlock(); + child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, + errp); + bdrv_graph_wrunlock(); + + return child; +} + /* * Opens a disk image whose options are given as BlockdevRef in another block * device's options. @@ -3761,27 +3793,15 @@ BdrvChild *bdrv_open_child(const char *filename, BdrvChildRole child_role, bool allow_none, Error **errp) { - BlockDriverState *bs; - BdrvChild *child; - - GLOBAL_STATE_CODE(); - - bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, - child_role, allow_none, errp); - if (bs == NULL) { - return NULL; - } - - bdrv_graph_wrlock(); - child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, - errp); - bdrv_graph_wrunlock(); - - return child; + return bdrv_open_child_common(filename, options, bdref_key, parent, + child_class, child_role, allow_none, false, + errp); } /* - * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. + * This does mostly the same as bdrv_open_child(), but for opening the primary + * child of a node. A notable difference from bdrv_open_child() is that it + * enables filename parsing for protocol names (including json:). * * @parent can move to a different AioContext in this function. */ @@ -3796,8 +3816,8 @@ int bdrv_open_file_child(const char *filename, role = parent->drv->is_filter ? (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; - if (!bdrv_open_child(filename, options, bdref_key, parent, - &child_of_bds, role, false, errp)) + if (!bdrv_open_child_common(filename, options, bdref_key, parent, + &child_of_bds, role, false, true, errp)) { return -EINVAL; } @@ -3842,7 +3862,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) } - bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp); + bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false, + errp); obj = NULL; qobject_unref(obj); visit_free(v); @@ -3932,7 +3953,7 @@ static BlockDriverState * no_coroutine_fn bdrv_open_inherit(const char *filename, const char *reference, QDict *options, int flags, BlockDriverState *parent, const BdrvChildClass *child_class, BdrvChildRole child_role, - Error **errp) + bool parse_filename, Error **errp) { int ret; BlockBackend *file = NULL; @@ -3980,9 +4001,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, } /* json: syntax counts as explicit options, as if in the QDict */ - parse_json_protocol(options, &filename, &local_err); - if (local_err) { - goto fail; + if (parse_filename) { + parse_json_protocol(options, &filename, &local_err); + if (local_err) { + goto fail; + } } bs->explicit_options = qdict_clone_shallow(options); @@ -4007,7 +4030,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, parent->open_flags, parent->options); } - ret = bdrv_fill_options(&options, filename, &flags, &local_err); + ret = bdrv_fill_options(&options, filename, &flags, parse_filename, + &local_err); if (ret < 0) { goto fail; } @@ -4076,7 +4100,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, file_bs = bdrv_open_child_bs(filename, options, "file", bs, &child_of_bds, BDRV_CHILD_IMAGE, - true, &local_err); + true, true, &local_err); if (local_err) { goto fail; } @@ -4225,7 +4249,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference, GLOBAL_STATE_CODE(); return bdrv_open_inherit(filename, reference, options, flags, NULL, - NULL, 0, errp); + NULL, 0, true, errp); } /* Return true if the NULL-terminated @list contains @str */ diff --git a/block/qcow2.c b/block/qcow2.c index 956128b409..4c78665bcb 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1636,7 +1636,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, goto fail; } - if (open_data_file) { + if (open_data_file && (flags & BDRV_O_NO_IO)) { + /* + * Don't open the data file for 'qemu-img info' so that it can be used + * to verify that an untrusted qcow2 image doesn't refer to external + * files. + * + * Note: This still makes has_data_file() return true. + */ + if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { + s->data_file = NULL; + } else { + s->data_file = bs->file; + } + qdict_extract_subqdict(options, NULL, "data-file."); + qdict_del(options, "data-file"); + } else if (open_data_file) { /* Open external data file */ bdrv_graph_co_rdunlock(); s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs, diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c index 3c648678ab..b960ddd4e4 100644 --- a/chardev/char-stdio.c +++ b/chardev/char-stdio.c @@ -41,6 +41,7 @@ /* init terminal so that we can grab keys */ static struct termios oldtty; static int old_fd0_flags; +static int old_fd1_flags; static bool stdio_in_use; static bool stdio_allow_signal; static bool stdio_echo_state; @@ -50,6 +51,8 @@ static void term_exit(void) if (stdio_in_use) { tcsetattr(0, TCSANOW, &oldtty); fcntl(0, F_SETFL, old_fd0_flags); + fcntl(1, F_SETFL, old_fd1_flags); + stdio_in_use = false; } } @@ -102,6 +105,7 @@ static void qemu_chr_open_stdio(Chardev *chr, stdio_in_use = true; old_fd0_flags = fcntl(0, F_GETFL); + old_fd1_flags = fcntl(1, F_GETFL); tcgetattr(0, &oldtty); if (!g_unix_set_fd_nonblocking(0, true, NULL)) { error_setg_errno(errp, errno, "Failed to set FD nonblocking"); diff --git a/configure b/configure index 3cd736b139..0aea9b113b 100755 --- a/configure +++ b/configure @@ -411,7 +411,9 @@ else # Using uname is really broken, but it is just a fallback for architectures # that are going to use TCI anyway cpu=$(uname -m) - echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'" + if test "$host_os" != "bogus"; then + echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'" + fi fi # Normalise host CPU name to the values used by Meson cross files and in source @@ -762,7 +764,7 @@ for opt do --*) meson_option_parse "$opt" "$optarg" ;; # Pass through -Dxxxx options to meson - -D*) meson_options="$meson_options $opt" + -D*) meson_option_add "$opt" ;; esac done @@ -894,6 +896,13 @@ EOF exit 0 fi +# Now that we are sure that the user did not only want to print the --help +# information, we should double-check that the C compiler really works: +write_c_skeleton +if ! compile_object ; then + error_exit "C compiler \"$cc\" either does not exist or does not work." +fi + # Remove old dependency files to make sure that they get properly regenerated rm -f ./*/config-devices.mak.d diff --git a/disas/riscv.c b/disas/riscv.c index e236c8b5b7..297cfa2f63 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -2190,7 +2190,22 @@ static const char *csr_name(int csrno) case 0x0383: return "mibound"; case 0x0384: return "mdbase"; case 0x0385: return "mdbound"; - case 0x03a0: return "pmpcfg3"; + case 0x03a0: return "pmpcfg0"; + case 0x03a1: return "pmpcfg1"; + case 0x03a2: return "pmpcfg2"; + case 0x03a3: return "pmpcfg3"; + case 0x03a4: return "pmpcfg4"; + case 0x03a5: return "pmpcfg5"; + case 0x03a6: return "pmpcfg6"; + case 0x03a7: return "pmpcfg7"; + case 0x03a8: return "pmpcfg8"; + case 0x03a9: return "pmpcfg9"; + case 0x03aa: return "pmpcfg10"; + case 0x03ab: return "pmpcfg11"; + case 0x03ac: return "pmpcfg12"; + case 0x03ad: return "pmpcfg13"; + case 0x03ae: return "pmpcfg14"; + case 0x03af: return "pmpcfg15"; case 0x03b0: return "pmpaddr0"; case 0x03b1: return "pmpaddr1"; case 0x03b2: return "pmpaddr2"; @@ -2207,6 +2222,54 @@ static const char *csr_name(int csrno) case 0x03bd: return "pmpaddr13"; case 0x03be: return "pmpaddr14"; case 0x03bf: return "pmpaddr15"; + case 0x03c0: return "pmpaddr16"; + case 0x03c1: return "pmpaddr17"; + case 0x03c2: return "pmpaddr18"; + case 0x03c3: return "pmpaddr19"; + case 0x03c4: return "pmpaddr20"; + case 0x03c5: return "pmpaddr21"; + case 0x03c6: return "pmpaddr22"; + case 0x03c7: return "pmpaddr23"; + case 0x03c8: return "pmpaddr24"; + case 0x03c9: return "pmpaddr25"; + case 0x03ca: return "pmpaddr26"; + case 0x03cb: return "pmpaddr27"; + case 0x03cc: return "pmpaddr28"; + case 0x03cd: return "pmpaddr29"; + case 0x03ce: return "pmpaddr30"; + case 0x03cf: return "pmpaddr31"; + case 0x03d0: return "pmpaddr32"; + case 0x03d1: return "pmpaddr33"; + case 0x03d2: return "pmpaddr34"; + case 0x03d3: return "pmpaddr35"; + case 0x03d4: return "pmpaddr36"; + case 0x03d5: return "pmpaddr37"; + case 0x03d6: return "pmpaddr38"; + case 0x03d7: return "pmpaddr39"; + case 0x03d8: return "pmpaddr40"; + case 0x03d9: return "pmpaddr41"; + case 0x03da: return "pmpaddr42"; + case 0x03db: return "pmpaddr43"; + case 0x03dc: return "pmpaddr44"; + case 0x03dd: return "pmpaddr45"; + case 0x03de: return "pmpaddr46"; + case 0x03df: return "pmpaddr47"; + case 0x03e0: return "pmpaddr48"; + case 0x03e1: return "pmpaddr49"; + case 0x03e2: return "pmpaddr50"; + case 0x03e3: return "pmpaddr51"; + case 0x03e4: return "pmpaddr52"; + case 0x03e5: return "pmpaddr53"; + case 0x03e6: return "pmpaddr54"; + case 0x03e7: return "pmpaddr55"; + case 0x03e8: return "pmpaddr56"; + case 0x03e9: return "pmpaddr57"; + case 0x03ea: return "pmpaddr58"; + case 0x03eb: return "pmpaddr59"; + case 0x03ec: return "pmpaddr60"; + case 0x03ed: return "pmpaddr61"; + case 0x03ee: return "pmpaddr62"; + case 0x03ef: return "pmpaddr63"; case 0x0780: return "mtohost"; case 0x0781: return "mfromhost"; case 0x0782: return "mreset"; diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 8d428c64b0..8d3518e887 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -219,15 +219,15 @@ def _nodes_for_enum_values(self, doc): section += dlnode return [section] - def _nodes_for_arguments(self, doc, boxed_arg_type): + def _nodes_for_arguments(self, doc, arg_type): """Return list of doctree nodes for the arguments section""" - if boxed_arg_type: + if arg_type and not arg_type.is_implicit(): assert not doc.args section = self._make_section('Arguments') dlnode = nodes.definition_list() dlnode += self._make_dlitem( [nodes.Text('The members of '), - nodes.literal('', boxed_arg_type.name)], + nodes.literal('', arg_type.name)], None) section += dlnode return [section] @@ -331,8 +331,7 @@ def visit_command(self, name, info, ifcond, features, arg_type, allow_preconfig, coroutine): doc = self._cur_doc self._add_doc('Command', - self._nodes_for_arguments(doc, - arg_type if boxed else None) + self._nodes_for_arguments(doc, arg_type) + self._nodes_for_features(doc) + self._nodes_for_sections(doc) + self._nodes_for_if_section(ifcond)) @@ -340,8 +339,7 @@ def visit_command(self, name, info, ifcond, features, arg_type, def visit_event(self, name, info, ifcond, features, arg_type, boxed): doc = self._cur_doc self._add_doc('Event', - self._nodes_for_arguments(doc, - arg_type if boxed else None) + self._nodes_for_arguments(doc, arg_type) + self._nodes_for_features(doc) + self._nodes_for_sections(doc) + self._nodes_for_if_section(ifcond)) diff --git a/docs/system/target-i386-desc.rst.inc b/docs/system/target-i386-desc.rst.inc index 5ebbcda9db..319e540573 100644 --- a/docs/system/target-i386-desc.rst.inc +++ b/docs/system/target-i386-desc.rst.inc @@ -36,7 +36,7 @@ The QEMU PC System emulator simulates the following peripherals: - PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1 hub. -SMP is supported with up to 255 CPUs. +SMP is supported with up to 255 CPUs (and 4096 CPUs for PC Q35 machine). QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL VGA BIOS. diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index cc68b5d8f1..9f2d96c733 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -24,6 +24,7 @@ #include "hw/qdev-clock.h" #include "hw/qdev-properties.h" #include "qapi/error.h" +#include "qemu/bswap.h" #include "qemu/units.h" #include "sysemu/sysemu.h" #include "target/arm/cpu-qom.h" @@ -386,7 +387,7 @@ static void npcm7xx_init_fuses(NPCM7xxState *s) * The initial mask of disabled modules indicates the chip derivative (e.g. * NPCM750 or NPCM730). */ - value = tswap32(nc->disabled_modules); + value = cpu_to_le32(nc->disabled_modules); npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE, sizeof(value)); } diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c index c80b58bf5d..4a56c00ec9 100644 --- a/hw/audio/virtio-snd.c +++ b/hw/audio/virtio-snd.c @@ -401,7 +401,7 @@ static void virtio_snd_get_qemu_audsettings(audsettings *as, as->nchannels = MIN(AUDIO_MAX_CHANNELS, params->channels); as->fmt = virtio_snd_get_qemu_format(params->format); as->freq = virtio_snd_get_qemu_freq(params->rate); - as->endianness = target_words_bigendian() ? 1 : 0; + as->endianness = 0; /* Conforming to VIRTIO 1.0: always little endian. */ } /* diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 1bda8424b9..c8f1cf5a87 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -518,10 +518,6 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, break; case 0xe8: /* Write to buffer */ trace_pflash_write(pfl->name, "write to buffer"); - /* FIXME should save @offset, @width for case 1+ */ - qemu_log_mask(LOG_UNIMP, - "%s: Write to buffer emulation is flawed\n", - __func__); pfl->status |= 0x80; /* Ready! */ break; case 0xf0: /* Probe for AMD flash */ @@ -574,7 +570,6 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, } pfl->counter = value; pfl->wcycle++; - pflash_blk_write_start(pfl, offset); break; case 0x60: if (cmd == 0xd0) { @@ -605,6 +600,9 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, switch (pfl->cmd) { case 0xe8: /* Block write */ /* FIXME check @offset, @width */ + if (pfl->blk_offset == -1 && pfl->counter) { + pflash_blk_write_start(pfl, offset); + } if (!pfl->ro && (pfl->blk_offset != -1)) { pflash_data_write(pfl, offset, value, width, be); } else { diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 27864c9507..b5e3849d3d 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -112,62 +112,38 @@ void machine_parse_smp_config(MachineState *ms, } /* - * If not supported by the machine, a topology parameter must be - * omitted. + * If not supported by the machine, a topology parameter must + * not be set to a value greater than 1. */ - if (!mc->smp_props.clusters_supported && config->has_clusters) { - if (config->clusters > 1) { - error_setg(errp, "clusters not supported by this " - "machine's CPU topology"); - return; - } else { - /* Here clusters only equals 1 since we've checked zero case. */ - warn_report("Deprecated CPU topology (considered invalid): " - "Unsupported clusters parameter mustn't be " - "specified as 1"); - } + if (!mc->smp_props.clusters_supported && + config->has_clusters && config->clusters > 1) { + error_setg(errp, + "clusters > 1 not supported by this machine's CPU topology"); + return; } clusters = clusters > 0 ? clusters : 1; - if (!mc->smp_props.dies_supported && config->has_dies) { - if (config->dies > 1) { - error_setg(errp, "dies not supported by this " - "machine's CPU topology"); - return; - } else { - /* Here dies only equals 1 since we've checked zero case. */ - warn_report("Deprecated CPU topology (considered invalid): " - "Unsupported dies parameter mustn't be " - "specified as 1"); - } + if (!mc->smp_props.dies_supported && + config->has_dies && config->dies > 1) { + error_setg(errp, + "dies > 1 not supported by this machine's CPU topology"); + return; } dies = dies > 0 ? dies : 1; - if (!mc->smp_props.books_supported && config->has_books) { - if (config->books > 1) { - error_setg(errp, "books not supported by this " - "machine's CPU topology"); - return; - } else { - /* Here books only equals 1 since we've checked zero case. */ - warn_report("Deprecated CPU topology (considered invalid): " - "Unsupported books parameter mustn't be " - "specified as 1"); - } + if (!mc->smp_props.books_supported && + config->has_books && config->books > 1) { + error_setg(errp, + "books > 1 not supported by this machine's CPU topology"); + return; } books = books > 0 ? books : 1; - if (!mc->smp_props.drawers_supported && config->has_drawers) { - if (config->drawers > 1) { - error_setg(errp, "drawers not supported by this " - "machine's CPU topology"); - return; - } else { - /* Here drawers only equals 1 since we've checked zero case. */ - warn_report("Deprecated CPU topology (considered invalid): " - "Unsupported drawers parameter mustn't be " - "specified as 1"); - } + if (!mc->smp_props.drawers_supported && + config->has_drawers && config->drawers > 1) { + error_setg(errp, + "drawers > 1 not supported by this machine's CPU topology"); + return; } drawers = drawers > 0 ? drawers : 1; diff --git a/hw/core/machine.c b/hw/core/machine.c index 37ede0e7d4..4273de16a0 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -37,6 +37,7 @@ GlobalProperty hw_compat_8_2[] = { { "migration", "zero-page-detection", "legacy"}, { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" }, { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, + { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, }; const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2); @@ -45,15 +46,15 @@ GlobalProperty hw_compat_8_1[] = { { "ramfb", "x-migrate", "off" }, { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }, { "igb", "x-pcie-flr-init", "off" }, + { TYPE_VIRTIO_NET, "host_uso", "off"}, + { TYPE_VIRTIO_NET, "guest_uso4", "off"}, + { TYPE_VIRTIO_NET, "guest_uso6", "off"}, }; const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1); GlobalProperty hw_compat_8_0[] = { { "migration", "multifd-flush-after-each-section", "on"}, { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" }, - { TYPE_VIRTIO_NET, "host_uso", "off"}, - { TYPE_VIRTIO_NET, "guest_uso4", "off"}, - { TYPE_VIRTIO_NET, "guest_uso6", "off"}, }; const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0); diff --git a/hw/display/vga.c b/hw/display/vga.c index 77f59e8c11..40adeb3e2f 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1772,6 +1772,13 @@ static void vga_draw_blank(VGACommonState *s, int full_update) if (s->last_scr_width <= 0 || s->last_scr_height <= 0) return; + if (is_buffer_shared(surface)) { + /* unshare buffer, otherwise the blanking corrupts vga vram */ + surface = qemu_create_displaysurface(s->last_scr_width, + s->last_scr_height); + dpy_gfx_replace_surface(s->con, surface); + } + w = s->last_scr_width * surface_bytes_per_pixel(surface); d = surface_data(surface); for(i = 0; i < s->last_scr_height; i++) { diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index ae831b6b3e..d60b1b2973 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -1166,10 +1166,17 @@ static void virtio_gpu_cursor_bh(void *opaque) virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq); } +static bool scanout_vmstate_after_v2(void *opaque, int version) +{ + struct VirtIOGPUBase *base = container_of(opaque, VirtIOGPUBase, scanout); + struct VirtIOGPU *gpu = container_of(base, VirtIOGPU, parent_obj); + + return gpu->scanout_vmstate_version >= 2; +} + static const VMStateDescription vmstate_virtio_gpu_scanout = { .name = "virtio-gpu-one-scanout", - .version_id = 2, - .minimum_version_id = 1, + .version_id = 1, .fields = (const VMStateField[]) { VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout), VMSTATE_UINT32(width, struct virtio_gpu_scanout), @@ -1181,12 +1188,18 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = { VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout), VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout), VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout), - VMSTATE_UINT32_V(fb.format, struct virtio_gpu_scanout, 2), - VMSTATE_UINT32_V(fb.bytes_pp, struct virtio_gpu_scanout, 2), - VMSTATE_UINT32_V(fb.width, struct virtio_gpu_scanout, 2), - VMSTATE_UINT32_V(fb.height, struct virtio_gpu_scanout, 2), - VMSTATE_UINT32_V(fb.stride, struct virtio_gpu_scanout, 2), - VMSTATE_UINT32_V(fb.offset, struct virtio_gpu_scanout, 2), + VMSTATE_UINT32_TEST(fb.format, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), + VMSTATE_UINT32_TEST(fb.bytes_pp, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), + VMSTATE_UINT32_TEST(fb.width, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), + VMSTATE_UINT32_TEST(fb.height, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), + VMSTATE_UINT32_TEST(fb.stride, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), + VMSTATE_UINT32_TEST(fb.offset, struct virtio_gpu_scanout, + scanout_vmstate_after_v2), VMSTATE_END_OF_LIST() }, }; @@ -1659,6 +1672,7 @@ static Property virtio_gpu_properties[] = { DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags, VIRTIO_GPU_FLAG_BLOB_ENABLED, false), DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0), + DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c index 1f5cd64ed1..530717d188 100644 --- a/hw/dma/xlnx_dpdma.c +++ b/hw/dma/xlnx_dpdma.c @@ -175,24 +175,24 @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc, switch (frag) { case 0: - addr = desc->source_address - + (extract32(desc->address_extension, 16, 12) << 20); + addr = (uint64_t)desc->source_address + + (extract64(desc->address_extension, 16, 16) << 32); break; case 1: - addr = desc->source_address2 - + (extract32(desc->address_extension_23, 0, 12) << 8); + addr = (uint64_t)desc->source_address2 + + (extract64(desc->address_extension_23, 0, 16) << 32); break; case 2: - addr = desc->source_address3 - + (extract32(desc->address_extension_23, 16, 12) << 20); + addr = (uint64_t)desc->source_address3 + + (extract64(desc->address_extension_23, 16, 16) << 32); break; case 3: - addr = desc->source_address4 - + (extract32(desc->address_extension_45, 0, 12) << 8); + addr = (uint64_t)desc->source_address4 + + (extract64(desc->address_extension_45, 0, 16) << 32); break; case 4: - addr = desc->source_address5 - + (extract32(desc->address_extension_45, 16, 12) << 20); + addr = (uint64_t)desc->source_address5 + + (extract64(desc->address_extension_45, 16, 16) << 32); break; default: addr = 0; diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 074cf50af2..e4b8437f8b 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -1658,7 +1658,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, *data = s->h_apr[gic_get_vcpu_real_id(cpu)]; } else if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ - *data = gic_apr_ns_view(s, regno, cpu); + *data = gic_apr_ns_view(s, cpu, regno); } else { *data = s->apr[regno][cpu]; } @@ -1746,7 +1746,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, s->h_apr[gic_get_vcpu_real_id(cpu)] = value; } else if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ - gic_apr_write_ns_view(s, regno, cpu, value); + gic_apr_write_ns_view(s, cpu, regno, value); } else { s->apr[regno][cpu] = value; } diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index fc5df0d598..32edd6d07b 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -1000,16 +1000,16 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, qdev_prop_set_bit(dev, "msimode", msimode); qdev_prop_set_bit(dev, "mmode", mmode); + if (parent) { + riscv_aplic_add_child(parent, dev); + } + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); if (!is_kvm_aia(msimode)) { sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); } - if (parent) { - riscv_aplic_add_child(parent, dev); - } - if (!msimode) { for (i = 0; i < num_harts; i++) { CPUState *cpu = cpu_by_arch_id(hartid_base + i); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 441d764843..83d3d7522f 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -333,7 +333,8 @@ static void fdt_add_memory_node(MachineState *ms, char *nodename = g_strdup_printf("/memory@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); - qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size); + qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", base >> 32, base, + size >> 32, size); qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory"); if (ms->numa_state && ms->numa_state->num_nodes) { @@ -832,7 +833,6 @@ static void loongarch_init(MachineState *machine) const CPUArchIdList *possible_cpus; MachineClass *mc = MACHINE_GET_CLASS(machine); CPUState *cpu; - char *ramName = NULL; struct loaderparams loaderparams = { }; if (!cpu_model) { @@ -892,7 +892,7 @@ static void loongarch_init(MachineState *machine) for (i = 1; i < nb_numa_nodes; i++) { MemoryRegion *nodemem = g_new(MemoryRegion, 1); - ramName = g_strdup_printf("loongarch.node%d.ram", i); + g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i); memory_region_init_alias(nodemem, NULL, ramName, machine->ram, offset, numa_info[i].node_mem); memory_region_add_subregion(address_space_mem, phyAddr, nodemem); diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 24e5e7d347..3644bfd91b 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2749,18 +2749,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) out_sg = elem->out_sg; if (out_num < 1) { virtio_error(vdev, "virtio-net header not in first element"); - virtqueue_detach_element(q->tx_vq, elem, 0); - g_free(elem); - return -EINVAL; + goto detach; } if (n->has_vnet_hdr) { if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) < n->guest_hdr_len) { virtio_error(vdev, "virtio-net header incorrect"); - virtqueue_detach_element(q->tx_vq, elem, 0); - g_free(elem); - return -EINVAL; + goto detach; } if (n->needs_vnet_hdr_swap) { virtio_net_hdr_swap(vdev, (void *) &vhdr); @@ -2791,6 +2787,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) n->guest_hdr_len, -1); out_num = sg_num; out_sg = sg; + + if (out_num < 1) { + virtio_error(vdev, "virtio-net nothing to send"); + goto detach; + } } ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index), @@ -2811,6 +2812,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) } } return num_packets; + +detach: + virtqueue_detach_element(q->tx_vq, elem, 0); + g_free(elem); + return -EINVAL; } static void virtio_net_tx_timer(void *opaque); diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 127c3d2383..e89f9f7808 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4352,7 +4352,7 @@ static uint16_t nvme_io_mgmt_send_ruh_update(NvmeCtrl *n, NvmeRequest *req) NvmeNamespace *ns = req->ns; uint32_t cdw10 = le32_to_cpu(cmd->cdw10); uint16_t ret = NVME_SUCCESS; - uint32_t npid = (cdw10 >> 1) + 1; + uint32_t npid = (cdw10 >> 16) + 1; unsigned int i = 0; g_autofree uint16_t *pids = NULL; uint32_t maxnpid; diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index d9b879e056..8dbafafb9e 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -281,7 +281,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, while (bytes > 0) { len = (bytes > pci_access_width) ? pci_access_width : bytes; if (is_write) { - memcpy(&val, ptr, len); + val = ldn_le_p(ptr, len); pci_host_config_write_common(o->pci_dev, offset, pci_config_size(o->pci_dev), val, len); @@ -289,7 +289,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, } else { val = pci_host_config_read_common(o->pci_dev, offset, pci_config_size(o->pci_dev), len); - memcpy(ptr, &val, len); + stn_le_p(ptr, len, val); trace_vfu_cfg_read(offset, val); } offset += len; diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index eccdb852a0..bac78a32bb 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -126,6 +126,10 @@ static MemTxResult ufs_dma_read_req_upiu(UfsRequest *req) copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE + data_segment_length; + if (copy_size > sizeof(req->req_upiu)) { + copy_size = sizeof(req->req_upiu); + } + ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size); if (ret) { trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr); @@ -225,6 +229,10 @@ static MemTxResult ufs_dma_write_rsp_upiu(UfsRequest *req) copy_size = rsp_upiu_byte_len; } + if (copy_size > sizeof(req->rsp_upiu)) { + copy_size = sizeof(req->rsp_upiu); + } + ret = ufs_addr_write(u, rsp_upiu_base_addr, &req->rsp_upiu, copy_size); if (ret) { trace_ufs_err_dma_write_rsp_upiu(req->slot, rsp_upiu_base_addr); diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index cb159fd078..e04218a9fb 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -892,7 +892,7 @@ static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) } ret = kvm_virtio_pci_vq_vector_use(proxy, vector); if (ret < 0) { - goto undo; + return ret; } /* * If guest supports masking, set up irqfd now. @@ -902,25 +902,11 @@ static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); if (ret < 0) { kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; + return ret; } } return 0; -undo: - - vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - return ret; - } - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); - if (ret < 0) { - return ret; - } - kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - return ret; } static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) { diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 871674f9be..fd2dfe3a6b 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -322,7 +322,6 @@ static void vring_packed_event_read(VirtIODevice *vdev, /* Make sure flags is seen before off_wrap */ smp_rmb(); e->off_wrap = virtio_lduw_phys_cached(vdev, cache, off_off); - virtio_tswap16s(vdev, &e->flags); } static void vring_packed_off_wrap_write(VirtIODevice *vdev, diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index ed44cdad6b..842315d51d 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -177,6 +177,7 @@ typedef struct VGPUDMABuf { struct VirtIOGPU { VirtIOGPUBase parent_obj; + uint8_t scanout_vmstate_version; uint64_t conf_max_hostmem; VirtQueue *ctrl_vq; diff --git a/io/channel-tls.c b/io/channel-tls.c index 1d9c9c72bf..67b9700006 100644 --- a/io/channel-tls.c +++ b/io/channel-tls.c @@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master, const char *aclname, Error **errp) { - QIOChannelTLS *ioc; + QIOChannelTLS *tioc; + QIOChannel *ioc; - ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); + tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); + ioc = QIO_CHANNEL(tioc); - ioc->master = master; + tioc->master = master; + ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { - qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN); + qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); } object_ref(OBJECT(master)); - ioc->session = qcrypto_tls_session_new( + tioc->session = qcrypto_tls_session_new( creds, NULL, aclname, QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, errp); - if (!ioc->session) { + if (!tioc->session) { goto error; } qcrypto_tls_session_set_callbacks( - ioc->session, + tioc->session, qio_channel_tls_write_handler, qio_channel_tls_read_handler, - ioc); + tioc); - trace_qio_channel_tls_new_server(ioc, master, creds, aclname); - return ioc; + trace_qio_channel_tls_new_server(tioc, master, creds, aclname); + return tioc; error: - object_unref(OBJECT(ioc)); + object_unref(OBJECT(tioc)); return NULL; } @@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master, ioc = QIO_CHANNEL(tioc); tioc->master = master; + ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); } diff --git a/io/channel-websock.c b/io/channel-websock.c index a12acc27cf..de39f0d182 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master) ioc = QIO_CHANNEL(wioc); wioc->master = master; + ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 75764f7a8f..4a38999a73 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2284,18 +2284,13 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, switch (optname) { case ALG_SET_KEY: { - char *alg_key = g_malloc(optlen); - + char *alg_key = lock_user(VERIFY_READ, optval_addr, optlen, 1); if (!alg_key) { - return -TARGET_ENOMEM; - } - if (copy_from_user(alg_key, optval_addr, optlen)) { - g_free(alg_key); return -TARGET_EFAULT; } ret = get_errno(setsockopt(sockfd, level, optname, alg_key, optlen)); - g_free(alg_key); + unlock_user(alg_key, optval_addr, optlen); break; } case ALG_SET_AEAD_AUTHSIZE: @@ -7222,11 +7217,17 @@ static inline int tswapid(int id) #else #define __NR_sys_setresgid __NR_setresgid #endif +#ifdef __NR_setgroups32 +#define __NR_sys_setgroups __NR_setgroups32 +#else +#define __NR_sys_setgroups __NR_setgroups +#endif _syscall1(int, sys_setuid, uid_t, uid) _syscall1(int, sys_setgid, gid_t, gid) _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) +_syscall2(int, sys_setgroups, int, size, gid_t *, grouplist) void syscall_init(void) { @@ -11907,7 +11908,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id)); } - return get_errno(setgroups(gidsetsize, grouplist)); + return get_errno(sys_setgroups(gidsetsize, grouplist)); } case TARGET_NR_fchown: return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); @@ -12243,7 +12244,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, } unlock_user(target_grouplist, arg2, 0); } - return get_errno(setgroups(gidsetsize, grouplist)); + return get_errno(sys_setgroups(gidsetsize, grouplist)); } #endif #ifdef TARGET_NR_fchown32 diff --git a/migration/colo.c b/migration/colo.c index 84632a603e..5600a43d78 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -835,6 +835,16 @@ static void *colo_process_incoming_thread(void *opaque) return NULL; } + /* Make sure all file formats throw away their mutable metadata */ + bql_lock(); + bdrv_activate_all(&local_err); + if (local_err) { + bql_unlock(); + error_report_err(local_err); + return NULL; + } + bql_unlock(); + failover_init_state(); mis->to_src_file = qemu_file_get_return_path(mis->from_src_file); @@ -922,7 +932,6 @@ static void *colo_process_incoming_thread(void *opaque) int coroutine_fn colo_incoming_co(void) { MigrationIncomingState *mis = migration_incoming_get_current(); - Error *local_err = NULL; QemuThread th; assert(bql_locked()); @@ -931,13 +940,6 @@ int coroutine_fn colo_incoming_co(void) return 0; } - /* Make sure all file formats throw away their mutable metadata */ - bdrv_activate_all(&local_err); - if (local_err) { - error_report_err(local_err); - return -EINVAL; - } - qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread, mis, QEMU_THREAD_JOINABLE); diff --git a/migration/file.c b/migration/file.c index ab18ba505a..ba5b5c44ff 100644 --- a/migration/file.c +++ b/migration/file.c @@ -84,12 +84,19 @@ void file_start_outgoing_migration(MigrationState *s, trace_migration_file_outgoing(filename); - fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC, - 0600, errp); + fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY, 0600, errp); if (!fioc) { return; } + if (ftruncate(fioc->fd, offset)) { + error_setg_errno(errp, errno, + "failed to truncate migration file to offset %" PRIx64, + offset); + object_unref(OBJECT(fioc)); + return; + } + outgoing_args.fname = g_strdup(filename); ioc = QIO_CHANNEL(fioc); diff --git a/nbd/client.c b/nbd/client.c index 29ffc609a4..c89c750467 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict, return 1; } +/* Callback to learn when QIO TLS upgrade is complete */ +struct NBDTLSClientHandshakeData { + bool complete; + Error *error; + GMainLoop *loop; +}; + +static void nbd_client_tls_handshake(QIOTask *task, void *opaque) +{ + struct NBDTLSClientHandshakeData *data = opaque; + + qio_task_propagate_error(task, &data->error); + data->complete = true; + if (data->loop) { + g_main_loop_quit(data->loop); + } +} + static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, const char *hostname, Error **errp) { int ret; QIOChannelTLS *tioc; - struct NBDTLSHandshakeData data = { 0 }; + struct NBDTLSClientHandshakeData data = { 0 }; ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp); if (ret <= 0) { @@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, return NULL; } qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); - data.loop = g_main_loop_new(g_main_context_default(), FALSE); trace_nbd_receive_starttls_tls_handshake(); qio_channel_tls_handshake(tioc, - nbd_tls_handshake, + nbd_client_tls_handshake, &data, NULL, NULL); if (!data.complete) { + data.loop = g_main_loop_new(g_main_context_default(), FALSE); g_main_loop_run(data.loop); + assert(data.complete); + g_main_loop_unref(data.loop); } - g_main_loop_unref(data.loop); + if (data.error) { error_propagate(errp, data.error); object_unref(OBJECT(tioc)); diff --git a/nbd/common.c b/nbd/common.c index 3247c1d618..589a748cfe 100644 --- a/nbd/common.c +++ b/nbd/common.c @@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp) } -void nbd_tls_handshake(QIOTask *task, - void *opaque) -{ - struct NBDTLSHandshakeData *data = opaque; - - qio_task_propagate_error(task, &data->error); - data->complete = true; - g_main_loop_quit(data->loop); -} - - const char *nbd_opt_lookup(uint32_t opt) { switch (opt) { diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index dfa02f77ee..91895106a9 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size, return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; } -struct NBDTLSHandshakeData { - GMainLoop *loop; - bool complete; - Error *error; -}; - - -void nbd_tls_handshake(QIOTask *task, - void *opaque); - int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); #endif diff --git a/nbd/server.c b/nbd/server.c index c3484cc1eb..892797bb11 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -195,8 +195,9 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option, /* Send a reply header, including length, but no payload. * Return -errno on error, 0 on success. */ -static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, - uint32_t len, Error **errp) +static coroutine_fn int +nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, + uint32_t len, Error **errp) { NBDOptionReply rep; @@ -211,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, /* Send a reply header with default 0 length. * Return -errno on error, 0 on success. */ -static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type, - Error **errp) +static coroutine_fn int +nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp) { return nbd_negotiate_send_rep_len(client, type, 0, errp); } /* Send an error reply. * Return -errno on error, 0 on success. */ -static int G_GNUC_PRINTF(4, 0) +static coroutine_fn int G_GNUC_PRINTF(4, 0) nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type, Error **errp, const char *fmt, va_list va) { @@ -259,7 +260,7 @@ nbd_sanitize_name(const char *name) /* Send an error reply. * Return -errno on error, 0 on success. */ -static int G_GNUC_PRINTF(4, 5) +static coroutine_fn int G_GNUC_PRINTF(4, 5) nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type, Error **errp, const char *fmt, ...) { @@ -275,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type, /* Drop remainder of the current option, and send a reply with the * given error type and message. Return -errno on read or write * failure; or 0 if connection is still live. */ -static int G_GNUC_PRINTF(4, 0) +static coroutine_fn int G_GNUC_PRINTF(4, 0) nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp, const char *fmt, va_list va) { @@ -288,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp, return ret; } -static int G_GNUC_PRINTF(4, 5) +static coroutine_fn int G_GNUC_PRINTF(4, 5) nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp, const char *fmt, ...) { @@ -302,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp, return ret; } -static int G_GNUC_PRINTF(3, 4) +static coroutine_fn int G_GNUC_PRINTF(3, 4) nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) { int ret; @@ -319,8 +320,9 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) * If @check_nul, require that no NUL bytes appear in buffer. * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, - bool check_nul, Error **errp) +static coroutine_fn int +nbd_opt_read(NBDClient *client, void *buffer, size_t size, + bool check_nul, Error **errp) { if (size > client->optlen) { return nbd_opt_invalid(client, errp, @@ -343,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, /* Drop size bytes from the unparsed payload of the current option. * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp) +static coroutine_fn int +nbd_opt_skip(NBDClient *client, size_t size, Error **errp) { if (size > client->optlen) { return nbd_opt_invalid(client, errp, @@ -366,8 +369,9 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp) * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, - Error **errp) +static coroutine_fn int +nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, + Error **errp) { int ret; uint32_t len; @@ -402,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, /* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload. * Return -errno on error, 0 on success. */ -static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, - Error **errp) +static coroutine_fn int +nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp) { ERRP_GUARD(); size_t name_len, desc_len; @@ -444,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, /* Process the NBD_OPT_LIST command, with a potential series of replies. * Return -errno on error, 0 on success. */ -static int nbd_negotiate_handle_list(NBDClient *client, Error **errp) +static coroutine_fn int +nbd_negotiate_handle_list(NBDClient *client, Error **errp) { NBDExport *exp; assert(client->opt == NBD_OPT_LIST); @@ -459,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp) return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); } -static void nbd_check_meta_export(NBDClient *client, NBDExport *exp) +static coroutine_fn void +nbd_check_meta_export(NBDClient *client, NBDExport *exp) { if (exp != client->contexts.exp) { client->contexts.count = 0; @@ -468,8 +474,9 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp) /* Send a reply to NBD_OPT_EXPORT_NAME. * Return -errno on error, 0 on success. */ -static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, - Error **errp) +static coroutine_fn int +nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, + Error **errp) { ERRP_GUARD(); g_autofree char *name = NULL; @@ -536,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, /* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes. * The buffer does NOT include the info type prefix. * Return -errno on error, 0 if ready to send more. */ -static int nbd_negotiate_send_info(NBDClient *client, - uint16_t info, uint32_t length, void *buf, - Error **errp) +static coroutine_fn int +nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length, + void *buf, Error **errp) { int rc; @@ -565,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client, * -errno transmission error occurred or @fatal was requested, errp is set * 0 error message successfully sent to client, errp is not set */ -static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp) +static coroutine_fn int +nbd_reject_length(NBDClient *client, bool fatal, Error **errp) { int ret; @@ -583,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp) /* Handle NBD_OPT_INFO and NBD_OPT_GO. * Return -errno on error, 0 if ready for next option, and 1 to move * into transmission phase. */ -static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) +static coroutine_fn int +nbd_negotiate_handle_info(NBDClient *client, Error **errp) { int rc; g_autofree char *name = NULL; @@ -748,15 +757,33 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) return rc; } +/* Callback to learn when QIO TLS upgrade is complete */ +struct NBDTLSServerHandshakeData { + bool complete; + Error *error; + Coroutine *co; +}; + +static void +nbd_server_tls_handshake(QIOTask *task, void *opaque) +{ + struct NBDTLSServerHandshakeData *data = opaque; + + qio_task_propagate_error(task, &data->error); + data->complete = true; + if (!qemu_coroutine_entered(data->co)) { + aio_co_wake(data->co); + } +} /* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the * new channel for all further (now-encrypted) communication. */ -static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, - Error **errp) +static coroutine_fn QIOChannel * +nbd_negotiate_handle_starttls(NBDClient *client, Error **errp) { QIOChannel *ioc; QIOChannelTLS *tioc; - struct NBDTLSHandshakeData data = { 0 }; + struct NBDTLSServerHandshakeData data = { 0 }; assert(client->opt == NBD_OPT_STARTTLS); @@ -777,17 +804,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls"); trace_nbd_negotiate_handle_starttls_handshake(); - data.loop = g_main_loop_new(g_main_context_default(), FALSE); + data.co = qemu_coroutine_self(); qio_channel_tls_handshake(tioc, - nbd_tls_handshake, + nbd_server_tls_handshake, &data, NULL, NULL); if (!data.complete) { - g_main_loop_run(data.loop); + qemu_coroutine_yield(); + assert(data.complete); } - g_main_loop_unref(data.loop); + if (data.error) { object_unref(OBJECT(tioc)); error_propagate(errp, data.error); @@ -803,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, * * For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead. */ -static int nbd_negotiate_send_meta_context(NBDClient *client, - const char *context, - uint32_t context_id, - Error **errp) +static coroutine_fn int +nbd_negotiate_send_meta_context(NBDClient *client, const char *context, + uint32_t context_id, Error **errp) { NBDOptionReplyMetaContext opt; struct iovec iov[] = { @@ -831,8 +858,9 @@ static int nbd_negotiate_send_meta_context(NBDClient *client, * Return true if @query matches @pattern, or if @query is empty when * the @client is performing _LIST_. */ -static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, - const char *query) +static coroutine_fn bool +nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, + const char *query) { if (!*query) { trace_nbd_negotiate_meta_query_parse("empty"); @@ -849,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, /* * Return true and adjust @str in place if it begins with @prefix. */ -static bool nbd_strshift(const char **str, const char *prefix) +static coroutine_fn bool +nbd_strshift(const char **str, const char *prefix) { size_t len = strlen(prefix); @@ -865,8 +894,9 @@ static bool nbd_strshift(const char **str, const char *prefix) * Handle queries to 'base' namespace. For now, only the base:allocation * context is available. Return true if @query has been handled. */ -static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, - const char *query) +static coroutine_fn bool +nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, + const char *query) { if (!nbd_strshift(&query, "base:")) { return false; @@ -885,8 +915,9 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, * and qemu:allocation-depth contexts are available. Return true if @query * has been handled. */ -static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, - const char *query) +static coroutine_fn bool +nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, + const char *query) { size_t i; @@ -950,8 +981,9 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, * * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_negotiate_meta_query(NBDClient *client, - NBDMetaContexts *meta, Error **errp) +static coroutine_fn int +nbd_negotiate_meta_query(NBDClient *client, + NBDMetaContexts *meta, Error **errp) { int ret; g_autofree char *query = NULL; @@ -990,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client, * Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT * * Return -errno on I/O error, or 0 if option was completely handled. */ -static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp) +static coroutine_fn int +nbd_negotiate_meta_queries(NBDClient *client, Error **errp) { int ret; g_autofree char *export_name = NULL; @@ -1118,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp) * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, * errp is not set */ -static int nbd_negotiate_options(NBDClient *client, Error **errp) +static coroutine_fn int +nbd_negotiate_options(NBDClient *client, Error **errp) { uint32_t flags; bool fixedNewstyle = false; diff --git a/plugins/core.c b/plugins/core.c index 11ca20e626..09c98382f5 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -373,7 +373,7 @@ void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb) struct qemu_plugin_cb *cb, *next; enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_TB_TRANS; - /* no plugin_mask check here; caller should have checked */ + /* no plugin_state->event_mask check here; caller should have checked */ QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) { qemu_plugin_vcpu_tb_trans_cb_t func = cb->f.vcpu_tb_trans; diff --git a/qapi/block-core.json b/qapi/block-core.json index 746d1694c2..4b18e01b85 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1671,8 +1671,6 @@ # # Takes a synchronous snapshot of a block device. # -# For the arguments, see the documentation of BlockdevSnapshotSync. -# # Errors: # - If @device is not a valid block device, DeviceNotFound # @@ -1701,8 +1699,6 @@ # device, the block device changes to using 'overlay' as its new # active image. # -# For the arguments, see the documentation of BlockdevSnapshot. -# # Features: # # @allow-write-only-overlay: If present, the check whether this @@ -6061,9 +6057,6 @@ # string, or a snapshot with name already exists, the operation will # fail. # -# For the arguments, see the documentation of -# BlockdevSnapshotInternal. -# # Errors: # - If @device is not a valid block device, GenericError # - If any snapshot matching @name exists, or @name is empty, diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index f3488afeef..176b549473 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -212,7 +212,8 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ * executing the command handler so that it can make progress if it * involves an AIO_WAIT_WHILE(). */ - aio_co_reschedule_self(qemu_get_aio_context()); + aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self()); + qemu_coroutine_yield(); } monitor_set_cur(qemu_coroutine_self(), cur_mon); @@ -226,7 +227,9 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ * Move back to iohandler_ctx so that nested event loops for * qemu_aio_context don't start new monitor commands. */ - aio_co_reschedule_self(iohandler_get_aio_context()); + aio_co_schedule(iohandler_get_aio_context(), + qemu_coroutine_self()); + qemu_coroutine_yield(); } } else { /* diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index d783bf54c6..5a26ef3d40 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -109,7 +109,11 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) * No explicit bits enabled, and no implicit bits from sve-max-vq. */ if (!cpu_isar_feature(aa64_sve, cpu)) { - /* SVE is disabled and so are all vector lengths. Good. */ + /* + * SVE is disabled and so are all vector lengths. Good. + * Disable all SVE extensions as well. + */ + cpu->isar.id_aa64zfr0 = 0; return; } diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 65a5601804..ee657f455b 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -397,85 +397,85 @@ struct hvf_sreg_match { }; static struct hvf_sreg_match hvf_sreg_match[] = { - { HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) }, - - { HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) }, - { HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) }, - { HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) }, - { HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) }, + { HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 7) }, + + { HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 4) }, + { HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 5) }, + { HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 6) }, + { HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 7) }, #ifdef SYNC_NO_RAW_REGS /* @@ -487,7 +487,7 @@ static struct hvf_sreg_match hvf_sreg_match[] = { { HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) }, { HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) }, #endif - { HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) }, + { HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 1) }, { HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) }, { HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) }, { HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) }, diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c index 5da1b0fc1d..f03977b4b0 100644 --- a/target/arm/tcg/hflags.c +++ b/target/arm/tcg/hflags.c @@ -38,8 +38,16 @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr) } /* - * If translation is disabled, then the default memory type is - * Device(-nGnRnE) instead of Normal, which requires that alignment + * With PMSA, when the MPU is disabled, all memory types in the + * default map are Normal, so don't need aligment enforcing. + */ + if (arm_feature(env, ARM_FEATURE_PMSA)) { + return false; + } + + /* + * With VMSA, if translation is disabled, then the default memory type + * is Device(-nGnRnE) instead of Normal, which requires that alignment * be enforced. Since this affects all ram, it is most efficient * to handle this during translation. */ diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c index 1f93510b85..cc7cab338c 100644 --- a/target/arm/tcg/vec_helper.c +++ b/target/arm/tcg/vec_helper.c @@ -843,7 +843,7 @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va, intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2); uint32_t neg_real = flip ^ neg_imag; intptr_t elements = opr_sz / sizeof(float16); - intptr_t eltspersegment = 16 / sizeof(float16); + intptr_t eltspersegment = MIN(16 / sizeof(float16), elements); intptr_t i, j; /* Shift boolean to the sign bit so we can xor to negate. */ @@ -905,7 +905,7 @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va, intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2); uint32_t neg_real = flip ^ neg_imag; intptr_t elements = opr_sz / sizeof(float32); - intptr_t eltspersegment = 16 / sizeof(float32); + intptr_t eltspersegment = MIN(16 / sizeof(float32), elements); intptr_t i, j; /* Shift boolean to the sign bit so we can xor to negate. */ diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 3e5e37abbe..ff59bc5522 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -1121,8 +1121,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = { uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus) { float_status *status = vstatus; - uint32_t inexact, frac; - uint32_t e_old, e_new; + uint32_t frac, e_old, e_new; + bool inexact; e_old = get_float_exception_flags(status); set_float_exception_flags(0, status); @@ -1130,13 +1130,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus) e_new = get_float_exception_flags(status); set_float_exception_flags(e_old | e_new, status); - if (value == float64_chs(float64_zero)) { - /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ - inexact = 1; - } else { - /* Normal inexact or overflow or NaN */ - inexact = e_new & (float_flag_inexact | float_flag_invalid); - } + /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */ + inexact = e_new & (float_flag_inexact | + float_flag_input_denormal | + float_flag_invalid); + + /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ + inexact |= value == float64_chs(float64_zero); /* Pack the result and the env->ZF representation of Z together. */ return deposit64(frac, 32, 32, inexact); diff --git a/target/i386/cpu.c b/target/i386/cpu.c index e4f25ffeca..5266eaba6d 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1553,8 +1553,8 @@ static FeatureDep feature_dependencies[] = { .to = { FEAT_SVM, ~0ull }, }, { - .from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE }, - .to = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG }, + .from = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG }, + .to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE }, }, }; @@ -6100,10 +6100,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, if (*eax & 31) { int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14); int vcpus_per_socket = cs->nr_cores * cs->nr_threads; - if (cs->nr_cores > 1) { - *eax &= ~0xFC000000; - *eax |= (pow2ceil(cs->nr_cores) - 1) << 26; - } + *eax &= ~0xFC000000; + *eax |= (pow2ceil(cs->nr_cores) - 1) << 26; if (host_vcpus_per_cache > vcpus_per_socket) { *eax &= ~0x3FFC000; *eax |= (pow2ceil(vcpus_per_socket) - 1) << 14; diff --git a/target/i386/kvm/hyperv.c b/target/i386/kvm/hyperv.c index f2a3fe650a..b94f12acc2 100644 --- a/target/i386/kvm/hyperv.c +++ b/target/i386/kvm/hyperv.c @@ -81,7 +81,7 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) */ async_safe_run_on_cpu(CPU(cpu), async_synic_update, RUN_ON_CPU_NULL); - return 0; + return EXCP_INTERRUPT; case KVM_EXIT_HYPERV_HCALL: { uint16_t code = exit->u.hcall.input & 0xffff; bool fast = exit->u.hcall.input & HV_HYPERCALL_FAST; diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 426c459412..4209d59ca8 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -1485,9 +1485,9 @@ static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid) case X86_FEAT_PCLMULQDQ: return (s->cpuid_ext_features & CPUID_EXT_PCLMULQDQ); case X86_FEAT_SSE: - return (s->cpuid_ext_features & CPUID_SSE); + return (s->cpuid_features & CPUID_SSE); case X86_FEAT_SSE2: - return (s->cpuid_ext_features & CPUID_SSE2); + return (s->cpuid_features & CPUID_SSE2); case X86_FEAT_SSE3: return (s->cpuid_ext_features & CPUID_EXT_SSE3); case X86_FEAT_SSSE3: diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index 4b965a5d6c..0747e8fd40 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -3010,6 +3010,11 @@ void helper_xsetbv(CPUX86State *env, uint32_t ecx, uint64_t mask) goto do_gpf; } + /* SSE can be disabled, but only if AVX is disabled too. */ + if ((mask & (XSTATE_SSE_MASK | XSTATE_YMM_MASK)) == XSTATE_YMM_MASK) { + goto do_gpf; + } + /* Disallow enabling unimplemented features. */ cpu_x86_cpuid(env, 0x0d, 0, &ena_lo, &dummy, &dummy, &ena_hi); ena = ((uint64_t)ena_hi << 32) | ena_lo; diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 83b9fa4939..c16fa3c0dc 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -2684,7 +2684,7 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) } /* Copy the FrameTemp value to EBP. */ - gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1); + gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1); /* Compute the final value of ESP. */ tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level); @@ -2798,13 +2798,17 @@ static void gen_bnd_jmp(DisasContext *s) static void do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) { + bool inhibit_reset; + gen_update_cc_op(s); /* If several instructions disable interrupts, only the first does it. */ - if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) { - gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); - } else { + inhibit_reset = false; + if (s->flags & HF_INHIBIT_IRQ_MASK) { gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK); + inhibit_reset = true; + } else if (inhibit) { + gen_set_hflag(s, HF_INHIBIT_IRQ_MASK); } if (s->base.tb->flags & HF_RF_MASK) { @@ -2813,9 +2817,11 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) if (recheck_tf) { gen_helper_rechecking_single_step(tcg_env); tcg_gen_exit_tb(NULL, 0); - } else if (s->flags & HF_TF_MASK) { + } else if ((s->flags & HF_TF_MASK) && !inhibit) { gen_helper_single_step(tcg_env); - } else if (jr) { + } else if (jr && + /* give irqs a chance to happen */ + !inhibit_reset) { tcg_gen_lookup_and_goto_ptr(); } else { tcg_gen_exit_tb(NULL, 0); @@ -6119,7 +6125,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); break; case 0xee: /* rdpkru */ - if (prefixes & PREFIX_LOCK) { + if (s->prefix & (PREFIX_LOCK | PREFIX_DATA + | PREFIX_REPZ | PREFIX_REPNZ)) { goto illegal_op; } tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]); @@ -6127,7 +6134,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64); break; case 0xef: /* wrpkru */ - if (prefixes & PREFIX_LOCK) { + if (s->prefix & (PREFIX_LOCK | PREFIX_DATA + | PREFIX_REPZ | PREFIX_REPNZ)) { goto illegal_op; } tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX], @@ -6835,12 +6843,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) modrm = x86_ldub_code(env, s); reg = ((modrm >> 3) & 7) | REX_R(s); - if (s->prefix & PREFIX_DATA) { - ot = MO_16; - } else { - ot = mo_64_32(dflag); - } - + ot = dflag; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_extu(ot, s->T0); tcg_gen_mov_tl(cpu_cc_src, s->T0); @@ -7004,7 +7007,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX]; dc->cpuid_xsave_features = env->features[FEAT_XSAVE]; dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) || - (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); + (flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK))); /* * If jmp_opt, we want to handle each string instruction individually. * For icount also disable repz optimization so that each iteration diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 203a349055..c1e6d98ac4 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -92,7 +92,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, { CPUState *cs = env_cpu(env); - qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n", + qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n", __func__, exception, loongarch_exception_name(exception)); @@ -710,7 +710,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY); qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 "," " PRCFG3=%016" PRIx64 "\n", - env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); + env->CSR_PRCFG1, env->CSR_PRCFG2, env->CSR_PRCFG3); qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index d630cc39cb..e2dff2b795 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs) env->fcsr0 = fpu.fcsr; for (i = 0; i < 32; i++) { env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0]; + env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1]; + env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2]; + env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3]; } for (i = 0; i < 8; i++) { env->cf[i] = fpu.fcc & 0xFF; @@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs) fpu.fcc = 0; for (i = 0; i < 32; i++) { fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0]; + fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1]; + fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2]; + fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3]; } for (i = 0; i < 8; i++) { diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0519e69c73..14e1922dc5 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1540,7 +1540,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { /* Vector cryptography extensions */ MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false), MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false), - MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false), + MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false), MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false), MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false), MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a67b86f6b7..2c3d20811e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -823,6 +823,9 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); +target_ulong riscv_new_csr_seed(target_ulong new_value, + target_ulong write_mask); + uint8_t satp_mode_max_from_map(uint32_t map); const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index fc090d729a..484edad900 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1176,28 +1176,30 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, switch (access_type) { case MMU_INST_FETCH: - if (env->virt_enabled && !first_stage) { + if (pmp_violation) { + cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT; + } else if (env->virt_enabled && !first_stage) { cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT; } else { - cs->exception_index = pmp_violation ? - RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT; + cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT; } break; case MMU_DATA_LOAD: - if (two_stage && !first_stage) { + if (pmp_violation) { + cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT; + } else if (two_stage && !first_stage) { cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT; } else { - cs->exception_index = pmp_violation ? - RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT; + cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT; } break; case MMU_DATA_STORE: - if (two_stage && !first_stage) { + if (pmp_violation) { + cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT; + } else if (two_stage && !first_stage) { cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT; } else { - cs->exception_index = pmp_violation ? - RISCV_EXCP_STORE_AMO_ACCESS_FAULT : - RISCV_EXCP_STORE_PAGE_FAULT; + cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT; } break; default: @@ -1373,17 +1375,17 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, __func__, pa, ret, prot_pmp, tlb_size); prot &= prot_pmp; - } - - if (ret != TRANSLATE_SUCCESS) { + } else { /* * Guest physical address translation failed, this is a HS * level exception */ first_stage_error = false; - env->guest_phys_fault_addr = (im_address | - (address & - (TARGET_PAGE_SIZE - 1))) >> 2; + if (ret != TRANSLATE_PMP_FAIL) { + env->guest_phys_fault_addr = (im_address | + (address & + (TARGET_PAGE_SIZE - 1))) >> 2; + } } } } else { diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 726096444f..829d8346ed 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -4267,10 +4267,8 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, #endif /* Crypto Extension */ -static RISCVException rmw_seed(CPURISCVState *env, int csrno, - target_ulong *ret_value, - target_ulong new_value, - target_ulong write_mask) +target_ulong riscv_new_csr_seed(target_ulong new_value, + target_ulong write_mask) { uint16_t random_v; Error *random_e = NULL; @@ -4294,6 +4292,18 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno, rval = random_v | SEED_OPST_ES16; } + return rval; +} + +static RISCVException rmw_seed(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, + target_ulong write_mask) +{ + target_ulong rval; + + rval = riscv_new_csr_seed(new_value, write_mask); + if (ret_value) { *ret_value = rval; } diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index be7a02cd90..c0026bd648 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -288,7 +288,7 @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg) static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) { RISCVCPU *cpu = RISCV_CPU(cs); - int reg_width = cpu->cfg.vlenb; + int bitsize = cpu->cfg.vlenb << 3; GDBFeatureBuilder builder; int i; @@ -298,7 +298,7 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) /* First define types and totals in a whole VL */ for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { - int count = reg_width / vec_lanes[i].size; + int count = bitsize / vec_lanes[i].size; gdb_feature_builder_append_tag( &builder, "", vec_lanes[i].id, vec_lanes[i].gdb_type, count); @@ -316,7 +316,7 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg) /* Define vector registers */ for (i = 0; i < 32; i++) { gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i), - reg_width, i, "riscv_vector", "vector"); + bitsize, i, "riscv_vector", "vector"); } gdb_feature_builder_end(&builder); diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 7d84e7d812..08c22f48cb 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -50,6 +50,22 @@ static bool require_rvf(DisasContext *s) } } +static bool require_rvfmin(DisasContext *s) +{ + if (s->mstatus_fs == EXT_STATUS_DISABLED) { + return false; + } + + switch (s->sew) { + case MO_16: + return s->cfg_ptr->ext_zvfhmin; + case MO_32: + return s->cfg_ptr->ext_zve32f; + default: + return false; + } +} + static bool require_scale_rvf(DisasContext *s) { if (s->mstatus_fs == EXT_STATUS_DISABLED) { @@ -75,8 +91,6 @@ static bool require_scale_rvfmin(DisasContext *s) } switch (s->sew) { - case MO_8: - return s->cfg_ptr->ext_zvfhmin; case MO_16: return s->cfg_ptr->ext_zve32f; case MO_32: @@ -2317,8 +2331,8 @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check) static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a) { return require_rvv(s) && + require_rvf(s) && require_scale_rvf(s) && - (s->sew != MO_8) && vext_check_isa_ill(s) && vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm); } @@ -2356,8 +2370,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check) static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a) { return require_rvv(s) && + require_rvf(s) && require_scale_rvf(s) && - (s->sew != MO_8) && vext_check_isa_ill(s) && vext_check_ds(s, a->rd, a->rs2, a->vm); } @@ -2388,8 +2402,8 @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf) static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a) { return require_rvv(s) && + require_rvf(s) && require_scale_rvf(s) && - (s->sew != MO_8) && vext_check_isa_ill(s) && vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm); } @@ -2427,8 +2441,8 @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv) static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a) { return require_rvv(s) && + require_rvf(s) && require_scale_rvf(s) && - (s->sew != MO_8) && vext_check_isa_ill(s) && vext_check_dd(s, a->rd, a->rs2, a->vm); } @@ -2685,8 +2699,8 @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a) static bool opffv_widen_check(DisasContext *s, arg_rmr *a) { return opfv_widen_check(s, a) && - require_scale_rvfmin(s) && - (s->sew != MO_8); + require_rvfmin(s) && + require_scale_rvfmin(s); } #define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \ @@ -2790,15 +2804,15 @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a) static bool opffv_narrow_check(DisasContext *s, arg_rmr *a) { return opfv_narrow_check(s, a) && - require_scale_rvfmin(s) && - (s->sew != MO_8); + require_rvfmin(s) && + require_scale_rvfmin(s); } static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a) { return opfv_narrow_check(s, a) && - require_scale_rvf(s) && - (s->sew != MO_8); + require_rvf(s) && + require_scale_rvf(s); } #define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \ @@ -2925,8 +2939,8 @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check) static bool freduction_widen_check(DisasContext *s, arg_rmrr *a) { return reduction_widen_check(s, a) && - require_scale_rvf(s) && - (s->sew != MO_8); + require_rvf(s) && + require_scale_rvf(s); } GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check) diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc index d5d7095903..15711c3140 100644 --- a/target/riscv/insn_trans/trans_rvzicbo.c.inc +++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc @@ -31,27 +31,35 @@ static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a) { REQUIRE_ZICBOM(ctx); - gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]); + TCGv src = get_address(ctx, a->rs1, 0); + + gen_helper_cbo_clean_flush(tcg_env, src); return true; } static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a) { REQUIRE_ZICBOM(ctx); - gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]); + TCGv src = get_address(ctx, a->rs1, 0); + + gen_helper_cbo_clean_flush(tcg_env, src); return true; } static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a) { REQUIRE_ZICBOM(ctx); - gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]); + TCGv src = get_address(ctx, a->rs1, 0); + + gen_helper_cbo_inval(tcg_env, src); return true; } static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a) { REQUIRE_ZICBOZ(ctx); - gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]); + TCGv src = get_address(ctx, a->rs1, 0); + + gen_helper_cbo_zero(tcg_env, src); return true; } diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 6a6c6cae80..94b0e393bf 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -427,10 +427,14 @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs) reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg); ret = kvm_set_one_reg(cs, id, ®); if (ret != 0) { - error_report("Unable to %s extension %s in KVM, error %d", - reg ? "enable" : "disable", - multi_ext_cfg->name, ret); - exit(EXIT_FAILURE); + if (!reg && ret == -EINVAL) { + warn_report("KVM cannot disable extension %s", + multi_ext_cfg->name); + } else { + error_report("Unable to enable extension %s in KVM, error %d", + multi_ext_cfg->name, ret); + exit(EXIT_FAILURE); + } } } } @@ -1054,8 +1058,8 @@ static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu, ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); if (ret != 0) { - error_report("Unable to read vlenb register, error code: %s", - strerrorname_np(errno)); + error_report("Unable to read vlenb register, error code: %d", + errno); exit(EXIT_FAILURE); } @@ -1418,6 +1422,28 @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run) return ret; } +static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run) +{ + target_ulong csr_num = run->riscv_csr.csr_num; + target_ulong new_value = run->riscv_csr.new_value; + target_ulong write_mask = run->riscv_csr.write_mask; + int ret = 0; + + switch (csr_num) { + case CSR_SEED: + run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask); + break; + default: + qemu_log_mask(LOG_UNIMP, + "%s: un-handled CSR EXIT for CSR %lx\n", + __func__, csr_num); + ret = -1; + break; + } + + return ret; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; @@ -1425,6 +1451,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) case KVM_EXIT_RISCV_SBI: ret = kvm_riscv_handle_sbi(cs, run); break; + case KVM_EXIT_RISCV_CSR: + ret = kvm_riscv_handle_csr(cs, run); + break; default: qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", __func__, run->exit_reason); @@ -1642,7 +1671,14 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, } } - hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1; + + if (max_hart_per_socket > 1) { + max_hart_per_socket--; + hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1; + } else { + hart_bits = 0; + } + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, KVM_DEV_RISCV_AIA_CONFIG_HART_BITS, &hart_bits, true, NULL); diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c index 996c21eb31..05b2d01e58 100644 --- a/target/riscv/vector_internals.c +++ b/target/riscv/vector_internals.c @@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, if (tot - cnt == 0) { return ; } + + if (HOST_BIG_ENDIAN) { + /* + * Deal the situation when the elements are insdie + * only one uint64 block including setting the + * masked-off element. + */ + if (((tot - 1) ^ cnt) < 8) { + memset(base + H1(tot - 1), -1, tot - cnt); + return; + } + /* + * Otherwise, at least cross two uint64_t blocks. + * Set first unaligned block. + */ + if (cnt % 8 != 0) { + uint32_t j = ROUND_UP(cnt, 8); + memset(base + H1(j - 1), -1, j - cnt); + cnt = j; + } + /* Set other 64bit aligend blocks */ + } memset(base + cnt, -1, tot - cnt); } diff --git a/target/sh4/translate.c b/target/sh4/translate.c index ebb6c901bf..f91d61b960 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -714,7 +714,7 @@ static void _decode_opc(DisasContext * ctx) tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8)); tcg_gen_andc_i32(cpu_sr_t, t1, t2); tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31); - tcg_gen_mov_i32(REG(B7_4), t0); + tcg_gen_mov_i32(REG(B11_8), t0); } return; case 0x2009: /* and Rm,Rn */ @@ -933,7 +933,7 @@ static void _decode_opc(DisasContext * ctx) t0 = tcg_temp_new(); tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4)); t1 = tcg_temp_new(); - tcg_gen_xor_i32(t1, t0, REG(B7_4)); + tcg_gen_xor_i32(t1, t0, REG(B11_8)); t2 = tcg_temp_new(); tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4)); tcg_gen_and_i32(t1, t1, t2); @@ -2181,6 +2181,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env) */ for (i = 1; i < max_insns; ++i) { tcg_gen_insn_start(pc + i * 2, ctx->envflags); + ctx->base.insn_start = tcg_last_op(); } } #endif diff --git a/target/sparc/helper.c b/target/sparc/helper.c index 2247e243b5..7846ddd6f6 100644 --- a/target/sparc/helper.c +++ b/target/sparc/helper.c @@ -121,7 +121,7 @@ uint64_t helper_sdiv(CPUSPARCState *env, target_ulong a, target_ulong b) return (uint32_t)(b32 < 0 ? INT32_MAX : INT32_MIN) | (-1ull << 32); } - a64 /= b; + a64 /= b32; r = a64; if (unlikely(r != a64)) { return (uint32_t)(a64 < 0 ? INT32_MIN : INT32_MAX) | (-1ull << 32); diff --git a/target/sparc/helper.h b/target/sparc/helper.h index b8087d0d2b..97fbf6f66c 100644 --- a/target/sparc/helper.h +++ b/target/sparc/helper.h @@ -94,15 +94,12 @@ DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_WG, s64, env, f32) DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64) DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128) -DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fmul8x16al, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fmul8x16au, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i32, i32) +DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i32, i64) +DEF_HELPER_FLAGS_2(fmul8x16a, TCG_CALL_NO_RWG_SE, i64, i32, s32) DEF_HELPER_FLAGS_2(fmul8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fmuld8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fmuld8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64) -DEF_HELPER_FLAGS_2(fexpand, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_1(fexpand, TCG_CALL_NO_RWG_SE, i64, i32) DEF_HELPER_FLAGS_3(pdist, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64) DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_NO_RWG_SE, i32, i64, i64) DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64) diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode index 2d26404cb2..e2d8a07dc4 100644 --- a/target/sparc/insns.decode +++ b/target/sparc/insns.decode @@ -352,7 +352,7 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5 FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r BSHUFFLE 10 ..... 110110 ..... 0 0100 1100 ..... @r_r_r - FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r + FEXPAND 10 ..... 110110 00000 0 0100 1101 ..... @r_r2 FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 571b3e3f03..99c6f3cc72 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -45,6 +45,7 @@ # define gen_helper_clear_softint(E, S) qemu_build_not_reached() # define gen_helper_done(E) qemu_build_not_reached() # define gen_helper_flushw(E) qemu_build_not_reached() +# define gen_helper_fmul8x16a(D, S1, S2) qemu_build_not_reached() # define gen_helper_rdccr(D, E) qemu_build_not_reached() # define gen_helper_rdcwp(D, E) qemu_build_not_reached() # define gen_helper_restored(E) qemu_build_not_reached() @@ -72,11 +73,7 @@ # define gen_helper_fexpand ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fmul8sux16 ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fmul8ulx16 ({ qemu_build_not_reached(); NULL; }) -# define gen_helper_fmul8x16al ({ qemu_build_not_reached(); NULL; }) -# define gen_helper_fmul8x16au ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fmul8x16 ({ qemu_build_not_reached(); NULL; }) -# define gen_helper_fmuld8sux16 ({ qemu_build_not_reached(); NULL; }) -# define gen_helper_fmuld8ulx16 ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fpmerge ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; }) # define gen_helper_fstox ({ qemu_build_not_reached(); NULL; }) @@ -719,6 +716,60 @@ static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2) #endif } +static void gen_op_fmul8x16al(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2) +{ + tcg_gen_ext16s_i32(src2, src2); + gen_helper_fmul8x16a(dst, src1, src2); +} + +static void gen_op_fmul8x16au(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2) +{ + tcg_gen_sari_i32(src2, src2, 16); + gen_helper_fmul8x16a(dst, src1, src2); +} + +static void gen_op_fmuld8ulx16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2) +{ + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + TCGv_i32 t2 = tcg_temp_new_i32(); + + tcg_gen_ext8u_i32(t0, src1); + tcg_gen_ext16s_i32(t1, src2); + tcg_gen_mul_i32(t0, t0, t1); + + tcg_gen_extract_i32(t1, src1, 16, 8); + tcg_gen_sextract_i32(t2, src2, 16, 16); + tcg_gen_mul_i32(t1, t1, t2); + + tcg_gen_concat_i32_i64(dst, t0, t1); +} + +static void gen_op_fmuld8sux16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2) +{ + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + TCGv_i32 t2 = tcg_temp_new_i32(); + + /* + * The insn description talks about extracting the upper 8 bits + * of the signed 16-bit input rs1, performing the multiply, then + * shifting left by 8 bits. Instead, zap the lower 8 bits of + * the rs1 input, which avoids the need for two shifts. + */ + tcg_gen_ext16s_i32(t0, src1); + tcg_gen_andi_i32(t0, t0, ~0xff); + tcg_gen_ext16s_i32(t1, src2); + tcg_gen_mul_i32(t0, t0, t1); + + tcg_gen_sextract_i32(t1, src1, 16, 16); + tcg_gen_andi_i32(t1, t1, ~0xff); + tcg_gen_sextract_i32(t2, src2, 16, 16); + tcg_gen_mul_i32(t1, t1, t2); + + tcg_gen_concat_i32_i64(dst, t0, t1); +} + static void finishing_insn(DisasContext *dc) { /* @@ -4358,6 +4409,25 @@ TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd) TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod) TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox) +static bool do_df(DisasContext *dc, arg_r_r *a, + void (*func)(TCGv_i64, TCGv_i32)) +{ + TCGv_i64 dst; + TCGv_i32 src; + + if (gen_trap_ifnofpu(dc)) { + return true; + } + + dst = tcg_temp_new_i64(); + src = gen_load_fpr_F(dc, a->rs); + func(dst, src); + gen_store_fpr_D(dc, a->rd, dst); + return advance_pc(dc); +} + +TRANS(FEXPAND, VIS1, do_df, a, gen_helper_fexpand) + static bool do_env_df(DisasContext *dc, arg_r_r *a, void (*func)(TCGv_i64, TCGv_env, TCGv_i32)) { @@ -4564,6 +4634,50 @@ TRANS(FSUBs, ALL, do_env_fff, a, gen_helper_fsubs) TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls) TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs) +static bool do_dff(DisasContext *dc, arg_r_r_r *a, + void (*func)(TCGv_i64, TCGv_i32, TCGv_i32)) +{ + TCGv_i64 dst; + TCGv_i32 src1, src2; + + if (gen_trap_ifnofpu(dc)) { + return true; + } + + dst = gen_dest_fpr_D(dc, a->rd); + src1 = gen_load_fpr_F(dc, a->rs1); + src2 = gen_load_fpr_F(dc, a->rs2); + func(dst, src1, src2); + gen_store_fpr_D(dc, a->rd, dst); + return advance_pc(dc); +} + +TRANS(FMUL8x16AU, VIS1, do_dff, a, gen_op_fmul8x16au) +TRANS(FMUL8x16AL, VIS1, do_dff, a, gen_op_fmul8x16al) +TRANS(FMULD8SUx16, VIS1, do_dff, a, gen_op_fmuld8sux16) +TRANS(FMULD8ULx16, VIS1, do_dff, a, gen_op_fmuld8ulx16) +TRANS(FPMERGE, VIS1, do_dff, a, gen_helper_fpmerge) + +static bool do_dfd(DisasContext *dc, arg_r_r_r *a, + void (*func)(TCGv_i64, TCGv_i32, TCGv_i64)) +{ + TCGv_i64 dst, src2; + TCGv_i32 src1; + + if (gen_trap_ifnofpu(dc)) { + return true; + } + + dst = gen_dest_fpr_D(dc, a->rd); + src1 = gen_load_fpr_F(dc, a->rs1); + src2 = gen_load_fpr_D(dc, a->rs2); + func(dst, src1, src2); + gen_store_fpr_D(dc, a->rd, dst); + return advance_pc(dc); +} + +TRANS(FMUL8x16, VIS1, do_dfd, a, gen_helper_fmul8x16) + static bool do_ddd(DisasContext *dc, arg_r_r_r *a, void (*func)(TCGv_i64, TCGv_i64, TCGv_i64)) { @@ -4581,15 +4695,8 @@ static bool do_ddd(DisasContext *dc, arg_r_r_r *a, return advance_pc(dc); } -TRANS(FMUL8x16, VIS1, do_ddd, a, gen_helper_fmul8x16) -TRANS(FMUL8x16AU, VIS1, do_ddd, a, gen_helper_fmul8x16au) -TRANS(FMUL8x16AL, VIS1, do_ddd, a, gen_helper_fmul8x16al) TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16) TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16) -TRANS(FMULD8SUx16, VIS1, do_ddd, a, gen_helper_fmuld8sux16) -TRANS(FMULD8ULx16, VIS1, do_ddd, a, gen_helper_fmuld8ulx16) -TRANS(FPMERGE, VIS1, do_ddd, a, gen_helper_fpmerge) -TRANS(FEXPAND, VIS1, do_ddd, a, gen_helper_fexpand) TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64) TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64) diff --git a/target/sparc/vis_helper.c b/target/sparc/vis_helper.c index 7763b16c24..14c665cad6 100644 --- a/target/sparc/vis_helper.c +++ b/target/sparc/vis_helper.c @@ -74,60 +74,38 @@ typedef union { float32 f; } VIS32; -uint64_t helper_fpmerge(uint64_t src1, uint64_t src2) +uint64_t helper_fpmerge(uint32_t src1, uint32_t src2) { - VIS64 s, d; + VIS32 s1, s2; + VIS64 d; - s.ll = src1; - d.ll = src2; + s1.l = src1; + s2.l = src2; + d.ll = 0; - /* Reverse calculation order to handle overlap */ - d.VIS_B64(7) = s.VIS_B64(3); - d.VIS_B64(6) = d.VIS_B64(3); - d.VIS_B64(5) = s.VIS_B64(2); - d.VIS_B64(4) = d.VIS_B64(2); - d.VIS_B64(3) = s.VIS_B64(1); - d.VIS_B64(2) = d.VIS_B64(1); - d.VIS_B64(1) = s.VIS_B64(0); - /* d.VIS_B64(0) = d.VIS_B64(0); */ + d.VIS_B64(7) = s1.VIS_B32(3); + d.VIS_B64(6) = s2.VIS_B32(3); + d.VIS_B64(5) = s1.VIS_B32(2); + d.VIS_B64(4) = s2.VIS_B32(2); + d.VIS_B64(3) = s1.VIS_B32(1); + d.VIS_B64(2) = s2.VIS_B32(1); + d.VIS_B64(1) = s1.VIS_B32(0); + d.VIS_B64(0) = s2.VIS_B32(0); return d.ll; } -uint64_t helper_fmul8x16(uint64_t src1, uint64_t src2) +uint64_t helper_fmul8x16(uint32_t src1, uint64_t src2) { - VIS64 s, d; - uint32_t tmp; - - s.ll = src1; - d.ll = src2; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \ - if ((tmp & 0xff) > 0x7f) { \ - tmp += 0x100; \ - } \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - return d.ll; -} - -uint64_t helper_fmul8x16al(uint64_t src1, uint64_t src2) -{ - VIS64 s, d; + VIS64 d; + VIS32 s; uint32_t tmp; - s.ll = src1; + s.l = src1; d.ll = src2; #define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \ + tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B32(r); \ if ((tmp & 0xff) > 0x7f) { \ tmp += 0x100; \ } \ @@ -142,20 +120,23 @@ uint64_t helper_fmul8x16al(uint64_t src1, uint64_t src2) return d.ll; } -uint64_t helper_fmul8x16au(uint64_t src1, uint64_t src2) +uint64_t helper_fmul8x16a(uint32_t src1, int32_t src2) { - VIS64 s, d; + VIS32 s; + VIS64 d; uint32_t tmp; - s.ll = src1; - d.ll = src2; + s.l = src1; + d.ll = 0; -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \ - if ((tmp & 0xff) > 0x7f) { \ - tmp += 0x100; \ - } \ - d.VIS_W64(r) = tmp >> 8; +#define PMUL(r) \ + do { \ + tmp = src2 * (int32_t)s.VIS_B32(r); \ + if ((tmp & 0xff) > 0x7f) { \ + tmp += 0x100; \ + } \ + d.VIS_W64(r) = tmp >> 8; \ + } while (0) PMUL(0); PMUL(1); @@ -214,59 +195,13 @@ uint64_t helper_fmul8ulx16(uint64_t src1, uint64_t src2) return d.ll; } -uint64_t helper_fmuld8sux16(uint64_t src1, uint64_t src2) -{ - VIS64 s, d; - uint32_t tmp; - - s.ll = src1; - d.ll = src2; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \ - if ((tmp & 0xff) > 0x7f) { \ - tmp += 0x100; \ - } \ - d.VIS_L64(r) = tmp; - - /* Reverse calculation order to handle overlap */ - PMUL(1); - PMUL(0); -#undef PMUL - - return d.ll; -} - -uint64_t helper_fmuld8ulx16(uint64_t src1, uint64_t src2) -{ - VIS64 s, d; - uint32_t tmp; - - s.ll = src1; - d.ll = src2; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \ - if ((tmp & 0xff) > 0x7f) { \ - tmp += 0x100; \ - } \ - d.VIS_L64(r) = tmp; - - /* Reverse calculation order to handle overlap */ - PMUL(1); - PMUL(0); -#undef PMUL - - return d.ll; -} - -uint64_t helper_fexpand(uint64_t src1, uint64_t src2) +uint64_t helper_fexpand(uint32_t src2) { VIS32 s; VIS64 d; - s.l = (uint32_t)src1; - d.ll = src2; + s.l = src2; + d.ll = 0; d.VIS_W64(0) = s.VIS_B32(0) << 4; d.VIS_W64(1) = s.VIS_B32(1) << 4; d.VIS_W64(2) = s.VIS_B32(2) << 4; diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 69c5b8ac4f..8f68bd3e51 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -366,8 +366,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, * back to the slow path. */ - intptr_t pc_offset; - tcg_target_long val_lo, val_hi, pc_hi, offset_hi; + intptr_t src_rx, pc_offset; tcg_target_long hi12, hi32, hi52; /* Value fits in signed i32. */ @@ -377,24 +376,23 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, } /* PC-relative cases. */ - pc_offset = tcg_pcrel_diff(s, (void *)val); - if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) { - /* Single pcaddu2i. */ - tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); - return; + src_rx = (intptr_t)tcg_splitwx_to_rx(s->code_ptr); + if ((val & 3) == 0) { + pc_offset = val - src_rx; + if (pc_offset == sextreg(pc_offset, 0, 22)) { + /* Single pcaddu2i. */ + tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); + return; + } } - if (pc_offset == (int32_t)pc_offset) { - /* Offset within 32 bits; load with pcalau12i + ori. */ - val_lo = sextreg(val, 0, 12); - val_hi = val >> 12; - pc_hi = (val - pc_offset) >> 12; - offset_hi = val_hi - pc_hi; - - tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); - tcg_out_opc_pcalau12i(s, rd, offset_hi); + pc_offset = (val >> 12) - (src_rx >> 12); + if (pc_offset == sextreg(pc_offset, 0, 20)) { + /* Load with pcalau12i + ori. */ + tcg_target_long val_lo = val & 0xfff; + tcg_out_opc_pcalau12i(s, rd, pc_offset); if (val_lo != 0) { - tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); + tcg_out_opc_ori(s, rd, rd, val_lo); } return; } @@ -808,18 +806,88 @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data, } } -static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, intptr_t arg2) +static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg dest, + TCGReg base, intptr_t offset) { - bool is_32bit = type == TCG_TYPE_I32; - tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2); + switch (type) { + case TCG_TYPE_I32: + if (dest < TCG_REG_V0) { + tcg_out_ldst(s, OPC_LD_W, dest, base, offset); + } else { + tcg_out_dupm_vec(s, TCG_TYPE_I128, MO_32, dest, base, offset); + } + break; + case TCG_TYPE_I64: + if (dest < TCG_REG_V0) { + tcg_out_ldst(s, OPC_LD_D, dest, base, offset); + } else { + tcg_out_dupm_vec(s, TCG_TYPE_I128, MO_64, dest, base, offset); + } + break; + case TCG_TYPE_V128: + if (-0x800 <= offset && offset <= 0x7ff) { + tcg_out_opc_vld(s, dest, base, offset); + } else { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset); + tcg_out_opc_vldx(s, dest, base, TCG_REG_TMP0); + } + break; + default: + g_assert_not_reached(); + } } -static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, - TCGReg arg1, intptr_t arg2) +static void tcg_out_st(TCGContext *s, TCGType type, TCGReg src, + TCGReg base, intptr_t offset) { - bool is_32bit = type == TCG_TYPE_I32; - tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2); + switch (type) { + case TCG_TYPE_I32: + if (src < TCG_REG_V0) { + tcg_out_ldst(s, OPC_ST_W, src, base, offset); + } else { + /* TODO: Could use fst_s, fstx_s */ + if (offset < -0x100 || offset > 0xff || (offset & 3)) { + if (-0x800 <= offset && offset <= 0x7ff) { + tcg_out_opc_addi_d(s, TCG_REG_TMP0, base, offset); + } else { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset); + tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP0, base); + } + base = TCG_REG_TMP0; + offset = 0; + } + tcg_out_opc_vstelm_w(s, src, base, offset, 0); + } + break; + case TCG_TYPE_I64: + if (src < TCG_REG_V0) { + tcg_out_ldst(s, OPC_ST_D, src, base, offset); + } else { + /* TODO: Could use fst_d, fstx_d */ + if (offset < -0x100 || offset > 0xff || (offset & 7)) { + if (-0x800 <= offset && offset <= 0x7ff) { + tcg_out_opc_addi_d(s, TCG_REG_TMP0, base, offset); + } else { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset); + tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP0, base); + } + base = TCG_REG_TMP0; + offset = 0; + } + tcg_out_opc_vstelm_d(s, src, base, offset, 0); + } + break; + case TCG_TYPE_V128: + if (-0x800 <= offset && offset <= 0x7ff) { + tcg_out_opc_vst(s, src, base, offset); + } else { + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset); + tcg_out_opc_vstx(s, src, base, TCG_REG_TMP0); + } + break; + default: + g_assert_not_reached(); + } } static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, @@ -1740,7 +1808,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, { TCGType type = vecl + TCG_TYPE_V64; TCGArg a0, a1, a2, a3; - TCGReg temp = TCG_REG_TMP0; TCGReg temp_vec = TCG_VEC_TMP0; static const LoongArchInsn cmp_vec_insn[16][4] = { @@ -1820,22 +1887,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, switch (opc) { case INDEX_op_st_vec: - /* Try to fit vst imm */ - if (-0x800 <= a2 && a2 <= 0x7ff) { - tcg_out_opc_vst(s, a0, a1, a2); - } else { - tcg_out_movi(s, TCG_TYPE_I64, temp, a2); - tcg_out_opc_vstx(s, a0, a1, temp); - } + tcg_out_st(s, type, a0, a1, a2); break; case INDEX_op_ld_vec: - /* Try to fit vld imm */ - if (-0x800 <= a2 && a2 <= 0x7ff) { - tcg_out_opc_vld(s, a0, a1, a2); - } else { - tcg_out_movi(s, TCG_TYPE_I64, temp, a2); - tcg_out_opc_vldx(s, a0, a1, temp); - } + tcg_out_ld(s, type, a0, a1, a2); break; case INDEX_op_and_vec: tcg_out_opc_vand_v(s, a0, a1, a2); diff --git a/tcg/optimize.c b/tcg/optimize.c index 2e9e5725a9..8c49229d6f 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -2274,7 +2274,7 @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op) case TCG_COND_TSTEQ: case TCG_COND_TSTNE: - if (arg_is_const_val(op->args[2], 0)) { + if (arg_is_const_val(op->args[3], 0)) { goto do_setcond_high; } if (arg_is_const_val(op->args[4], 0)) { diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index 989b65111c..d0ab5aaa83 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -646,12 +646,12 @@ def test_arm_cubieboard_initrd(self): :avocado: tags=accel:tcg """ deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) initrd_url = ('https://github.com/groeck/linux-build-test/raw/' '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' @@ -690,12 +690,12 @@ def test_arm_cubieboard_sata(self): :avocado: tags=accel:tcg """ deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) rootfs_url = ('https://github.com/groeck/linux-build-test/raw/' '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' @@ -872,13 +872,13 @@ def test_arm_bpim2u(self): :avocado: tags=machine:bpim2u :avocado: tags=accel:tcg """ - deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/' - 'linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + deb_url = ('https://apt.armbian.com/pool/main/l/' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = ('/usr/lib/linux-image-current-sunxi/' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' 'sun8i-r40-bananapi-m2-ultra.dtb') dtb_path = self.extract_from_deb(deb_path, dtb_path) @@ -899,13 +899,13 @@ def test_arm_bpim2u_initrd(self): :avocado: tags=accel:tcg :avocado: tags=machine:bpim2u """ - deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/' - 'linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + deb_url = ('https://apt.armbian.com/pool/main/l/' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = ('/usr/lib/linux-image-current-sunxi/' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' 'sun8i-r40-bananapi-m2-ultra.dtb') dtb_path = self.extract_from_deb(deb_path, dtb_path) initrd_url = ('https://github.com/groeck/linux-build-test/raw/' @@ -946,13 +946,13 @@ def test_arm_bpim2u_gmac(self): """ self.require_netdev('user') - deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/' - 'linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + deb_url = ('https://apt.armbian.com/pool/main/l/' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = ('/usr/lib/linux-image-current-sunxi/' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' 'sun8i-r40-bananapi-m2-ultra.dtb') dtb_path = self.extract_from_deb(deb_path, dtb_path) rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/' @@ -1049,12 +1049,12 @@ def test_arm_orangepi(self): :avocado: tags=accel:tcg """ deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) self.vm.set_console() @@ -1075,12 +1075,12 @@ def test_arm_orangepi_initrd(self): :avocado: tags=machine:orangepi-pc """ deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) initrd_url = ('https://github.com/groeck/linux-build-test/raw/' '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' @@ -1121,12 +1121,12 @@ def test_arm_orangepi_sd(self): self.require_netdev('user') deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/' 'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz') diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py index 10d99403a4..0474f7b7c8 100644 --- a/tests/avocado/replay_kernel.py +++ b/tests/avocado/replay_kernel.py @@ -203,12 +203,12 @@ def test_arm_cubieboard_initrd(self): :avocado: tags=machine:cubieboard """ deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb') - deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0' + 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') + deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-5.10.16-sunxi') - dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb' + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' dtb_path = self.extract_from_deb(deb_path, dtb_path) initrd_url = ('https://github.com/groeck/linux-build-test/raw/' '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos9.docker similarity index 82% rename from tests/docker/dockerfiles/centos8.docker rename to tests/docker/dockerfiles/centos9.docker index d97c30e96a..9fc9b27eb7 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos9.docker @@ -1,15 +1,14 @@ # THIS FILE WAS AUTO-GENERATED # -# $ lcitool dockerfile --layers all centos-stream-8 qemu +# $ lcitool dockerfile --layers all centos-stream-9 qemu # # https://gitlab.com/libvirt/libvirt-ci -FROM quay.io/centos/centos:stream8 +FROM quay.io/centos/centos:stream9 RUN dnf distro-sync -y && \ dnf install 'dnf-command(config-manager)' -y && \ - dnf config-manager --set-enabled -y powertools && \ - dnf install -y centos-release-advanced-virtualization && \ + dnf config-manager --set-enabled -y crb && \ dnf install -y epel-release && \ dnf install -y epel-next-release && \ dnf install -y \ @@ -42,7 +41,6 @@ RUN dnf distro-sync -y && \ glib2-static \ glibc-langpack-en \ glibc-static \ - glusterfs-api-devel \ gnutls-devel \ gtk3-devel \ hostname \ @@ -82,6 +80,7 @@ RUN dnf distro-sync -y && \ lzo-devel \ make \ mesa-libgbm-devel \ + meson \ mtools \ ncurses-devel \ nettle-devel \ @@ -95,25 +94,25 @@ RUN dnf distro-sync -y && \ pixman-devel \ pkgconfig \ pulseaudio-libs-devel \ - python38 \ - python38-PyYAML \ - python38-numpy \ - python38-pip \ - python38-setuptools \ - python38-wheel \ + python3 \ + python3-PyYAML \ + python3-numpy \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx_rtd_theme \ + python3-tomli \ rdma-core-devel \ sed \ snappy-devel \ socat \ spice-protocol \ - spice-server-devel \ swtpm \ systemd-devel \ systemtap-sdt-devel \ tar \ usbredir-devel \ util-linux \ - virglrenderer-devel \ vte291-devel \ which \ xfsprogs-devel \ @@ -131,18 +130,11 @@ RUN dnf distro-sync -y && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc -RUN /usr/bin/pip3.8 install \ - meson==0.63.2 \ - pillow \ - sphinx \ - sphinx-rtd-theme \ - tomli - ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" -ENV PYTHON "/usr/bin/python3.8" +ENV PYTHON "/usr/bin/python3" # As a final step configure the user (if env is defined) ARG USER ARG UID diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker b/tests/docker/dockerfiles/debian-all-test-cross.docker index 2cc7a24d4d..6cc38a3633 100644 --- a/tests/docker/dockerfiles/debian-all-test-cross.docker +++ b/tests/docker/dockerfiles/debian-all-test-cross.docker @@ -68,6 +68,7 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \ ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools ENV DEF_TARGET_LIST aarch64-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sparc64-linux-user # As a final step configure the user (if env is defined) +ENV MAKE /usr/bin/make ARG USER ARG UID RUN if [ "${USER}" ]; then \ diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker index 60bd8faa20..f2d40f2dee 100644 --- a/tests/docker/dockerfiles/debian-hexagon-cross.docker +++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker @@ -45,6 +45,7 @@ ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL" ENV PATH $PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin +ENV MAKE /usr/bin/make # As a final step configure the user (if env is defined) ARG USER ARG UID diff --git a/tests/docker/dockerfiles/debian-legacy-test-cross.docker b/tests/docker/dockerfiles/debian-legacy-test-cross.docker index 8cc68bc912..d75e0b85e2 100644 --- a/tests/docker/dockerfiles/debian-legacy-test-cross.docker +++ b/tests/docker/dockerfiles/debian-legacy-test-cross.docker @@ -42,6 +42,7 @@ RUN /usr/bin/pip3 install tomli ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools ENV DEF_TARGET_LIST alpha-linux-user,sh4-linux-user +ENV MAKE /usr/bin/make # As a final step configure the user (if env is defined) ARG USER ARG UID diff --git a/tests/docker/dockerfiles/debian-loongarch-cross.docker b/tests/docker/dockerfiles/debian-loongarch-cross.docker index b25e779a2c..6a9197528b 100644 --- a/tests/docker/dockerfiles/debian-loongarch-cross.docker +++ b/tests/docker/dockerfiles/debian-loongarch-cross.docker @@ -44,6 +44,7 @@ ENV LD_LIBRARY_PATH /opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-li ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch-softmmu +ENV MAKE /usr/bin/make # As a final step configure the user (if env is defined) ARG USER diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker b/tests/docker/dockerfiles/debian-tricore-cross.docker index c597f8e16b..16276aa21d 100644 --- a/tests/docker/dockerfiles/debian-tricore-cross.docker +++ b/tests/docker/dockerfiles/debian-tricore-cross.docker @@ -44,6 +44,7 @@ RUN curl -#SL https://github.com/bkoppelmann/package_940/releases/download/trico # This image can only build a very minimal QEMU as well as the tests ENV DEF_TARGET_LIST tricore-softmmu ENV QEMU_CONFIGURE_OPTS --disable-user --disable-tools --disable-fdt +ENV MAKE /usr/bin/make # As a final step configure the user (if env is defined) ARG USER ARG UID diff --git a/tests/docker/dockerfiles/debian-xtensa-cross.docker b/tests/docker/dockerfiles/debian-xtensa-cross.docker index 72c25d63d9..413881899b 100644 --- a/tests/docker/dockerfiles/debian-xtensa-cross.docker +++ b/tests/docker/dockerfiles/debian-xtensa-cross.docker @@ -27,6 +27,7 @@ RUN for cpu in $CPU_LIST; do \ done ENV PATH $PATH:/opt/$TOOLCHAIN_RELEASE/xtensa-dc232b-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dc233c-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-de233_fpu-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dsp3400-elf/bin +ENV MAKE /usr/bin/make # As a final step configure the user (if env is defined) ARG USER ARG UID diff --git a/tests/docker/dockerfiles/fedora-cris-cross.docker b/tests/docker/dockerfiles/fedora-cris-cross.docker index f2899af410..97c9d37ede 100644 --- a/tests/docker/dockerfiles/fedora-cris-cross.docker +++ b/tests/docker/dockerfiles/fedora-cris-cross.docker @@ -4,6 +4,7 @@ FROM registry.fedoraproject.org/fedora:33 ENV PACKAGES gcc-cris-linux-gnu +ENV MAKE /usr/bin/make RUN dnf install -y $PACKAGES RUN rpm -q $PACKAGES | sort > /packages.txt # As a final step configure the user (if env is defined) diff --git a/tests/lcitool/mappings.yml b/tests/lcitool/mappings.yml index 407c03301b..03b974ad02 100644 --- a/tests/lcitool/mappings.yml +++ b/tests/lcitool/mappings.yml @@ -1,66 +1,50 @@ mappings: flake8: - CentOSStream8: OpenSUSELeap15: meson: - CentOSStream8: OpenSUSELeap15: python3: - CentOSStream8: python38 OpenSUSELeap15: python311-base python3-PyYAML: - CentOSStream8: python38-PyYAML OpenSUSELeap15: python3-devel: - CentOSStream8: python38-devel OpenSUSELeap15: python311-devel python3-docutils: - CentOSStream8: OpenSUSELeap15: python3-numpy: - CentOSStream8: python38-numpy OpenSUSELeap15: python3-opencv: - CentOSStream8: OpenSUSELeap15: python3-pillow: - CentOSStream8: OpenSUSELeap15: python3-pip: - CentOSStream8: python38-pip OpenSUSELeap15: python311-pip python3-pillow: - CentOSStream8: OpenSUSELeap15: python3-selinux: - CentOSStream8: OpenSUSELeap15: python3-setuptools: - CentOSStream8: python38-setuptools OpenSUSELeap15: python311-setuptools python3-sphinx: - CentOSStream8: OpenSUSELeap15: python3-sphinx-rtd-theme: - CentOSStream8: OpenSUSELeap15: python3-sqlite3: - CentOSStream8: python38 OpenSUSELeap15: python311 python3-tomli: @@ -69,15 +53,11 @@ mappings: Fedora: Debian12: OpenSUSELeap15: - # Not available for Python 3.8 - CentOSStream8: python3-venv: - CentOSStream8: python38 OpenSUSELeap15: python311-base python3-wheel: - CentOSStream8: python38-wheel OpenSUSELeap15: python311-pip pypi_mappings: diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh index fe7692c500..bfb2d5b753 100755 --- a/tests/lcitool/refresh +++ b/tests/lcitool/refresh @@ -125,7 +125,7 @@ try: # Standard native builds # generate_dockerfile("alpine", "alpine-318") - generate_dockerfile("centos8", "centos-stream-8") + generate_dockerfile("centos9", "centos-stream-9") generate_dockerfile("debian", "debian-12", trailer="".join(debian12_extras)) generate_dockerfile("fedora", "fedora-38") diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 index 53c7d428e3..b71ac097d1 100755 --- a/tests/qemu-iotests/061 +++ b/tests/qemu-iotests/061 @@ -326,12 +326,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" echo _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" -_img_info --format-specific +$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt +$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts echo $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -_img_info --format-specific +$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt +$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts echo diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index 139fc68177..24c33add7c 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 qemu-img: data-file can only be set for images that use an external data file Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data -qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory +qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64 MiB (67108864 bytes) @@ -560,7 +562,9 @@ Format specific information: corrupt: false extended l2: false -qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image +qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 64 MiB (67108864 bytes) diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 index 3e61fa25bb..bb9cc6512f 100755 --- a/tests/qemu-iotests/244 +++ b/tests/qemu-iotests/244 @@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" # blkdebug doesn't support copy offloading, so this tests the error path -$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG" -$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" -$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" +test_img_with_blkdebug="json:{ + 'driver': 'qcow2', + 'file': { + 'driver': 'file', + 'filename': '$TEST_IMG' + }, + 'data-file': { + 'driver': 'blkdebug', + 'image': { + 'driver': 'file', + 'filename': '$TEST_IMG.data' + } + } +}" +$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug" +$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug" echo echo "=== Flushing should flush the data file ===" diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270 index 74352342db..c37b674aa2 100755 --- a/tests/qemu-iotests/270 +++ b/tests/qemu-iotests/270 @@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \ # "write" 2G of data without using any space. # (qemu-img create does not like it, though, because null-co does not # support image creation.) -$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ - "$TEST_IMG" +test_img_with_null_data="json:{ + 'driver': '$IMGFMT', + 'file': { + 'filename': '$TEST_IMG' + }, + 'data-file': { + 'driver': 'null-co', + 'size':'4294967296' + } +}" # This gives us a range of: # 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31 @@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ # on L2 boundaries, we need large L2 tables; hence the cluster size of # 2 MB. (Anything from 256 kB should work, though, because then one L2 # table covers 8 GB.) -$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io _check_test_img diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread b/tests/qemu-iotests/tests/nbd-tls-iothread new file mode 100755 index 0000000000..a2fb07206e --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-tls-iothread @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +# group: rw quick +# +# Test of NBD+TLS+iothread +# +# Copyright (C) 2024 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# creator +owner=eblake@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_qemu + _cleanup_test_img + rm -f "$dst_image" + tls_x509_cleanup +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +cd .. +. ./common.rc +. ./common.filter +. ./common.qemu +. ./common.tls +. ./common.nbd + +_supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below +_supported_proto file + +# pick_unused_port +# +# Picks and returns an "unused" port, setting the global variable +# $port. +# +# This is inherently racy, but we need it because qemu does not currently +# permit NBD+TLS over a Unix domain socket +pick_unused_port () +{ + if ! (ss --version) >/dev/null 2>&1; then + _notrun "ss utility required, skipped this test" + fi + + # Start at a random port to make it less likely that two parallel + # tests will conflict. + port=$(( 50000 + (RANDOM%15000) )) + while ss -ltn | grep -sqE ":$port\b"; do + ((port++)) + if [ $port -eq 65000 ]; then port=50000; fi + done + echo picked unused port +} + +tls_x509_init + +size=1G +DST_IMG="$TEST_DIR/dst.qcow2" + +echo +echo "== preparing TLS creds and spare port ==" + +pick_unused_port +tls_x509_create_root_ca "ca1" +tls_x509_create_server "ca1" "server1" +tls_x509_create_client "ca1" "client1" +tls_obj_base=tls-creds-x509,id=tls0,verify-peer=true,dir="${tls_dir}" + +echo +echo "== preparing image ==" + +_make_test_img $size +$QEMU_IMG create -f qcow2 "$DST_IMG" $size | _filter_img_create + +echo +echo === Starting Src QEMU === +echo + +_launch_qemu -machine q35 \ + -object iothread,id=iothread0 \ + -object "${tls_obj_base}"/client1,endpoint=client \ + -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true, + "bus":"pcie.0"}' \ + -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0", + "bus":"root0", "iothread":"iothread0"}' \ + -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1", + "bus":"virtio_scsi_pci0.0"}' \ + -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false}, + "filename":"'"$TEST_IMG"'", "node-name":"drive_sys1"}' \ + -blockdev '{"driver":"qcow2", "node-name":"drive_image1", + "file":"drive_sys1"}' +h1=$QEMU_HANDLE +_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return' + +echo +echo === Starting Dst VM2 === +echo + +_launch_qemu -machine q35 \ + -object iothread,id=iothread0 \ + -object "${tls_obj_base}"/server1,endpoint=server \ + -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true, + "bus":"pcie.0"}' \ + -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0", + "bus":"root0", "iothread":"iothread0"}' \ + -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1", + "bus":"virtio_scsi_pci0.0"}' \ + -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false}, + "filename":"'"$DST_IMG"'", "node-name":"drive_sys1"}' \ + -blockdev '{"driver":"qcow2", "node-name":"drive_image1", + "file":"drive_sys1"}' \ + -incoming defer +h2=$QEMU_HANDLE +_send_qemu_cmd $h2 '{"execute": "qmp_capabilities"}' 'return' + +echo +echo === Dst VM: Enable NBD server for incoming storage migration === +echo + +_send_qemu_cmd $h2 '{"execute": "nbd-server-start", "arguments": + {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": "'$port'"}}, + "tls-creds": "tls0"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g" +_send_qemu_cmd $h2 '{"execute": "block-export-add", "arguments": + {"node-name": "drive_image1", "type": "nbd", "writable": true, + "id": "drive_image1"}}' '{"return": {}}' + +echo +echo === Src VM: Mirror to dst NBD for outgoing storage migration === +echo + +_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments": + {"node-name": "mirror", "driver": "nbd", + "server": {"type": "inet", "host": "127.0.0.1", "port": "'$port'"}, + "export": "drive_image1", "tls-creds": "tls0", + "tls-hostname": "127.0.0.1"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g" +_send_qemu_cmd $h1 '{"execute": "blockdev-mirror", "arguments": + {"sync": "full", "device": "drive_image1", "target": "mirror", + "job-id": "drive_image1_53"}}' '{"return": {}}' +_timed_wait_for $h1 '"ready"' + +echo +echo === Cleaning up === +echo + +_send_qemu_cmd $h1 '{"execute":"quit"}' '' +_send_qemu_cmd $h2 '{"execute":"quit"}' '' + +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread.out b/tests/qemu-iotests/tests/nbd-tls-iothread.out new file mode 100644 index 0000000000..1d83d4f903 --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-tls-iothread.out @@ -0,0 +1,54 @@ +QA output created by nbd-tls-iothread + +== preparing TLS creds and spare port == +picked unused port +Generating a self signed certificate... +Generating a signed certificate... +Generating a signed certificate... + +== preparing image == +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +Formatting 'TEST_DIR/dst.IMGFMT', fmt=IMGFMT size=1073741824 + +=== Starting Src QEMU === + +{"execute": "qmp_capabilities"} +{"return": {}} + +=== Starting Dst VM2 === + +{"execute": "qmp_capabilities"} +{"return": {}} + +=== Dst VM: Enable NBD server for incoming storage migration === + +{"execute": "nbd-server-start", "arguments": + {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": PORT}}, + "tls-creds": "tls0"}} +{"return": {}} +{"execute": "block-export-add", "arguments": + {"node-name": "drive_image1", "type": "nbd", "writable": true, + "id": "drive_image1"}} +{"return": {}} + +=== Src VM: Mirror to dst NBD for outgoing storage migration === + +{"execute": "blockdev-add", "arguments": + {"node-name": "mirror", "driver": "nbd", + "server": {"type": "inet", "host": "127.0.0.1", "port": PORT}, + "export": "drive_image1", "tls-creds": "tls0", + "tls-hostname": "127.0.0.1"}} +{"return": {}} +{"execute": "blockdev-mirror", "arguments": + {"sync": "full", "device": "drive_image1", "target": "mirror", + "job-id": "drive_image1_53"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "drive_image1_53"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "drive_image1_53"}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "drive_image1_53"}} + +=== Cleaning up === + +{"execute":"quit"} +{"execute":"quit"} +*** done diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index 70d728ae9a..4ecbca6a41 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -41,8 +41,9 @@ endif # Pauth Tests ifneq ($(CROSS_CC_HAS_ARMV8_3),) -AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 +AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375 pauth-%: CFLAGS += -march=armv8.3-a +test-2375: CFLAGS += -march=armv8.3-a run-pauth-1: QEMU_OPTS += -cpu max run-pauth-2: QEMU_OPTS += -cpu max # Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45]. diff --git a/tests/tcg/aarch64/test-2375.c b/tests/tcg/aarch64/test-2375.c new file mode 100644 index 0000000000..84c7e7de71 --- /dev/null +++ b/tests/tcg/aarch64/test-2375.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (c) 2024 Linaro Ltd */ +/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */ + +#include + +int main(void) +{ + int r, z; + + asm("msr fpcr, %2\n\t" + "fjcvtzs %w0, %d3\n\t" + "cset %1, eq" + : "=r"(r), "=r"(z) + : "r"(0x01000000L), /* FZ = 1 */ + "w"(0xfcff00L)); /* denormal */ + + assert(r == 0); + assert(z == 0); + return 0; +} diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target index 4d09291c0c..7852fa62d8 100644 --- a/tests/tcg/sh4/Makefile.target +++ b/tests/tcg/sh4/Makefile.target @@ -17,3 +17,9 @@ TESTS += test-macl test-macw: CFLAGS += -O -g TESTS += test-macw + +test-addv: CFLAGS += -O -g +TESTS += test-addv + +test-subv: CFLAGS += -O -g +TESTS += test-subv diff --git a/tests/tcg/sh4/test-addv.c b/tests/tcg/sh4/test-addv.c new file mode 100644 index 0000000000..ca87fe746a --- /dev/null +++ b/tests/tcg/sh4/test-addv.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include + +static void addv(const int a, const int b, const int res, const int carry) +{ + int o = a, c; + + asm volatile("addv %2,%0\n" + "movt %1\n" + : "+r"(o), "=r"(c) : "r"(b) : ); + + if (c != carry || o != res) { + printf("ADDV %d, %d = %d/%d [T = %d/%d]\n", a, b, o, res, c, carry); + abort(); + } +} + +int main(void) +{ + addv(INT_MAX, 1, INT_MIN, 1); + addv(INT_MAX - 1, 1, INT_MAX, 0); + + return 0; +} diff --git a/tests/tcg/sh4/test-subv.c b/tests/tcg/sh4/test-subv.c new file mode 100644 index 0000000000..a3c2db96e4 --- /dev/null +++ b/tests/tcg/sh4/test-subv.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include + +static void subv(const int a, const int b, const int res, const int carry) +{ + int o = a, c; + + asm volatile("subv %2,%0\n" + "movt %1\n" + : "+r"(o), "=r"(c) : "r"(b) : ); + + if (c != carry || o != res) { + printf("SUBV %d, %d = %d/%d [T = %d/%d]\n", a, b, o, res, c, carry); + abort(); + } +} + +int main(void) +{ + subv(INT_MIN, 1, INT_MAX, 1); + subv(INT_MAX, -1, INT_MIN, 1); + subv(INT_MAX, 1, INT_MAX - 1, 0); + subv(0, 1, -1, 0); + subv(-1, -1, 0, 0); + + return 0; +} diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target index e64aab1b81..1d427cdc2c 100644 --- a/tests/tcg/x86_64/Makefile.target +++ b/tests/tcg/x86_64/Makefile.target @@ -8,6 +8,8 @@ include $(SRC_PATH)/tests/tcg/i386/Makefile.target +X86_64_TESTS += test-2413 + ifeq ($(filter %-linux-user, $(TARGET)),$(TARGET)) X86_64_TESTS += vsyscall X86_64_TESTS += noexec diff --git a/tests/tcg/x86_64/test-2413.c b/tests/tcg/x86_64/test-2413.c new file mode 100644 index 0000000000..456e5332fc --- /dev/null +++ b/tests/tcg/x86_64/test-2413.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright 2024 Linaro, Ltd. */ +/* See https://gitlab.com/qemu-project/qemu/-/issues/2413 */ + +#include + +void test(unsigned long *a, unsigned long *d, unsigned long c) +{ + asm("xorl %%eax, %%eax\n\t" + "xorl %%edx, %%edx\n\t" + "testb $0x20, %%cl\n\t" + "sete %%al\n\t" + "setne %%dl\n\t" + "shll %%cl, %%eax\n\t" + "shll %%cl, %%edx\n\t" + : "=a"(*a), "=d"(*d) + : "c"(c)); +} + +int main(void) +{ + unsigned long a, c, d; + + for (c = 0; c < 64; c++) { + test(&a, &d, c); + assert(a == (c & 0x20 ? 0 : 1u << (c & 0x1f))); + assert(d == (c & 0x20 ? 1u << (c & 0x1f) : 0)); + } + return 0; +} diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 8994337e12..9fdba24fce 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -330,6 +330,14 @@ static const struct SMPTestData data_generic_valid[] = { .config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 16), .expect_prefer_sockets = CPU_TOPOLOGY_GENERIC(8, 2, 4, 2, 16), .expect_prefer_cores = CPU_TOPOLOGY_GENERIC(8, 2, 4, 2, 16), + }, { + /* + * Unsupported parameters are always allowed to be set to '1' + * config: -smp 8,books=1,drawers=1,sockets=2,modules=1,dies=1,cores=2,threads=2,maxcpus=8 + * expect: cpus=8,sockets=2,cores=2,threads=2,maxcpus=8 */ + .config = SMP_CONFIG_WITH_FULL_TOPO(8, 1, 1, 2, 1, 1, 2, 2, 8), + .expect_prefer_sockets = CPU_TOPOLOGY_GENERIC(8, 2, 2, 2, 8), + .expect_prefer_cores = CPU_TOPOLOGY_GENERIC(8, 2, 2, 2, 8), }, }; @@ -337,21 +345,21 @@ static const struct SMPTestData data_generic_invalid[] = { { /* config: -smp 2,dies=2 */ .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), - .expect_error = "dies not supported by this machine's CPU topology", + .expect_error = "dies > 1 not supported by this machine's CPU topology", }, { /* config: -smp 2,clusters=2 */ .config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), - .expect_error = "clusters not supported by this machine's CPU topology", + .expect_error = "clusters > 1 not supported by this machine's CPU topology", }, { /* config: -smp 2,books=2 */ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0, F, 0), - .expect_error = "books not supported by this machine's CPU topology", + .expect_error = "books > 1 not supported by this machine's CPU topology", }, { /* config: -smp 2,drawers=2 */ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 2, T, 2, F, 0, F, 0, F, 0, F, 0, F, 0), - .expect_error = "drawers not supported by this machine's CPU topology", + .expect_error = "drawers > 1 not supported by this machine's CPU topology", }, { /* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */ .config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8), diff --git a/tests/vm/centos b/tests/vm/centos index 097a9ca14d..d25c8f8b5b 100755 --- a/tests/vm/centos +++ b/tests/vm/centos @@ -26,8 +26,8 @@ class CentosVM(basevm.BaseVM): export SRC_ARCHIVE=/dev/vdb; sudo chmod a+r $SRC_ARCHIVE; tar -xf $SRC_ARCHIVE; - make docker-test-block@centos8 {verbose} J={jobs} NETWORK=1; - make docker-test-quick@centos8 {verbose} J={jobs} NETWORK=1; + make docker-test-block@centos9 {verbose} J={jobs} NETWORK=1; + make docker-test-quick@centos9 {verbose} J={jobs} NETWORK=1; """ def build_image(self, img): diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 3af5ac5bcf..bceeeb0352 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -99,7 +99,7 @@ void gd_egl_draw(VirtualConsole *vc) #ifdef CONFIG_GBM if (dmabuf) { egl_dmabuf_create_fence(dmabuf); - if (dmabuf->fence_fd > 0) { + if (dmabuf->fence_fd >= 0) { qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc); return; } @@ -150,6 +150,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl) vc, vc->window ? vc->window : vc->gfx.drawing_area); if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) { + gd_egl_draw(vc); return; } diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 52dcac161e..b490727402 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -86,7 +86,7 @@ void gd_gl_area_draw(VirtualConsole *vc) #ifdef CONFIG_GBM if (dmabuf) { egl_dmabuf_create_fence(dmabuf); - if (dmabuf->fence_fd > 0) { + if (dmabuf->fence_fd >= 0) { qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc); return; } @@ -126,6 +126,7 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl) gd_update_monitor_refresh_rate(vc, vc->window ? vc->window : vc->gfx.drawing_area); if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) { + gd_gl_area_draw(vc); return; } diff --git a/ui/gtk.c b/ui/gtk.c index 810d7fc796..f1bb838ed3 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -597,10 +597,12 @@ void gd_hw_gl_flushed(void *vcon) VirtualConsole *vc = vcon; QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; - qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL); - close(dmabuf->fence_fd); - dmabuf->fence_fd = -1; - graphic_hw_gl_block(vc->gfx.dcl.con, false); + if (dmabuf->fence_fd >= 0) { + qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL); + close(dmabuf->fence_fd); + dmabuf->fence_fd = -1; + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } } /** DisplayState Callbacks (opengl version) **/ @@ -887,7 +889,7 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, int x, y; int mx, my; int fbh, fbw; - int ww, wh, ws; + int ww, wh; if (!vc->gfx.ds) { return TRUE; @@ -895,11 +897,15 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y; - ww = gtk_widget_get_allocated_width(widget); wh = gtk_widget_get_allocated_height(widget); - ws = gtk_widget_get_scale_factor(widget); + /* + * `widget` may not have the same size with the frame buffer. + * In such cases, some paddings are needed around the `vc`. + * To achieve that, `vc` will be displayed at (mx, my) + * so that it is displayed at the center of the widget. + */ mx = my = 0; if (ww > fbw) { mx = (ww - fbw) / 2; @@ -908,8 +914,12 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, my = (wh - fbh) / 2; } - x = (motion->x - mx) / vc->gfx.scale_x * ws; - y = (motion->y - my) / vc->gfx.scale_y * ws; + /* + * `motion` is reported in `widget` coordinates + * so translating it to the coordinates in `vc`. + */ + x = (motion->x - mx) / vc->gfx.scale_x; + y = (motion->y - my) / vc->gfx.scale_y; if (qemu_input_is_absolute(vc->gfx.dcl.con)) { if (x < 0 || y < 0 || diff --git a/ui/sdl2.c b/ui/sdl2.c index 4971963f00..0a0eb5a42d 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -874,6 +874,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); #endif SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + SDL_EnableScreenSaver(); memset(&info, 0, sizeof(info)); SDL_VERSION(&info.version);