aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-07-06 11:24:58 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-07-06 11:24:58 +0100
commit9aef0954195cc592e86846dbbe7f3c2c5603690a (patch)
tree9f5060babce3eebabb4aa3ba2f3321073f87ca54
parent9bef7ea9d93ee6b6297a5be6cb5a557f7d1764c9 (diff)
parent7ca6f2ad375d32e81844788dbc2b05a04cc391b5 (diff)
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* More Meson test conversions and configure cleanups * Generalize XSAVE area offset so that it matches AMD processors on KVM * Improvements for -display and deprecation of -no-quit * Enable SMP configuration as a compound machine property ("-M smp.cpus=...") * Haiku compilation fix * Add icon on Darwin # gpg: Signature made Tue 06 Jul 2021 08:35:23 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (40 commits) config-host.mak: remove unused compiler-related lines Set icon for QEMU binary on Mac OS qemu-option: remove now-dead code machine: add smp compound property vl: switch -M parsing to keyval keyval: introduce keyval_parse_into keyval: introduce keyval_merge qom: export more functions for use with non-UserCreatable objects configure: convert compiler tests to meson, part 6 configure: convert compiler tests to meson, part 5 configure: convert compiler tests to meson, part 4 configure: convert compiler tests to meson, part 3 configure: convert compiler tests to meson, part 2 configure: convert compiler tests to meson, part 1 configure: convert HAVE_BROKEN_SIZE_MAX to meson configure, meson: move CONFIG_IVSHMEM to meson meson: store dependency('threads') in a variable meson: sort existing compiler tests configure, meson: convert libxml2 detection to meson configure, meson: convert liburing detection to meson ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--Makefile2
-rwxr-xr-xconfigure1023
-rw-r--r--docs/devel/kconfig.rst2
-rw-r--r--docs/system/deprecated.rst12
-rw-r--r--hw/core/machine.c108
-rw-r--r--hw/display/meson.build6
-rw-r--r--include/hw/boards.h1
-rw-r--r--include/qemu/option.h6
-rw-r--r--include/qom/object.h23
-rw-r--r--meson.build231
-rw-r--r--meson_options.txt12
-rw-r--r--qemu-options.hx50
-rw-r--r--qom/object_interfaces.c58
-rw-r--r--scripts/coverity-scan/COMPONENTS.md6
-rwxr-xr-xscripts/coverity-scan/run-coverity-scan8
-rwxr-xr-xscripts/entitlement.sh10
-rw-r--r--softmmu/vl.c347
-rw-r--r--target/i386/cpu.c18
-rw-r--r--target/i386/cpu.h41
-rw-r--r--target/i386/hvf/hvf-cpu.c29
-rw-r--r--target/i386/hvf/hvf.c9
-rw-r--r--target/i386/hvf/x86hvf.c19
-rw-r--r--target/i386/kvm/kvm-cpu.c30
-rw-r--r--target/i386/kvm/kvm.c59
-rw-r--r--target/i386/tcg/fpu_helper.c1
-rw-r--r--target/i386/tcg/tcg-cpu.c20
-rw-r--r--target/i386/tcg/tcg-cpu.h57
-rw-r--r--target/i386/xsave_helper.c267
-rw-r--r--tests/qtest/numa-test.c22
-rw-r--r--tests/unit/test-keyval.c58
-rw-r--r--tests/unit/test-qemu-opts.c35
-rw-r--r--util/keyval.c123
-rw-r--r--util/meson.build5
-rw-r--r--util/qemu-option.c51
34 files changed, 1170 insertions, 1579 deletions
diff --git a/Makefile b/Makefile
index 30f19d33bb..6c36330eef 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ SRC_PATH=.
# we have explicit rules for everything
MAKEFLAGS += -rR
-SHELL = /usr/bin/env bash -o pipefail
+SHELL = bash -o pipefail
# Usage: $(call quiet-command,command and args,"NAME","args to print")
# This will run "command and args", and either:
diff --git a/configure b/configure
index e799d908a3..650d9c0735 100755
--- a/configure
+++ b/configure
@@ -315,7 +315,7 @@ xen="$default_feature"
xen_ctrl_version="$default_feature"
xen_pci_passthrough="auto"
linux_aio="$default_feature"
-linux_io_uring="$default_feature"
+linux_io_uring="auto"
cap_ng="auto"
attr="auto"
xfs="$default_feature"
@@ -408,8 +408,8 @@ gnutls="auto"
nettle="auto"
gcrypt="auto"
auth_pam="auto"
-vte="$default_feature"
-virglrenderer="$default_feature"
+vte="auto"
+virglrenderer="auto"
tpm="$default_feature"
libssh="$default_feature"
live_block_migration=${default_feature:-yes}
@@ -425,15 +425,15 @@ vdi=${default_feature:-yes}
vvfat=${default_feature:-yes}
qed=${default_feature:-yes}
parallels=${default_feature:-yes}
-libxml2="$default_feature"
+libxml2="auto"
debug_mutex="no"
-libpmem="$default_feature"
+libpmem="auto"
default_devices="true"
plugins="no"
fuzzing="no"
rng_none="no"
secret_keyring="$default_feature"
-libdaxctl="$default_feature"
+libdaxctl="auto"
meson=""
ninja=""
skip_meson=no
@@ -521,9 +521,6 @@ query_pkg_config() {
pkg_config=query_pkg_config
sdl2_config="${SDL2_CONFIG-${cross_prefix}sdl2-config}"
-# If the user hasn't specified ARFLAGS, default to 'rv', just as make does.
-ARFLAGS="${ARFLAGS-rv}"
-
# default flags for all hosts
# We use -fwrapv to tell the compiler that we require a C dialect where
# left shift of signed integers is well defined and has the expected
@@ -1205,9 +1202,9 @@ for opt do
;;
--enable-linux-aio) linux_aio="yes"
;;
- --disable-linux-io-uring) linux_io_uring="no"
+ --disable-linux-io-uring) linux_io_uring="disabled"
;;
- --enable-linux-io-uring) linux_io_uring="yes"
+ --enable-linux-io-uring) linux_io_uring="enabled"
;;
--disable-attr) attr="disabled"
;;
@@ -1395,13 +1392,13 @@ for opt do
;;
--disable-pvrdma) pvrdma="no"
;;
- --disable-vte) vte="no"
+ --disable-vte) vte="disabled"
;;
- --enable-vte) vte="yes"
+ --enable-vte) vte="enabled"
;;
- --disable-virglrenderer) virglrenderer="no"
+ --disable-virglrenderer) virglrenderer="disabled"
;;
- --enable-virglrenderer) virglrenderer="yes"
+ --enable-virglrenderer) virglrenderer="enabled"
;;
--disable-tpm) tpm="no"
;;
@@ -1419,9 +1416,9 @@ for opt do
;;
--enable-numa) numa="yes"
;;
- --disable-libxml2) libxml2="no"
+ --disable-libxml2) libxml2="disabled"
;;
- --enable-libxml2) libxml2="yes"
+ --enable-libxml2) libxml2="enabled"
;;
--disable-tcmalloc) tcmalloc="no"
;;
@@ -1504,9 +1501,9 @@ for opt do
;;
--disable-debug-mutex) debug_mutex=no
;;
- --enable-libpmem) libpmem=yes
+ --enable-libpmem) libpmem=disabled
;;
- --disable-libpmem) libpmem=no
+ --disable-libpmem) libpmem=enabled
;;
--enable-xkbcommon) xkbcommon="enabled"
;;
@@ -1534,9 +1531,9 @@ for opt do
;;
--disable-keyring) secret_keyring="no"
;;
- --enable-libdaxctl) libdaxctl=yes
+ --enable-libdaxctl) libdaxctl=disabled
;;
- --disable-libdaxctl) libdaxctl=no
+ --disable-libdaxctl) libdaxctl=enabled
;;
--enable-fuse) fuse="enabled"
;;
@@ -2376,20 +2373,6 @@ if test "$softmmu" = "no"; then
fi
##########################################
-# Some versions of Mac OS X incorrectly define SIZE_MAX
-cat > $TMPC << EOF
-#include <stdint.h>
-#include <stdio.h>
-int main(int argc, char *argv[]) {
- return printf("%zu", SIZE_MAX);
-}
-EOF
-have_broken_size_max=no
-if ! compile_object -Werror ; then
- have_broken_size_max=yes
-fi
-
-##########################################
# L2TPV3 probe
cat > $TMPC <<EOF
@@ -2800,28 +2783,6 @@ EOF
fi
##########################################
-# VTE probe
-
-if test "$vte" != "no"; then
- vteminversion="0.32.0"
- if $pkg_config --exists "vte-2.91"; then
- vtepackage="vte-2.91"
- else
- vtepackage="vte-2.90"
- fi
- if $pkg_config --exists "$vtepackage >= $vteminversion"; then
- vte_cflags=$($pkg_config --cflags $vtepackage)
- vte_libs=$($pkg_config --libs $vtepackage)
- vteversion=$($pkg_config --modversion $vtepackage)
- vte="yes"
- elif test "$vte" = "yes"; then
- feature_not_found "vte" "Install libvte-2.90/2.91 devel"
- else
- vte="no"
- fi
-fi
-
-##########################################
# RDMA needs OpenFabrics libraries
if test "$rdma" != "no" ; then
cat > $TMPC <<EOF
@@ -3356,21 +3317,6 @@ EOF
linux_aio=no
fi
fi
-##########################################
-# linux-io-uring probe
-
-if test "$linux_io_uring" != "no" ; then
- if $pkg_config liburing; then
- linux_io_uring_cflags=$($pkg_config --cflags liburing)
- linux_io_uring_libs=$($pkg_config --libs liburing)
- linux_io_uring=yes
- else
- if test "$linux_io_uring" = "yes" ; then
- feature_not_found "linux io_uring" "Install liburing devel"
- fi
- linux_io_uring=no
- fi
-fi
##########################################
# TPM emulation is only on POSIX
@@ -3447,107 +3393,6 @@ EOF
fi
##########################################
-# libxml2 probe
-if test "$libxml2" != "no" ; then
- if $pkg_config --exists libxml-2.0; then
- libxml2="yes"
- libxml2_cflags=$($pkg_config --cflags libxml-2.0)
- libxml2_libs=$($pkg_config --libs libxml-2.0)
- else
- if test "$libxml2" = "yes"; then
- feature_not_found "libxml2" "Install libxml2 devel"
- fi
- libxml2="no"
- fi
-fi
-
-# Check for inotify functions when we are building linux-user
-# emulator. This is done because older glibc versions don't
-# have syscall stubs for these implemented. In that case we
-# don't provide them even if kernel supports them.
-#
-inotify=no
-cat > $TMPC << EOF
-#include <sys/inotify.h>
-
-int
-main(void)
-{
- /* try to start inotify */
- return inotify_init();
-}
-EOF
-if compile_prog "" "" ; then
- inotify=yes
-fi
-
-inotify1=no
-cat > $TMPC << EOF
-#include <sys/inotify.h>
-
-int
-main(void)
-{
- /* try to start inotify */
- return inotify_init1(0);
-}
-EOF
-if compile_prog "" "" ; then
- inotify1=yes
-fi
-
-# check if pipe2 is there
-pipe2=no
-cat > $TMPC << EOF
-#include <unistd.h>
-#include <fcntl.h>
-
-int main(void)
-{
- int pipefd[2];
- return pipe2(pipefd, O_CLOEXEC);
-}
-EOF
-if compile_prog "" "" ; then
- pipe2=yes
-fi
-
-# check if accept4 is there
-accept4=no
-cat > $TMPC << EOF
-#include <sys/socket.h>
-#include <stddef.h>
-
-int main(void)
-{
- accept4(0, NULL, NULL, SOCK_CLOEXEC);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- accept4=yes
-fi
-
-# check if tee/splice is there. vmsplice was added same time.
-splice=no
-cat > $TMPC << EOF
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-
-int main(void)
-{
- int len, fd = 0;
- len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
- splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- splice=yes
-fi
-
-##########################################
# libnuma probe
if test "$numa" != "no" ; then
@@ -3577,59 +3422,6 @@ elif test "$jemalloc" = "yes" ; then
malloc=jemalloc
fi
-##########################################
-# signalfd probe
-signalfd="no"
-cat > $TMPC << EOF
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <signal.h>
-int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }
-EOF
-
-if compile_prog "" "" ; then
- signalfd=yes
-fi
-
-# check if optreset global is declared by <getopt.h>
-optreset="no"
-cat > $TMPC << EOF
-#include <getopt.h>
-int main(void) { return optreset; }
-EOF
-
-if compile_prog "" "" ; then
- optreset=yes
-fi
-
-# check if eventfd is supported
-eventfd=no
-cat > $TMPC << EOF
-#include <sys/eventfd.h>
-
-int main(void)
-{
- return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-}
-EOF
-if compile_prog "" "" ; then
- eventfd=yes
-fi
-
-# check if memfd is supported
-memfd=no
-cat > $TMPC << EOF
-#include <sys/mman.h>
-
-int main(void)
-{
- return memfd_create("foo", MFD_ALLOW_SEALING);
-}
-EOF
-if compile_prog "" "" ; then
- memfd=yes
-fi
-
# check for usbfs
have_usbfs=no
if test "$linux_user" = "yes"; then
@@ -3654,297 +3446,6 @@ EOF
fi
fi
-# check for fallocate
-fallocate=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-
-int main(void)
-{
- fallocate(0, 0, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- fallocate=yes
-fi
-
-# check for fallocate hole punching
-fallocate_punch_hole=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-#include <linux/falloc.h>
-
-int main(void)
-{
- fallocate(0, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- fallocate_punch_hole=yes
-fi
-
-# check that fallocate supports range zeroing inside the file
-fallocate_zero_range=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-#include <linux/falloc.h>
-
-int main(void)
-{
- fallocate(0, FALLOC_FL_ZERO_RANGE, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- fallocate_zero_range=yes
-fi
-
-# check for posix_fallocate
-posix_fallocate=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-
-int main(void)
-{
- posix_fallocate(0, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- posix_fallocate=yes
-fi
-
-# check for sync_file_range
-sync_file_range=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-
-int main(void)
-{
- sync_file_range(0, 0, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- sync_file_range=yes
-fi
-
-# check for linux/fiemap.h and FS_IOC_FIEMAP
-fiemap=no
-cat > $TMPC << EOF
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <linux/fiemap.h>
-
-int main(void)
-{
- ioctl(0, FS_IOC_FIEMAP, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- fiemap=yes
-fi
-
-# check for dup3
-dup3=no
-cat > $TMPC << EOF
-#include <unistd.h>
-
-int main(void)
-{
- dup3(0, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- dup3=yes
-fi
-
-# check for ppoll support
-ppoll=no
-cat > $TMPC << EOF
-#include <poll.h>
-
-int main(void)
-{
- struct pollfd pfd = { .fd = 0, .events = 0, .revents = 0 };
- ppoll(&pfd, 1, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- ppoll=yes
-fi
-
-# check for prctl(PR_SET_TIMERSLACK , ... ) support
-prctl_pr_set_timerslack=no
-cat > $TMPC << EOF
-#include <sys/prctl.h>
-
-int main(void)
-{
- prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- prctl_pr_set_timerslack=yes
-fi
-
-# check for epoll support
-epoll=no
-cat > $TMPC << EOF
-#include <sys/epoll.h>
-
-int main(void)
-{
- epoll_create(0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- epoll=yes
-fi
-
-# epoll_create1 is a later addition
-# so we must check separately for its presence
-epoll_create1=no
-cat > $TMPC << EOF
-#include <sys/epoll.h>
-
-int main(void)
-{
- /* Note that we use epoll_create1 as a value, not as
- * a function being called. This is necessary so that on
- * old SPARC glibc versions where the function was present in
- * the library but not declared in the header file we will
- * fail the configure check. (Otherwise we will get a compiler
- * warning but not an error, and will proceed to fail the
- * qemu compile where we compile with -Werror.)
- */
- return (int)(uintptr_t)&epoll_create1;
-}
-EOF
-if compile_prog "" "" ; then
- epoll_create1=yes
-fi
-
-# check for sendfile support
-sendfile=no
-cat > $TMPC << EOF
-#include <sys/sendfile.h>
-
-int main(void)
-{
- return sendfile(0, 0, 0, 0);
-}
-EOF
-if compile_prog "" "" ; then
- sendfile=yes
-fi
-
-# check for timerfd support (glibc 2.8 and newer)
-timerfd=no
-cat > $TMPC << EOF
-#include <sys/timerfd.h>
-
-int main(void)
-{
- return(timerfd_create(CLOCK_REALTIME, 0));
-}
-EOF
-if compile_prog "" "" ; then
- timerfd=yes
-fi
-
-# check for setns and unshare support
-setns=no
-cat > $TMPC << EOF
-#include <sched.h>
-
-int main(void)
-{
- int ret;
- ret = setns(0, 0);
- ret = unshare(0);
- return ret;
-}
-EOF
-if compile_prog "" "" ; then
- setns=yes
-fi
-
-# clock_adjtime probe
-clock_adjtime=no
-cat > $TMPC <<EOF
-#include <time.h>
-#include <sys/timex.h>
-
-int main(void)
-{
- return clock_adjtime(0, 0);
-}
-EOF
-clock_adjtime=no
-if compile_prog "" "" ; then
- clock_adjtime=yes
-fi
-
-# syncfs probe
-syncfs=no
-cat > $TMPC <<EOF
-#include <unistd.h>
-
-int main(void)
-{
- return syncfs(0);
-}
-EOF
-syncfs=no
-if compile_prog "" "" ; then
- syncfs=yes
-fi
-
-# Search for bswap_32 function
-byteswap_h=no
-cat > $TMPC << EOF
-#include <byteswap.h>
-int main(void) { return bswap_32(0); }
-EOF
-if compile_prog "" "" ; then
- byteswap_h=yes
-fi
-
-# Search for bswap32 function
-bswap_h=no
-cat > $TMPC << EOF
-#include <sys/endian.h>
-#include <sys/types.h>
-#include <machine/bswap.h>
-int main(void) { return bswap32(0); }
-EOF
-if compile_prog "" "" ; then
- bswap_h=yes
-fi
-
-# Check whether we have openpty() in either libc or libutil
-cat > $TMPC << EOF
-extern int openpty(int *am, int *as, char *name, void *termp, void *winp);
-int main(void) { return openpty(0, 0, 0, 0, 0); }
-EOF
-
-have_openpty="no"
-if compile_prog "" "" ; then
- have_openpty="yes"
-else
- if compile_prog "" "-lutil" ; then
- have_openpty="yes"
- fi
-fi
-
##########################################
# spice probe
if test "$spice_protocol" != "no" ; then
@@ -4059,28 +3560,6 @@ EOF
fi
##########################################
-# virgl renderer probe
-
-if test "$virglrenderer" != "no" ; then
- cat > $TMPC << EOF
-#include <virglrenderer.h>
-int main(void) { virgl_renderer_poll(); return 0; }
-EOF
- virgl_cflags=$($pkg_config --cflags virglrenderer 2>/dev/null)
- virgl_libs=$($pkg_config --libs virglrenderer 2>/dev/null)
- virgl_version=$($pkg_config --modversion virglrenderer 2>/dev/null)
- if $pkg_config virglrenderer >/dev/null 2>&1 && \
- compile_prog "$virgl_cflags" "$virgl_libs" ; then
- virglrenderer="yes"
- else
- if test "$virglrenderer" = "yes" ; then
- feature_not_found "virglrenderer"
- fi
- virglrenderer="no"
- fi
-fi
-
-##########################################
# capstone
case "$capstone" in
@@ -4091,66 +3570,6 @@ case "$capstone" in
esac
##########################################
-# check if we have fdatasync
-
-fdatasync=no
-cat > $TMPC << EOF
-#include <unistd.h>
-int main(void) {
-#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
-return fdatasync(0);
-#else
-#error Not supported
-#endif
-}
-EOF
-if compile_prog "" "" ; then
- fdatasync=yes
-fi
-
-##########################################
-# check if we have madvise
-
-madvise=no
-cat > $TMPC << EOF
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <stddef.h>
-int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }
-EOF
-if compile_prog "" "" ; then
- madvise=yes
-fi
-
-##########################################
-# check if we have posix_madvise
-
-posix_madvise=no
-cat > $TMPC << EOF
-#include <sys/mman.h>
-#include <stddef.h>
-int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }
-EOF
-if compile_prog "" "" ; then
- posix_madvise=yes
-fi
-
-##########################################
-# check if we have posix_memalign()
-
-posix_memalign=no
-cat > $TMPC << EOF
-#include <stdlib.h>
-int main(void) {
- void *p;
- return posix_memalign(&p, 8, 8);
-}
-EOF
-if compile_prog "" "" ; then
- posix_memalign=yes
-fi
-
-##########################################
# check if we have posix_syslog
posix_syslog=no
@@ -4163,59 +3582,6 @@ if compile_prog "" "" ; then
fi
##########################################
-# check if we have sem_timedwait
-
-sem_timedwait=no
-cat > $TMPC << EOF
-#include <semaphore.h>
-int main(void) { sem_t s; struct timespec t = {0}; return sem_timedwait(&s, &t); }
-EOF
-if compile_prog "" "" ; then
- sem_timedwait=yes
-fi
-
-##########################################
-# check if we have strchrnul
-
-strchrnul=no
-cat > $TMPC << EOF
-#include <string.h>
-int main(void);
-// Use a haystack that the compiler shouldn't be able to constant fold
-char *haystack = (char*)&main;
-int main(void) { return strchrnul(haystack, 'x') != &haystack[6]; }
-EOF
-if compile_prog "" "" ; then
- strchrnul=yes
-fi
-
-#########################################
-# check if we have st_atim
-
-st_atim=no
-cat > $TMPC << EOF
-#include <sys/stat.h>
-#include <stddef.h>
-int main(void) { return offsetof(struct stat, st_atim); }
-EOF
-if compile_prog "" "" ; then
- st_atim=yes
-fi
-
-##########################################
-# check if we have sigev_notify_thread_id
-
-sigev_notify_thread_id=no
-cat > $TMPC << EOF
-#include <stddef.h>
-#include <signal.h>
-int main(void) { return offsetof(struct sigevent, sigev_notify_thread_id); }
-EOF
-if compile_prog "" "" ; then
- sigev_notify_thread_id=yes
-fi
-
-##########################################
# check if trace backend exists
$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null
@@ -4394,65 +3760,6 @@ else # "$safe_stack" = ""
fi
fi
-##########################################
-# check if we have open_by_handle_at
-
-open_by_handle_at=no
-cat > $TMPC << EOF
-#include <fcntl.h>
-#if !defined(AT_EMPTY_PATH)
-# error missing definition
-#else
-int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
-#endif
-EOF
-if compile_prog "" "" ; then
- open_by_handle_at=yes
-fi
-
-########################################
-# check if we have linux/magic.h
-
-linux_magic_h=no
-cat > $TMPC << EOF
-#include <linux/magic.h>
-int main(void) {
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- linux_magic_h=yes
-fi
-
-########################################
-# check if we have valgrind/valgrind.h
-
-valgrind_h=no
-cat > $TMPC << EOF
-#include <valgrind/valgrind.h>
-int main(void) {
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- valgrind_h=yes
-fi
-
-########################################
-# check if environ is declared
-
-has_environ=no
-cat > $TMPC << EOF
-#include <unistd.h>
-int main(void) {
- environ = 0;
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- has_environ=yes
-fi
-
########################################
# check if cpuid.h is usable.
@@ -4725,20 +4032,6 @@ if test "$fortify_source" != "no"; then
fi
fi
-###############################################
-# Check if copy_file_range is provided by glibc
-have_copy_file_range=no
-cat > $TMPC << EOF
-#include <unistd.h>
-int main(void) {
- copy_file_range(0, NULL, 0, NULL, 0, 0);
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- have_copy_file_range=yes
-fi
-
##########################################
# check if struct fsxattr is available via linux/fs.h
@@ -4786,19 +4079,6 @@ else
fi
##########################################
-# check if rtnetlink.h exists and is useful
-have_rtnetlink=no
-cat > $TMPC << EOF
-#include <linux/rtnetlink.h>
-int main(void) {
- return IFLA_PROTO_DOWN;
-}
-EOF
-if compile_prog "" "" ; then
- have_rtnetlink=yes
-fi
-
-##########################################
# check for usable AF_VSOCK environment
have_af_vsock=no
cat > $TMPC << EOF
@@ -4851,49 +4131,6 @@ then
fi
-#################################################
-# check for sysmacros.h
-
-have_sysmacros=no
-cat > $TMPC << EOF
-#include <sys/sysmacros.h>
-int main(void) {
- return makedev(0, 0);
-}
-EOF
-if compile_prog "" "" ; then
- have_sysmacros=yes
-fi
-
-##########################################
-# check for utmpx.h, it is missing e.g. on OpenBSD
-
-have_utmpx=no
-cat > $TMPC << EOF
-#include <utmpx.h>
-struct utmpx user_info;
-int main(void) {
- return 0;
-}
-EOF
-if compile_prog "" "" ; then
- have_utmpx=yes
-fi
-
-##########################################
-# check for getrandom()
-
-have_getrandom=no
-cat > $TMPC << EOF
-#include <sys/random.h>
-int main(void) {
- return getrandom(0, 0, GRND_NONBLOCK);
-}
-EOF
-if compile_prog "" "" ; then
- have_getrandom=yes
-fi
-
##########################################
# checks for sanitizers
@@ -4978,38 +4215,6 @@ EOF
fi
##########################################
-# check for libpmem
-
-if test "$libpmem" != "no"; then
- if $pkg_config --exists "libpmem"; then
- libpmem="yes"
- libpmem_libs=$($pkg_config --libs libpmem)
- libpmem_cflags=$($pkg_config --cflags libpmem)
- else
- if test "$libpmem" = "yes" ; then
- feature_not_found "libpmem" "Install nvml or pmdk"
- fi
- libpmem="no"
- fi
-fi
-
-##########################################
-# check for libdaxctl
-
-if test "$libdaxctl" != "no"; then
- if $pkg_config --atleast-version=57 "libdaxctl"; then
- libdaxctl="yes"
- libdaxctl_libs=$($pkg_config --libs libdaxctl)
- libdaxctl_cflags=$($pkg_config --cflags libdaxctl)
- else
- if test "$libdaxctl" = "yes" ; then
- feature_not_found "libdaxctl" "Install libdaxctl"
- fi
- libdaxctl="no"
- fi
-fi
-
-##########################################
# check for slirp
case "$slirp" in
@@ -5143,11 +4348,6 @@ if test "$mingw32" = "yes" ; then
done
fi
-# We can only support ivshmem if we have eventfd
-if [ "$eventfd" = "yes" ]; then
- ivshmem=yes
-fi
-
# Probe for guest agent support/options
if [ "$guest_agent" != "no" ]; then
@@ -5372,96 +4572,9 @@ fi
if test "$module_upgrades" = "yes"; then
echo "CONFIG_MODULE_UPGRADES=y" >> $config_host_mak
fi
-if test "$pipe2" = "yes" ; then
- echo "CONFIG_PIPE2=y" >> $config_host_mak
-fi
-if test "$accept4" = "yes" ; then
- echo "CONFIG_ACCEPT4=y" >> $config_host_mak
-fi
-if test "$splice" = "yes" ; then
- echo "CONFIG_SPLICE=y" >> $config_host_mak
-fi
-if test "$eventfd" = "yes" ; then
- echo "CONFIG_EVENTFD=y" >> $config_host_mak
-fi
-if test "$memfd" = "yes" ; then
- echo "CONFIG_MEMFD=y" >> $config_host_mak
-fi
if test "$have_usbfs" = "yes" ; then
echo "CONFIG_USBFS=y" >> $config_host_mak
fi
-if test "$fallocate" = "yes" ; then
- echo "CONFIG_FALLOCATE=y" >> $config_host_mak
-fi
-if test "$fallocate_punch_hole" = "yes" ; then
- echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak
-fi
-if test "$fallocate_zero_range" = "yes" ; then
- echo "CONFIG_FALLOCATE_ZERO_RANGE=y" >> $config_host_mak
-fi
-if test "$posix_fallocate" = "yes" ; then
- echo "CONFIG_POSIX_FALLOCATE=y" >> $config_host_mak
-fi
-if test "$sync_file_range" = "yes" ; then
- echo "CONFIG_SYNC_FILE_RANGE=y" >> $config_host_mak
-fi
-if test "$fiemap" = "yes" ; then
- echo "CONFIG_FIEMAP=y" >> $config_host_mak
-fi
-if test "$dup3" = "yes" ; then
- echo "CONFIG_DUP3=y" >> $config_host_mak
-fi
-if test "$ppoll" = "yes" ; then
- echo "CONFIG_PPOLL=y" >> $config_host_mak
-fi
-if test "$prctl_pr_set_timerslack" = "yes" ; then
- echo "CONFIG_PRCTL_PR_SET_TIMERSLACK=y" >> $config_host_mak
-fi
-if test "$epoll" = "yes" ; then
- echo "CONFIG_EPOLL=y" >> $config_host_mak
-fi
-if test "$epoll_create1" = "yes" ; then
- echo "CONFIG_EPOLL_CREATE1=y" >> $config_host_mak
-fi
-if test "$sendfile" = "yes" ; then
- echo "CONFIG_SENDFILE=y" >> $config_host_mak
-fi
-if test "$timerfd" = "yes" ; then
- echo "CONFIG_TIMERFD=y" >> $config_host_mak
-fi
-if test "$setns" = "yes" ; then
- echo "CONFIG_SETNS=y" >> $config_host_mak
-fi
-if test "$clock_adjtime" = "yes" ; then
- echo "CONFIG_CLOCK_ADJTIME=y" >> $config_host_mak
-fi
-if test "$syncfs" = "yes" ; then
- echo "CONFIG_SYNCFS=y" >> $config_host_mak
-fi
-if test "$inotify" = "yes" ; then
- echo "CONFIG_INOTIFY=y" >> $config_host_mak
-fi
-if test "$inotify1" = "yes" ; then
- echo "CONFIG_INOTIFY1=y" >> $config_host_mak
-fi
-if test "$sem_timedwait" = "yes" ; then
- echo "CONFIG_SEM_TIMEDWAIT=y" >> $config_host_mak
-fi
-if test "$strchrnul" = "yes" ; then
- echo "HAVE_STRCHRNUL=y" >> $config_host_mak
-fi
-if test "$st_atim" = "yes" ; then
- echo "HAVE_STRUCT_STAT_ST_ATIM=y" >> $config_host_mak
-fi
-if test "$sigev_notify_thread_id" = "yes" ; then
- echo "HAVE_SIGEV_NOTIFY_THREAD_ID=y" >> $config_host_mak
-fi
-if test "$byteswap_h" = "yes" ; then
- echo "CONFIG_BYTESWAP_H=y" >> $config_host_mak
-fi
-if test "$bswap_h" = "yes" ; then
- echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak
-fi
if test "$gio" = "yes" ; then
echo "CONFIG_GIO=y" >> $config_host_mak
echo "GIO_CFLAGS=$gio_cflags" >> $config_host_mak
@@ -5471,12 +4584,6 @@ if test "$gdbus_codegen" != "" ; then
echo "GDBUS_CODEGEN=$gdbus_codegen" >> $config_host_mak
fi
echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
-if test "$have_broken_size_max" = "yes" ; then
- echo "HAVE_BROKEN_SIZE_MAX=y" >> $config_host_mak
-fi
-if test "$have_openpty" = "yes" ; then
- echo "HAVE_OPENPTY=y" >> $config_host_mak
-fi
# Work around a system header bug with some kernel/XFS header
# versions where they both try to define 'struct fsxattr':
@@ -5485,19 +4592,6 @@ fi
if test "$have_fsxattr" = "yes" ; then
echo "HAVE_FSXATTR=y" >> $config_host_mak
fi
-if test "$have_copy_file_range" = "yes" ; then
- echo "HAVE_COPY_FILE_RANGE=y" >> $config_host_mak
-fi
-if test "$vte" = "yes" ; then
- echo "CONFIG_VTE=y" >> $config_host_mak
- echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
- echo "VTE_LIBS=$vte_libs" >> $config_host_mak
-fi
-if test "$virglrenderer" = "yes" ; then
- echo "CONFIG_VIRGL=y" >> $config_host_mak
- echo "VIRGL_CFLAGS=$virgl_cflags" >> $config_host_mak
- echo "VIRGL_LIBS=$virgl_libs" >> $config_host_mak
-fi
if test "$xen" = "enabled" ; then
echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
@@ -5507,11 +4601,6 @@ fi
if test "$linux_aio" = "yes" ; then
echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
fi
-if test "$linux_io_uring" = "yes" ; then
- echo "CONFIG_LINUX_IO_URING=y" >> $config_host_mak
- echo "LINUX_IO_URING_CFLAGS=$linux_io_uring_cflags" >> $config_host_mak
- echo "LINUX_IO_URING_LIBS=$linux_io_uring_libs" >> $config_host_mak
-fi
if test "$vhost_scsi" = "yes" ; then
echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
fi
@@ -5551,27 +4640,9 @@ fi
if test "$membarrier" = "yes" ; then
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
fi
-if test "$signalfd" = "yes" ; then
- echo "CONFIG_SIGNALFD=y" >> $config_host_mak
-fi
-if test "$optreset" = "yes" ; then
- echo "HAVE_OPTRESET=y" >> $config_host_mak
-fi
if test "$tcg" = "enabled" -a "$tcg_interpreter" = "true" ; then
echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak
fi
-if test "$fdatasync" = "yes" ; then
- echo "CONFIG_FDATASYNC=y" >> $config_host_mak
-fi
-if test "$madvise" = "yes" ; then
- echo "CONFIG_MADVISE=y" >> $config_host_mak
-fi
-if test "$posix_madvise" = "yes" ; then
- echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
-fi
-if test "$posix_memalign" = "yes" ; then
- echo "CONFIG_POSIX_MEMALIGN=y" >> $config_host_mak
-fi
if test "$spice_protocol" = "yes" ; then
echo "CONFIG_SPICE_PROTOCOL=y" >> $config_host_mak
@@ -5628,18 +4699,6 @@ if test "$crypto_afalg" = "yes" ; then
echo "CONFIG_AF_ALG=y" >> $config_host_mak
fi
-if test "$open_by_handle_at" = "yes" ; then
- echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak
-fi
-
-if test "$linux_magic_h" = "yes" ; then
- echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak
-fi
-
-if test "$valgrind_h" = "yes" ; then
- echo "CONFIG_VALGRIND_H=y" >> $config_host_mak
-fi
-
if test "$have_asan_iface_fiber" = "yes" ; then
echo "CONFIG_ASAN_IFACE_FIBER=y" >> $config_host_mak
fi
@@ -5648,10 +4707,6 @@ if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then
echo "CONFIG_TSAN=y" >> $config_host_mak
fi
-if test "$has_environ" = "yes" ; then
- echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak
-fi
-
if test "$cpuid_h" = "yes" ; then
echo "CONFIG_CPUID_H=y" >> $config_host_mak
fi
@@ -5738,16 +4793,6 @@ if test "$pvrdma" = "yes" ; then
echo "CONFIG_PVRDMA=y" >> $config_host_mak
fi
-if test "$have_rtnetlink" = "yes" ; then
- echo "CONFIG_RTNETLINK=y" >> $config_host_mak
-fi
-
-if test "$libxml2" = "yes" ; then
- echo "CONFIG_LIBXML2=y" >> $config_host_mak
- echo "LIBXML2_CFLAGS=$libxml2_cflags" >> $config_host_mak
- echo "LIBXML2_LIBS=$libxml2_libs" >> $config_host_mak
-fi
-
if test "$replication" = "yes" ; then
echo "CONFIG_REPLICATION=y" >> $config_host_mak
fi
@@ -5756,19 +4801,6 @@ if test "$have_af_vsock" = "yes" ; then
echo "CONFIG_AF_VSOCK=y" >> $config_host_mak
fi
-if test "$have_sysmacros" = "yes" ; then
- echo "CONFIG_SYSMACROS=y" >> $config_host_mak
-fi
-
-if test "$have_utmpx" = "yes" ; then
- echo "HAVE_UTMPX=y" >> $config_host_mak
-fi
-if test "$have_getrandom" = "yes" ; then
- echo "CONFIG_GETRANDOM=y" >> $config_host_mak
-fi
-if test "$ivshmem" = "yes" ; then
- echo "CONFIG_IVSHMEM=y" >> $config_host_mak
-fi
if test "$debug_mutex" = "yes" ; then
echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
fi
@@ -5792,11 +4824,6 @@ if test "$libpmem" = "yes" ; then
echo "LIBPMEM_CFLAGS=$libpmem_cflags" >> $config_host_mak
fi
-if test "$libdaxctl" = "yes" ; then
- echo "CONFIG_LIBDAXCTL=y" >> $config_host_mak
- echo "LIBDAXCTL_LIBS=$libdaxctl_libs" >> $config_host_mak
-fi
-
if test "$bochs" = "yes" ; then
echo "CONFIG_BOCHS=y" >> $config_host_mak
fi
@@ -5887,19 +4914,12 @@ echo "HOST_CC=$host_cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then
echo "CONFIG_IASL=$iasl" >> $config_host_mak
fi
-echo "CXX=$cxx" >> $config_host_mak
-echo "OBJCC=$objcc" >> $config_host_mak
echo "AR=$ar" >> $config_host_mak
-echo "ARFLAGS=$ARFLAGS" >> $config_host_mak
echo "AS=$as" >> $config_host_mak
echo "CCAS=$ccas" >> $config_host_mak
echo "CPP=$cpp" >> $config_host_mak
echo "OBJCOPY=$objcopy" >> $config_host_mak
echo "LD=$ld" >> $config_host_mak
-echo "RANLIB=$ranlib" >> $config_host_mak
-echo "NM=$nm" >> $config_host_mak
-echo "PKG_CONFIG=$pkg_config_exe" >> $config_host_mak
-echo "WINDRES=$windres" >> $config_host_mak
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
@@ -6155,16 +5175,17 @@ if test "$skip_meson" = no; then
-Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf -Dnvmm=$nvmm \
-Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
-Dcocoa=$cocoa -Dgtk=$gtk -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
- -Dlibusb=$libusb -Dsmartcard=$smartcard -Dusb_redir=$usb_redir \
+ -Dlibusb=$libusb -Dsmartcard=$smartcard -Dusb_redir=$usb_redir -Dvte=$vte \
-Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
-Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Dvirtiofsd=$virtiofsd \
-Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt -Dbrlapi=$brlapi \
-Dcurl=$curl -Dglusterfs=$glusterfs -Dbzip2=$bzip2 -Dlibiscsi=$libiscsi \
-Dlibnfs=$libnfs -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
- -Drbd=$rbd -Dlzo=$lzo -Dsnappy=$snappy -Dlzfse=$lzfse \
+ -Drbd=$rbd -Dlzo=$lzo -Dsnappy=$snappy -Dlzfse=$lzfse -Dlibxml2=$libxml2 \
+ -Dlibdaxctl=$libdaxctl -Dlibpmem=$libpmem -Dlinux_io_uring=$linux_io_uring \
-Dgnutls=$gnutls -Dnettle=$nettle -Dgcrypt=$gcrypt -Dauth_pam=$auth_pam \
-Dzstd=$zstd -Dseccomp=$seccomp -Dvirtfs=$virtfs -Dcap_ng=$cap_ng \
- -Dattr=$attr -Ddefault_devices=$default_devices \
+ -Dattr=$attr -Ddefault_devices=$default_devices -Dvirglrenderer=$virglrenderer \
-Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \
-Dvhost_user_blk_server=$vhost_user_blk_server -Dmultiprocess=$multiprocess \
-Dfuse=$fuse -Dfuse_lseek=$fuse_lseek -Dguest_agent_msi=$guest_agent_msi -Dbpf=$bpf\
diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst
index cb2d7ffac0..a1cdbec751 100644
--- a/docs/devel/kconfig.rst
+++ b/docs/devel/kconfig.rst
@@ -303,5 +303,5 @@ variable::
host_kconfig = \
('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
- ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
+ (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
...
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index e2e0090878..70e08baff6 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -126,6 +126,18 @@ other options have been processed. This will either have no effect (if
if they were not given. The property is therefore useless and should not be
specified.
+``-display sdl,window_close=...`` (since 6.1)
+'''''''''''''''''''''''''''''''''''''''''''''
+
+Use ``-display sdl,window-close=...`` instead (i.e. with a minus instead of
+an underscore between "window" and "close").
+
+``-no-quit`` (since 6.1)
+''''''''''''''''''''''''
+
+The ``-no-quit`` is a synonym for ``-display ...,window-close=off`` which
+should be used instead.
+
QEMU Machine Protocol (QMP) commands
------------------------------------
diff --git a/hw/core/machine.c b/hw/core/machine.c
index ca69f0343a..57c18f909a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -19,6 +19,7 @@
#include "hw/loader.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-visit-machine.h"
#include "qapi/visitor.h"
#include "hw/sysbus.h"
#include "sysemu/cpus.h"
@@ -799,6 +800,57 @@ static void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
ms->smp.sockets = sockets;
}
+static void machine_get_smp(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ SMPConfiguration *config = &(SMPConfiguration){
+ .has_cores = true, .cores = ms->smp.cores,
+ .has_sockets = true, .sockets = ms->smp.sockets,
+ .has_dies = true, .dies = ms->smp.dies,
+ .has_threads = true, .threads = ms->smp.threads,
+ .has_cpus = true, .cpus = ms->smp.cpus,
+ .has_maxcpus = true, .maxcpus = ms->smp.max_cpus,
+ };
+ if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) {
+ return;
+ }
+}
+
+static void machine_set_smp(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ MachineState *ms = MACHINE(obj);
+ SMPConfiguration *config;
+ ERRP_GUARD();
+
+ if (!visit_type_SMPConfiguration(v, name, &config, errp)) {
+ return;
+ }
+
+ mc->smp_parse(ms, config, errp);
+ if (errp) {
+ goto out_free;
+ }
+
+ /* sanity-check smp_cpus and max_cpus against mc */
+ if (ms->smp.cpus < mc->min_cpus) {
+ error_setg(errp, "Invalid SMP CPUs %d. The min CPUs "
+ "supported by machine '%s' is %d",
+ ms->smp.cpus,
+ mc->name, mc->min_cpus);
+ } else if (ms->smp.max_cpus > mc->max_cpus) {
+ error_setg(errp, "Invalid SMP CPUs %d. The max CPUs "
+ "supported by machine '%s' is %d",
+ current_machine->smp.max_cpus,
+ mc->name, mc->max_cpus);
+ }
+
+out_free:
+ qapi_free_SMPConfiguration(config);
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -838,6 +890,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "dumpdtb",
"Dump current dtb to a file and quit");
+ object_class_property_add(oc, "smp", "SMPConfiguration",
+ machine_get_smp, machine_set_smp,
+ NULL, NULL);
+ object_class_property_set_description(oc, "smp",
+ "CPU topology");
+
object_class_property_add(oc, "phandle-start", "int",
machine_get_phandle_start, machine_set_phandle_start,
NULL, NULL);
@@ -1126,56 +1184,6 @@ MemoryRegion *machine_consume_memdev(MachineState *machine,
return ret;
}
-bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp)
-{
- MachineClass *mc = MACHINE_GET_CLASS(ms);
- ERRP_GUARD();
-
- if (opts) {
- SMPConfiguration config = {
- .has_cpus = !!qemu_opt_get(opts, "cpus"),
- .cpus = qemu_opt_get_number(opts, "cpus", 0),
- .has_sockets = !!qemu_opt_get(opts, "sockets"),
- .sockets = qemu_opt_get_number(opts, "sockets", 0),
- .has_dies = !!qemu_opt_get(opts, "dies"),
- .dies = qemu_opt_get_number(opts, "dies", 0),
- .has_cores = !!qemu_opt_get(opts, "cores"),
- .cores = qemu_opt_get_number(opts, "cores", 0),
- .has_threads = !!qemu_opt_get(opts, "threads"),
- .threads = qemu_opt_get_number(opts, "threads", 0),
- .has_maxcpus = !!qemu_opt_get(opts, "maxcpus"),
- .maxcpus = qemu_opt_get_number(opts, "maxcpus", 0),
- };
-
- mc->smp_parse(ms, &config, errp);
- if (*errp) {
- return false;
- }
- }
-
- /* sanity-check smp_cpus and max_cpus against mc */
- if (ms->smp.cpus < mc->min_cpus) {
- error_setg(errp, "Invalid SMP CPUs %d. The min CPUs "
- "supported by machine '%s' is %d",
- ms->smp.cpus,
- mc->name, mc->min_cpus);
- return false;
- } else if (ms->smp.max_cpus > mc->max_cpus) {
- error_setg(errp, "Invalid SMP CPUs %d. The max CPUs "
- "supported by machine '%s' is %d",
- current_machine->smp.max_cpus,
- mc->name, mc->max_cpus);
- return false;
- }
-
- if (ms->smp.cpus > 1) {
- Error *blocker = NULL;
- error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
- replay_add_blocker(blocker);
- }
- return true;
-}
-
void machine_run_board_init(MachineState *machine)
{
MachineClass *machine_class = MACHINE_GET_CLASS(machine);
diff --git a/hw/display/meson.build b/hw/display/meson.build
index e1f473c1df..1e6b707d3c 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -61,7 +61,7 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
virtio_gpu_gl_ss = ss.source_set()
- virtio_gpu_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRGL', opengl],
+ virtio_gpu_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', virgl, opengl],
if_true: [files('virtio-gpu-gl.c', 'virtio-gpu-virgl.c'), pixman, virgl])
hw_display_modules += {'virtio-gpu-gl': virtio_gpu_gl_ss}
endif
@@ -75,7 +75,7 @@ if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
hw_display_modules += {'virtio-gpu-pci': virtio_gpu_pci_ss}
virtio_gpu_pci_gl_ss = ss.source_set()
- virtio_gpu_pci_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRTIO_PCI', 'CONFIG_VIRGL', opengl],
+ virtio_gpu_pci_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRTIO_PCI', virgl, opengl],
if_true: [files('virtio-gpu-pci-gl.c'), pixman])
hw_display_modules += {'virtio-gpu-pci-gl': virtio_gpu_pci_gl_ss}
endif
@@ -89,7 +89,7 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
hw_display_modules += {'virtio-vga': virtio_vga_ss}
virtio_vga_gl_ss = ss.source_set()
- virtio_vga_gl_ss.add(when: ['CONFIG_VIRTIO_VGA', 'CONFIG_VIRGL', opengl],
+ virtio_vga_gl_ss.add(when: ['CONFIG_VIRTIO_VGA', virgl, opengl],
if_true: [files('virtio-vga-gl.c'), pixman])
hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
endif
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 1eae4427e8..accd6eff35 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -26,7 +26,6 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
extern MachineState *current_machine;
void machine_run_board_init(MachineState *machine);
-bool machine_smp_parse(MachineState *ms, QemuOpts *opts, Error **errp);
bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
diff --git a/include/qemu/option.h b/include/qemu/option.h
index f73e0dc7d9..306bf07575 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -119,7 +119,6 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
void qemu_opts_reset(QemuOptsList *list);
void qemu_opts_loc_restore(QemuOpts *opts);
-bool qemu_opts_set(QemuOptsList *list, const char *name, const char *value, Error **errp);
const char *qemu_opts_id(QemuOpts *opts);
void qemu_opts_set_id(QemuOpts *opts, char *id);
void qemu_opts_del(QemuOpts *opts);
@@ -130,8 +129,6 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
bool permit_abbrev);
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
bool permit_abbrev, Error **errp);
-void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
- int permit_abbrev);
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
Error **errp);
QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
@@ -147,7 +144,10 @@ void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
void qemu_opts_free(QemuOptsList *list);
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
+QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
+ bool *p_help, Error **errp);
QDict *keyval_parse(const char *params, const char *implied_key,
bool *help, Error **errp);
+void keyval_merge(QDict *old, const QDict *new, Error **errp);
#endif
diff --git a/include/qom/object.h b/include/qom/object.h
index 6721cd312e..faae0d841f 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -862,6 +862,29 @@ static void do_qemu_init_ ## type_array(void) \
type_init(do_qemu_init_ ## type_array)
/**
+ * type_print_class_properties:
+ * @type: a QOM class name
+ *
+ * Print the object's class properties to stdout or the monitor.
+ * Return whether an object was found.
+ */
+bool type_print_class_properties(const char *type);
+
+/**
+ * object_set_properties_from_keyval:
+ * @obj: a QOM object
+ * @qdict: a dictionary with the properties to be set
+ * @from_json: true if leaf values of @qdict are typed, false if they
+ * are strings
+ * @errp: pointer to error object
+ *
+ * For each key in the dictionary, parse the value string if needed,
+ * then set the corresponding property in @obj.
+ */
+void object_set_properties_from_keyval(Object *obj, const QDict *qdict,
+ bool from_json, Error **errp);
+
+/**
* object_class_dynamic_cast_assert:
* @klass: The #ObjectClass to attempt to cast.
* @typename: The QOM typename of the class to cast to.
diff --git a/meson.build b/meson.build
index db6789af9c..7e12de01be 100644
--- a/meson.build
+++ b/meson.build
@@ -164,6 +164,7 @@ endif
multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
libm = cc.find_library('m', required: false)
+threads = dependency('threads')
util = cc.find_library('util', required: false)
winmm = []
socket = []
@@ -327,15 +328,16 @@ if have_system or have_tools
endif
libaio = cc.find_library('aio', required: false)
zlib = dependency('zlib', required: true, kwargs: static_kwargs)
+
linux_io_uring = not_found
-if 'CONFIG_LINUX_IO_URING' in config_host
- linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
- link_args: config_host['LINUX_IO_URING_LIBS'].split())
+if not get_option('linux_io_uring').auto() or have_block
+ linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
+ method: 'pkg-config', kwargs: static_kwargs)
endif
libxml2 = not_found
-if 'CONFIG_LIBXML2' in config_host
- libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
- link_args: config_host['LIBXML2_LIBS'].split())
+if not get_option('libxml2').auto() or have_block
+ libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
+ method: 'pkg-config', kwargs: static_kwargs)
endif
libnfs = not_found
if not get_option('libnfs').auto() or have_block
@@ -471,9 +473,11 @@ if 'CONFIG_GBM' in config_host
link_args: config_host['GBM_LIBS'].split())
endif
virgl = not_found
-if 'CONFIG_VIRGL' in config_host
- virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
- link_args: config_host['VIRGL_LIBS'].split())
+if not get_option('virglrenderer').auto() or have_system
+ virgl = dependency('virglrenderer',
+ method: 'pkg-config',
+ required: get_option('virglrenderer'),
+ kwargs: static_kwargs)
endif
curl = not_found
if not get_option('curl').auto() or have_block
@@ -860,6 +864,7 @@ endif
gtk = not_found
gtkx11 = not_found
+vte = not_found
if not get_option('gtk').auto() or (have_system and not cocoa.found())
gtk = dependency('gtk+-3.0', version: '>=3.22.0',
method: 'pkg-config',
@@ -871,14 +876,16 @@ if not get_option('gtk').auto() or (have_system and not cocoa.found())
required: false,
kwargs: static_kwargs)
gtk = declare_dependency(dependencies: [gtk, gtkx11])
+
+ if not get_option('vte').auto() or have_system
+ vte = dependency('vte-2.91',
+ method: 'pkg-config',
+ required: get_option('vte'),
+ kwargs: static_kwargs)
+ endif
endif
endif
-vte = not_found
-if 'CONFIG_VTE' in config_host
- vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
- link_args: config_host['VTE_LIBS'].split())
-endif
x11 = not_found
if gtkx11.found()
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
@@ -1001,13 +1008,15 @@ if not get_option('libusb').auto() or have_system
endif
libpmem = not_found
-if 'CONFIG_LIBPMEM' in config_host
- libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
- link_args: config_host['LIBPMEM_LIBS'].split())
+if not get_option('libpmem').auto() or have_system
+ libpmem = dependency('libpmem', required: get_option('libpmem'),
+ method: 'pkg-config', kwargs: static_kwargs)
endif
libdaxctl = not_found
-if 'CONFIG_LIBDAXCTL' in config_host
- libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
+if not get_option('libdaxctl').auto() or have_system
+ libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
+ version: '>=57', method: 'pkg-config',
+ kwargs: static_kwargs)
endif
tasn1 = not_found
if gnutls.found()
@@ -1042,10 +1051,12 @@ endif
# Check whether the glibc provides statx()
-statx_test = '''
+gnu_source_prefix = '''
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+'''
+statx_test = gnu_source_prefix + '''
#include <sys/stat.h>
int main(void) {
struct statx statxbuf;
@@ -1208,6 +1219,7 @@ if glusterfs.found()
config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
endif
config_host_data.set('CONFIG_GTK', gtk.found())
+config_host_data.set('CONFIG_VTE', vte.found())
config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
config_host_data.set('CONFIG_EBPF', libbpf.found())
@@ -1244,16 +1256,150 @@ config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
+config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
+
+# has_header
+config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
+config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
+config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
+config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
-config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
-config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
-config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
+# has_function
+config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
+config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
+config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
+config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
+config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
+config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
+config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
+config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
+config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
+config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
+config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
+config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
+config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
+config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
+config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
+config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
+config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
+
+# has_header_symbol
+config_host_data.set('CONFIG_BYTESWAP_H',
+ cc.has_header_symbol('byteswap.h', 'bswap_32'))
+config_host_data.set('CONFIG_EPOLL_CREATE1',
+ cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
+config_host_data.set('CONFIG_HAS_ENVIRON',
+ cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
+config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
+ cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
+ cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
+config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
+ cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
+config_host_data.set('CONFIG_FIEMAP',
+ cc.has_header('linux/fiemap.h') and
+ cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
+config_host_data.set('CONFIG_GETRANDOM',
+ cc.has_function('getrandom') and
+ cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
+config_host_data.set('CONFIG_INOTIFY',
+ cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
+config_host_data.set('CONFIG_INOTIFY1',
+ cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
+config_host_data.set('CONFIG_MACHINE_BSWAP_H',
+ cc.has_header_symbol('machine/bswap.h', 'bswap32',
+ prefix: '''#include <sys/endian.h>
+ #include <sys/types.h>'''))
+config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
+ cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
+config_host_data.set('CONFIG_RTNETLINK',
+ cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
+config_host_data.set('CONFIG_SYSMACROS',
+ cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
+config_host_data.set('HAVE_OPTRESET',
+ cc.has_header_symbol('getopt.h', 'optreset'))
+config_host_data.set('HAVE_UTMPX',
+ cc.has_header_symbol('utmpx.h', 'struct utmpx'))
+
+# has_member
+config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
+ cc.has_member('struct sigevent', 'sigev_notify_thread_id',
+ prefix: '#include <signal.h>'))
+config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
+ cc.has_member('struct stat', 'st_atim',
+ prefix: '#include <sys/stat.h>'))
+
+config_host_data.set('CONFIG_EVENTFD', cc.compiles('''
+ #include <sys/eventfd.h>
+ int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
+config_host_data.set('CONFIG_FDATASYNC', cc.compiles(gnu_source_prefix + '''
+ #include <unistd.h>
+ int main(void) {
+ #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
+ return fdatasync(0);
+ #else
+ #error Not supported
+ #endif
+ }'''))
+config_host_data.set('CONFIG_MADVISE', cc.compiles(gnu_source_prefix + '''
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <stddef.h>
+ int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
+config_host_data.set('CONFIG_MEMFD', cc.compiles(gnu_source_prefix + '''
+ #include <sys/mman.h>
+ int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
+config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.compiles(gnu_source_prefix + '''
+ #include <fcntl.h>
+ #if !defined(AT_EMPTY_PATH)
+ # error missing definition
+ #else
+ int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
+ #endif'''))
+config_host_data.set('CONFIG_PIPE2', cc.compiles(gnu_source_prefix + '''
+ #include <unistd.h>
+ #include <fcntl.h>
+
+ int main(void)
+ {
+ int pipefd[2];
+ return pipe2(pipefd, O_CLOEXEC);
+ }'''))
+config_host_data.set('CONFIG_POSIX_MADVISE', cc.compiles(gnu_source_prefix + '''
+ #include <sys/mman.h>
+ #include <stddef.h>
+ int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
+config_host_data.set('CONFIG_SIGNALFD', cc.compiles(gnu_source_prefix + '''
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <signal.h>
+ int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }'''))
+config_host_data.set('CONFIG_SPLICE', cc.compiles(gnu_source_prefix + '''
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <limits.h>
+
+ int main(void)
+ {
+ int len, fd = 0;
+ len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
+ splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
+ return 0;
+ }'''))
+
+# Some versions of Mac OS X incorrectly define SIZE_MAX
+config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
+ #include <stdint.h>
+ #include <stdio.h>
+ int main(int argc, char *argv[]) {
+ return printf("%zu", SIZE_MAX);
+ }''', args: ['-Werror']))
+
ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
@@ -1322,10 +1468,11 @@ if link_language == 'cpp'
}
endif
+have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
host_kconfig = \
('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
- ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
+ (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
(x11.found() ? ['CONFIG_X11=y'] : []) + \
('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
@@ -1987,7 +2134,7 @@ util_ss.add_all(trace_ss)
util_ss = util_ss.apply(config_all, strict: false)
libqemuutil = static_library('qemuutil',
sources: util_ss.sources() + stub_ss.sources() + genh,
- dependencies: [util_ss.dependencies(), libm, glib, socket, malloc, pixman])
+ dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
qemuutil = declare_dependency(link_with: libqemuutil,
sources: genh + version_res)
@@ -2360,8 +2507,7 @@ foreach target : target_dirs
endif
foreach exe: execs
exe_name = exe['name']
- exe_sign = 'CONFIG_HVF' in config_target
- if exe_sign
+ if targetos == 'darwin'
exe_name += '-unsigned'
endif
@@ -2375,7 +2521,13 @@ foreach target : target_dirs
link_args: link_args,
gui_app: exe['gui'])
- if exe_sign
+ if 'CONFIG_HVF' in config_target
+ entitlements = meson.current_source_dir() / 'accel/hvf/entitlements.plist'
+ else
+ entitlements = '/dev/null'
+ endif
+ if targetos == 'darwin'
+ icon = meson.current_source_dir() / 'pc-bios/qemu.rsrc'
emulators += {exe['name'] : custom_target(exe['name'],
depends: emulator,
output: exe['name'],
@@ -2383,14 +2535,14 @@ foreach target : target_dirs
meson.current_source_dir() / 'scripts/entitlement.sh',
meson.current_build_dir() / exe_name,
meson.current_build_dir() / exe['name'],
- meson.current_source_dir() / 'accel/hvf/entitlements.plist'
+ entitlements, icon
])
}
meson.add_install_script('scripts/entitlement.sh', '--install',
get_option('bindir') / exe_name,
get_option('bindir') / exe['name'],
- meson.current_source_dir() / 'accel/hvf/entitlements.plist')
+ entitlements, icon)
else
emulators += {exe['name']: emulator}
endif
@@ -2476,7 +2628,7 @@ if have_tools
install: true)
endif
- if 'CONFIG_IVSHMEM' in config_host
+ if have_ivshmem
subdir('contrib/ivshmem-client')
subdir('contrib/ivshmem-server')
endif
@@ -2613,7 +2765,6 @@ if targetos == 'windows'
summary_info += {'Windows SDK': config_host['WIN_SDK']}
endif
endif
-summary_info += {'ARFLAGS': config_host['ARFLAGS']}
summary_info += {'CFLAGS': ' '.join(get_option('c_args')
+ ['-O' + get_option('optimization')]
+ (get_option('debug') ? ['-g'] : []))}
@@ -2634,10 +2785,6 @@ summary_info += {'PIE': get_option('b_pie')}
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
summary_info += {'malloc trim support': has_malloc_trim}
summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
-summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
-summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
-summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
-summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
summary_info += {'memory allocator': get_option('malloc')}
@@ -2756,7 +2903,7 @@ summary_info += {'SDL image support': sdl_image.found()}
summary_info += {'GTK support': gtk.found()}
summary_info += {'pixman': pixman.found()}
# TODO: add back version
-summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
+summary_info += {'VTE support': vte.found()}
# TODO: add back version
summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
summary_info += {'libtasn1': tasn1.found()}
@@ -2764,7 +2911,7 @@ summary_info += {'PAM': pam.found()}
summary_info += {'iconv support': iconv.found()}
summary_info += {'curses support': curses.found()}
# TODO: add back version
-summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
+summary_info += {'virgl support': virgl.found()}
summary_info += {'curl support': curl.found()}
summary_info += {'Multipath support': mpathpersist.found()}
summary_info += {'VNC support': vnc.found()}
@@ -2777,7 +2924,7 @@ summary_info += {'brlapi support': brlapi.found()}
summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
-summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
+summary_info += {'Linux io_uring support': linux_io_uring.found()}
summary_info += {'ATTR/XATTR support': libattr.found()}
summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
@@ -2812,10 +2959,10 @@ summary_info += {'bzip2 support': libbzip2.found()}
summary_info += {'lzfse support': liblzfse.found()}
summary_info += {'zstd support': zstd.found()}
summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
-summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
+summary_info += {'libxml2': libxml2.found()}
summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
-summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
-summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
+summary_info += {'libpmem support': libpmem.found()}
+summary_info += {'libdaxctl support': libdaxctl.found()}
summary_info += {'libudev': libudev.found()}
summary_info += {'FUSE lseek': fuse_lseek.found()}
summary(summary_info, bool_yn: true, section: 'Dependencies')
diff --git a/meson_options.txt b/meson_options.txt
index f7ec9bee27..a9a9b8f4c6 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -84,10 +84,18 @@ option('nettle', type : 'feature', value : 'auto',
description: 'nettle cryptography support')
option('gcrypt', type : 'feature', value : 'auto',
description: 'libgcrypt cryptography support')
+option('libdaxctl', type : 'feature', value : 'auto',
+ description: 'libdaxctl support')
+option('libpmem', type : 'feature', value : 'auto',
+ description: 'libpmem support')
option('libudev', type : 'feature', value : 'auto',
description: 'Use libudev to enumerate host devices')
option('libusb', type : 'feature', value : 'auto',
description: 'libusb support for USB passthrough')
+option('libxml2', type : 'feature', value : 'auto',
+ description: 'libxml2 support for Parallels image format')
+option('linux_io_uring', type : 'feature', value : 'auto',
+ description: 'Linux io_uring support')
option('lzfse', type : 'feature', value : 'auto',
description: 'lzfse support for DMG images')
option('lzo', type : 'feature', value : 'auto',
@@ -110,6 +118,8 @@ option('u2f', type : 'feature', value : 'auto',
description: 'U2F emulation support')
option('usb_redir', type : 'feature', value : 'auto',
description: 'libusbredir support')
+option('virglrenderer', type : 'feature', value : 'auto',
+ description: 'virgl rendering support')
option('vnc', type : 'feature', value : 'enabled',
description: 'VNC server')
option('vnc_jpeg', type : 'feature', value : 'auto',
@@ -118,6 +128,8 @@ option('vnc_png', type : 'feature', value : 'auto',
description: 'PNG compression for VNC server')
option('vnc_sasl', type : 'feature', value : 'auto',
description: 'SASL authentication for VNC server')
+option('vte', type : 'feature', value : 'auto',
+ description: 'vte support for the gtk UI')
option('xkbcommon', type : 'feature', value : 'auto',
description: 'xkbcommon support')
option('zstd', type : 'feature', value : 'auto',
diff --git a/qemu-options.hx b/qemu-options.hx
index ba3ca9da1d..8965dabc83 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1783,11 +1783,12 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
"-display spice-app[,gl=on|off]\n"
#endif
#if defined(CONFIG_SDL)
- "-display sdl[,alt_grab=on|off][,ctrl_grab=on|off]\n"
- " [,window_close=on|off][,gl=on|core|es|off]\n"
+ "-display sdl[,alt_grab=on|off][,ctrl_grab=on|off][,gl=on|core|es|off]\n"
+ " [,show-cursor=on|off][,window-close=on|off]\n"
#endif
#if defined(CONFIG_GTK)
- "-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
+ "-display gtk[,full-screen=on|off][,gl=on|off][,grab-on-hover=on|off]\n"
+ " [,show-cursor=on|off][,window-close=on|off]\n"
#endif
#if defined(CONFIG_VNC)
"-display vnc=<display>[,<optargs>]\n"
@@ -1824,17 +1825,37 @@ SRST
application. The Spice server will redirect the serial consoles
and QEMU monitors. (Since 4.0)
- ``sdl[,window-close=on|off][,gl=on|core|es|off]``
-
+ ``sdl``
Display video output via SDL (usually in a separate graphics
window; see the SDL documentation for other possibilities).
+ Valid parameters are:
+
+ ``alt_grab=on|off`` : Use Control+Alt+Shift-g to toggle mouse grabbing
+
+ ``ctrl_grab=on|off`` : Use Right-Control-g to toggle mouse grabbing
+
+ ``gl=on|off|core|es`` : Use OpenGL for displaying
- ``gtk[,grab-on-hover=on|off][,gl=on|off]``
+ ``show-cursor=on|off`` : Force showing the mouse cursor
+
+ ``window-close=on|off`` : Allow to quit qemu with window close button
+
+ ``gtk``
Display video output in a GTK window. This interface provides
drop-down menus and other UI elements to configure and control
- the VM during runtime.
+ the VM during runtime. Valid parameters are:
+
+ ``full-screen=on|off`` : Start in fullscreen mode
+
+ ``gl=on|off`` : Use OpenGL for displaying
- ``curses [,charset=<encoding>]``
+ ``grab-on-hover=on|off`` : Grab keyboard input on mouse hover
+
+ ``show-cursor=on|off`` : Force showing the mouse cursor
+
+ ``window-close=on|off`` : Allow to quit qemu with window close button
+
+ ``curses[,charset=<encoding>]``
Display video output via curses. For graphics device models
which support a text mode, QEMU can display this output using a
curses/ncurses interface. Nothing is displayed when the graphics
@@ -1845,11 +1866,14 @@ SRST
``charset=CP850`` for IBM CP850 encoding. The default is
``CP437``.
- ``egl-headless[,rendernode<file>]``
+ ``egl-headless[,rendernode=<file>]``
Offload all OpenGL operations to a local DRI device. For any
graphical display, this display needs to be paired with either
VNC or SPICE displays.
+ ``vnc=<display>``
+ Start a VNC server on display <display>
+
``none``
Do not display video output. The guest will still see an
emulated graphics card, but its output will not be displayed to
@@ -1857,9 +1881,6 @@ SRST
that it only affects what is done with video output; -nographic
also changes the destination of the serial and parallel port
data.
-
-
-
ERST
DEF("nographic", 0, QEMU_OPTION_nographic,
@@ -1910,10 +1931,11 @@ SRST
ERST
DEF("no-quit", 0, QEMU_OPTION_no_quit,
- "-no-quit disable SDL window close capability\n", QEMU_ARCH_ALL)
+ "-no-quit disable SDL/GTK window close capability (deprecated)\n", QEMU_ARCH_ALL)
SRST
``-no-quit``
- Disable SDL window close capability.
+ Disable window close capability (SDL and GTK only). This option is
+ deprecated, please use ``-display ...,window-close=off`` instead.
ERST
DEF("sdl", 0, QEMU_OPTION_sdl,
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 4479ee693a..ad9b56b59a 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -42,6 +42,44 @@ bool user_creatable_can_be_deleted(UserCreatable *uc)
}
}
+static void object_set_properties_from_qdict(Object *obj, const QDict *qdict,
+ Visitor *v, Error **errp)
+{
+ const QDictEntry *e;
+ Error *local_err = NULL;
+
+ if (!visit_start_struct(v, NULL, NULL, 0, &local_err)) {
+ goto out;
+ }
+ for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+ if (!object_property_set(obj, e->key, v, &local_err)) {
+ break;
+ }
+ }
+ if (!local_err) {
+ visit_check_struct(v, &local_err);
+ }
+ visit_end_struct(v, NULL);
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+}
+
+void object_set_properties_from_keyval(Object *obj, const QDict *qdict,
+ bool from_json, Error **errp)
+{
+ Visitor *v;
+ if (from_json) {
+ v = qobject_input_visitor_new(QOBJECT(qdict));
+ } else {
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+ }
+ object_set_properties_from_qdict(obj, qdict, v, errp);
+ visit_free(v);
+}
+
Object *user_creatable_add_type(const char *type, const char *id,
const QDict *qdict,
Visitor *v, Error **errp)
@@ -49,7 +87,6 @@ Object *user_creatable_add_type(const char *type, const char *id,
ERRP_GUARD();
Object *obj;
ObjectClass *klass;
- const QDictEntry *e;
Error *local_err = NULL;
if (id != NULL && !id_wellformed(id)) {
@@ -78,18 +115,7 @@ Object *user_creatable_add_type(const char *type, const char *id,
assert(qdict);
obj = object_new(type);
- if (!visit_start_struct(v, NULL, NULL, 0, &local_err)) {
- goto out;
- }
- for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
- if (!object_property_set(obj, e->key, v, &local_err)) {
- break;
- }
- }
- if (!local_err) {
- visit_check_struct(v, &local_err);
- }
- visit_end_struct(v, NULL);
+ object_set_properties_from_qdict(obj, qdict, v, &local_err);
if (local_err) {
goto out;
}
@@ -178,7 +204,7 @@ static void user_creatable_print_types(void)
g_slist_free(list);
}
-static bool user_creatable_print_type_properites(const char *type)
+bool type_print_class_properties(const char *type)
{
ObjectClass *klass;
ObjectPropertyIterator iter;
@@ -224,7 +250,7 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts)
}
if (qemu_opt_has_help_opt(opts)) {
- return user_creatable_print_type_properites(type);
+ return type_print_class_properties(type);
}
return false;
@@ -234,7 +260,7 @@ static void user_creatable_print_help_from_qdict(QDict *args)
{
const char *type = qdict_get_try_str(args, "qom-type");
- if (!type || !user_creatable_print_type_properites(type)) {
+ if (!type || !type_print_class_properties(type)) {
user_creatable_print_types();
}
}
diff --git a/scripts/coverity-scan/COMPONENTS.md b/scripts/coverity-scan/COMPONENTS.md
index 02a3447dab..183f26a32c 100644
--- a/scripts/coverity-scan/COMPONENTS.md
+++ b/scripts/coverity-scan/COMPONENTS.md
@@ -21,9 +21,6 @@ hppa
i386
~ (/qemu)?((/include)?/hw/i386/.*|/target/i386/.*|/hw/intc/[^/]*apic[^/]*\.c)
-lm32
- ~ (/qemu)?((/include)?/hw/lm32/.*|/target/lm32/.*|/hw/.*/(milkymist|lm32).*)
-
m68k
~ (/qemu)?((/include)?/hw/m68k/.*|/target/m68k/.*|(/include)?/hw(/.*)?/mcf.*)
@@ -60,9 +57,6 @@ tilegx
tricore
~ (/qemu)?((/include)?/hw/tricore/.*|/target/tricore/.*)
-unicore32
- ~ (/qemu)?((/include)?/hw/unicore32/.*|/target/unicore32/.*)
-
9pfs
~ (/qemu)?(/hw/9pfs/.*|/fsdev/.*)
diff --git a/scripts/coverity-scan/run-coverity-scan b/scripts/coverity-scan/run-coverity-scan
index 6eefb4b558..7395bbfad4 100755
--- a/scripts/coverity-scan/run-coverity-scan
+++ b/scripts/coverity-scan/run-coverity-scan
@@ -380,15 +380,17 @@ export PATH="$TOOLBIN:$PATH"
cd "$SRCDIR"
-echo "Doing make distclean..."
-make distclean
+echo "Nuking build directory..."
+rm -rf +build
+mkdir +build
+cd +build
echo "Configuring..."
# We configure with a fixed set of enables here to ensure that we don't
# accidentally reduce the scope of the analysis by doing the build on
# the system that's missing a dependency that we need to build part of
# the codebase.
-./configure --disable-modules --enable-sdl --enable-gtk \
+../configure --disable-modules --enable-sdl --enable-gtk \
--enable-opengl --enable-vte --enable-gnutls \
--enable-nettle --enable-curses --enable-curl \
--audio-drv-list=oss,alsa,sdl,pa --enable-virtfs \
diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
index f7aaaf2766..d2a7079ce3 100755
--- a/scripts/entitlement.sh
+++ b/scripts/entitlement.sh
@@ -11,6 +11,7 @@ fi
SRC="$1"
DST="$2"
ENTITLEMENT="$3"
+ICON="$4"
if $in_place; then
trap 'rm "$DST.tmp"' exit
@@ -20,6 +21,13 @@ else
cd "$MESON_INSTALL_DESTDIR_PREFIX"
fi
-codesign --entitlements "$ENTITLEMENT" --force -s - "$SRC"
+if test "$ENTITLEMENT" != '/dev/null'; then
+ codesign --entitlements "$ENTITLEMENT" --force -s - "$SRC"
+fi
+
+# Add the QEMU icon to the binary on Mac OS
+Rez -append "$ICON" -o "$SRC"
+SetFile -a C "$SRC"
+
mv -f "$SRC" "$DST"
trap '' exit
diff --git a/softmmu/vl.c b/softmmu/vl.c
index d99e2cbdbf..a50c8575a1 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -145,6 +145,8 @@ static const char *cpu_option;
static const char *mem_path;
static const char *incoming;
static const char *loadvm;
+static const char *accelerators;
+static QDict *machine_opts_dict;
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
static ram_addr_t maxram_size;
static uint64_t ram_slots;
@@ -235,21 +237,6 @@ static QemuOptsList qemu_option_rom_opts = {
},
};
-static QemuOptsList qemu_machine_opts = {
- .name = "machine",
- .implied_opt_name = "type",
- .merge_lists = true,
- .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
- .desc = {
- /*
- * no elements => accept any
- * sanity checking will happen later
- * when setting machine properties
- */
- { }
- },
-};
-
static QemuOptsList qemu_accel_opts = {
.name = "accel",
.implied_opt_name = "accel",
@@ -498,16 +485,6 @@ static QemuOptsList qemu_action_opts = {
},
};
-/**
- * Get machine options
- *
- * Returns: machine options (never null).
- */
-static QemuOpts *qemu_get_machine_opts(void)
-{
- return qemu_find_opts_singleton("machine");
-}
-
const char *qemu_get_vm_name(void)
{
return qemu_name;
@@ -815,33 +792,6 @@ static MachineClass *find_default_machine(GSList *machines)
return default_machineclass;
}
-static int machine_help_func(QemuOpts *opts, MachineState *machine)
-{
- ObjectProperty *prop;
- ObjectPropertyIterator iter;
-
- if (!qemu_opt_has_help_opt(opts)) {
- return 0;
- }
-
- object_property_iter_init(&iter, OBJECT(machine));
- while ((prop = object_property_iter_next(&iter))) {
- if (!prop->set) {
- continue;
- }
-
- printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name,
- prop->name, prop->type);
- if (prop->description) {
- printf(" (%s)\n", prop->description);
- } else {
- printf("\n");
- }
- }
-
- return 1;
-}
-
static void version(void)
{
printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
@@ -1062,8 +1012,6 @@ static void parse_display(const char *p)
* sdl DisplayType needs hand-crafted parser instead of
* parse_display_qapi() due to some options not in
* DisplayOptions, specifically:
- * - frame
- * Already deprecated.
* - ctrl_grab + alt_grab
* Not clear yet what happens to them long-term. Should
* replaced by something better or deprecated and dropped.
@@ -1091,7 +1039,12 @@ static void parse_display(const char *p)
} else {
goto invalid_sdl_args;
}
- } else if (strstart(opts, ",window_close=", &nextopt)) {
+ } else if (strstart(opts, ",window_close=", &nextopt) ||
+ strstart(opts, ",window-close=", &nextopt)) {
+ if (strstart(opts, ",window_close=", NULL)) {
+ warn_report("window_close with an underscore is deprecated,"
+ " please use window-close instead.");
+ }
opts = nextopt;
dpy.has_window_close = true;
if (strstart(opts, "on", &nextopt)) {
@@ -1551,33 +1504,50 @@ static gint machine_class_cmp(gconstpointer a, gconstpointer b)
object_class_get_name(OBJECT_CLASS(mc1)));
}
-static MachineClass *machine_parse(const char *name, GSList *machines)
+static void machine_help_func(const QDict *qdict)
{
- MachineClass *mc;
- GSList *el;
+ GSList *machines, *el;
+ const char *type = qdict_get_try_str(qdict, "type");
- if (is_help_option(name)) {
- printf("Supported machines are:\n");
- machines = g_slist_sort(machines, machine_class_cmp);
- for (el = machines; el; el = el->next) {
- MachineClass *mc = el->data;
- if (mc->alias) {
- printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
- }
- printf("%-20s %s%s%s\n", mc->name, mc->desc,
- mc->is_default ? " (default)" : "",
- mc->deprecation_reason ? " (deprecated)" : "");
+ machines = object_class_get_list(TYPE_MACHINE, false);
+ if (type) {
+ ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines));
+ if (machine_class) {
+ type_print_class_properties(object_class_get_name(machine_class));
+ return;
}
- exit(0);
}
- mc = find_machine(name, machines);
- if (!mc) {
- error_report("unsupported machine type");
- error_printf("Use -machine help to list supported machines\n");
- exit(1);
+ printf("Supported machines are:\n");
+ machines = g_slist_sort(machines, machine_class_cmp);
+ for (el = machines; el; el = el->next) {
+ MachineClass *mc = el->data;
+ if (mc->alias) {
+ printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
+ }
+ printf("%-20s %s%s%s\n", mc->name, mc->desc,
+ mc->is_default ? " (default)" : "",
+ mc->deprecation_reason ? " (deprecated)" : "");
}
- return mc;
+}
+
+static void
+machine_parse_property_opt(QemuOptsList *opts_list, const char *propname,
+ const char *arg, Error **errp)
+{
+ QDict *opts, *prop;
+ bool help = false;
+ ERRP_GUARD();
+
+ prop = keyval_parse(arg, opts_list->implied_opt_name, &help, errp);
+ if (help) {
+ qemu_opts_print_help(opts_list, true);
+ return;
+ }
+ opts = qdict_new();
+ qdict_put(opts, propname, prop);
+ keyval_merge(machine_opts_dict, opts, errp);
+ qobject_unref(opts);
}
static const char *pid_file;
@@ -1630,32 +1600,31 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
return popt;
}
-static MachineClass *select_machine(void)
+static MachineClass *select_machine(QDict *qdict, Error **errp)
{
+ const char *optarg = qdict_get_try_str(qdict, "type");
GSList *machines = object_class_get_list(TYPE_MACHINE, false);
- MachineClass *machine_class = find_default_machine(machines);
- const char *optarg;
- QemuOpts *opts;
- Location loc;
-
- loc_push_none(&loc);
-
- opts = qemu_get_machine_opts();
- qemu_opts_loc_restore(opts);
+ MachineClass *machine_class;
+ Error *local_err = NULL;
- optarg = qemu_opt_get(opts, "type");
if (optarg) {
- machine_class = machine_parse(optarg, machines);
- }
-
- if (!machine_class) {
- error_report("No machine specified, and there is no default");
- error_printf("Use -machine help to list supported machines\n");
- exit(1);
+ machine_class = find_machine(optarg, machines);
+ qdict_del(qdict, "type");
+ if (!machine_class) {
+ error_setg(&local_err, "unsupported machine type");
+ }
+ } else {
+ machine_class = find_default_machine(machines);
+ if (!machine_class) {
+ error_setg(&local_err, "No machine specified, and there is no default");
+ }
}
- loc_pop(&loc);
g_slist_free(machines);
+ if (local_err) {
+ error_append_hint(&local_err, "Use -machine help to list supported machines\n");
+ error_propagate(errp, local_err);
+ }
return machine_class;
}
@@ -1674,42 +1643,70 @@ static int object_parse_property_opt(Object *obj,
return 0;
}
-static int machine_set_property(void *opaque,
- const char *name, const char *value,
- Error **errp)
+/* *Non*recursively replace underscores with dashes in QDict keys. */
+static void keyval_dashify(QDict *qdict, Error **errp)
{
- g_autofree char *qom_name = g_strdup(name);
+ const QDictEntry *ent, *next;
char *p;
- for (p = qom_name; *p; p++) {
- if (*p == '_') {
- *p = '-';
+ for (ent = qdict_first(qdict); ent; ent = next) {
+ g_autofree char *new_key = NULL;
+
+ next = qdict_next(qdict, ent);
+ if (!strchr(ent->key, '_')) {
+ continue;
+ }
+ new_key = g_strdup(ent->key);
+ for (p = new_key; *p; p++) {
+ if (*p == '_') {
+ *p = '-';
+ }
+ }
+ if (qdict_haskey(qdict, new_key)) {
+ error_setg(errp, "Conflict between '%s' and '%s'", ent->key, new_key);
+ return;
}
+ qobject_ref(ent->value);
+ qdict_put_obj(qdict, new_key, ent->value);
+ qdict_del(qdict, ent->key);
}
+}
+
+static void qemu_apply_legacy_machine_options(QDict *qdict)
+{
+ const char *value;
+
+ keyval_dashify(qdict, &error_fatal);
/* Legacy options do not correspond to MachineState properties. */
- if (g_str_equal(qom_name, "accel")) {
- return 0;
+ value = qdict_get_try_str(qdict, "accel");
+ if (value) {
+ accelerators = g_strdup(value);
+ qdict_del(qdict, "accel");
}
- if (g_str_equal(qom_name, "igd-passthru")) {
- object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value,
+
+ value = qdict_get_try_str(qdict, "igd-passthru");
+ if (value) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), "igd-passthru", value,
false);
- return 0;
+ qdict_del(qdict, "igd-passthru");
}
- if (g_str_equal(qom_name, "kvm-shadow-mem")) {
- object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value,
+
+ value = qdict_get_try_str(qdict, "kvm-shadow-mem");
+ if (value) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kvm-shadow-mem", value,
false);
- return 0;
+ qdict_del(qdict, "kvm-shadow-mem");
}
- if (g_str_equal(qom_name, "kernel-irqchip")) {
- object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value,
+
+ value = qdict_get_try_str(qdict, "kernel-irqchip");
+ if (value) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kernel-irqchip", value,
false);
- object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), qom_name, value,
+ object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), "kernel-irqchip", value,
false);
- return 0;
+ qdict_del(qdict, "kernel-irqchip");
}
-
- return object_parse_property_opt(opaque, name, value, "type", errp);
}
static void object_option_foreach_add(bool (*type_opt_predicate)(const char *))
@@ -1824,16 +1821,14 @@ static bool object_create_early(const char *type)
return true;
}
-static void qemu_apply_machine_options(void)
+static void qemu_apply_machine_options(QDict *qdict)
{
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
- QemuOpts *machine_opts = qemu_get_machine_opts();
const char *boot_order = NULL;
const char *boot_once = NULL;
QemuOpts *opts;
- qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
- &error_fatal);
+ object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal);
current_machine->ram_size = ram_size;
current_machine->maxram_size = maxram_size;
current_machine->ram_slots = ram_slots;
@@ -1862,10 +1857,14 @@ static void qemu_apply_machine_options(void)
current_machine->boot_once = boot_once;
if (semihosting_enabled() && !semihosting_get_argc()) {
- const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
- const char *kernel_cmdline = qemu_opt_get(machine_opts, "append") ?: "";
/* fall back to the -kernel/-append */
- semihosting_arg_fallback(kernel_filename, kernel_cmdline);
+ semihosting_arg_fallback(current_machine->kernel_filename, current_machine->kernel_cmdline);
+ }
+
+ if (current_machine->smp.cpus > 1) {
+ Error *blocker = NULL;
+ error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp");
+ replay_add_blocker(blocker);
}
}
@@ -1921,8 +1920,7 @@ static void qemu_create_early_backends(void)
/*
* Note: we need to create audio and block backends before
- * machine_set_property(), so machine properties can refer to
- * them.
+ * setting machine properties, so they can be referred to.
*/
configure_blockdev(&bdo_queue, machine_class, snapshot);
audio_init_audiodevs();
@@ -2088,16 +2086,14 @@ static void set_memory_options(MachineClass *mc)
loc_pop(&loc);
}
-static void qemu_create_machine(MachineClass *machine_class)
+static void qemu_create_machine(QDict *qdict)
{
+ MachineClass *machine_class = select_machine(qdict, &error_fatal);
object_set_machine_compat_props(machine_class->compat_props);
set_memory_options(machine_class);
current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
- if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
- exit(0);
- }
object_property_add_child(object_get_root(), "machine",
OBJECT(current_machine));
object_property_add_child(container_get(OBJECT(current_machine),
@@ -2120,16 +2116,17 @@ static void qemu_create_machine(MachineClass *machine_class)
qemu_set_hw_version(machine_class->hw_version);
}
- machine_smp_parse(current_machine,
- qemu_opts_find(qemu_find_opts("smp-opts"), NULL), &error_fatal);
-
/*
* Get the default machine options from the machine if it is not already
* specified either by the configuration file or by the command line.
*/
if (machine_class->default_machine_opts) {
- qemu_opts_set_defaults(qemu_find_opts("machine"),
- machine_class->default_machine_opts, 0);
+ QDict *default_opts =
+ keyval_parse(machine_class->default_machine_opts, NULL, NULL,
+ &error_abort);
+ object_set_properties_from_keyval(OBJECT(current_machine), default_opts,
+ false, &error_abort);
+ qobject_unref(default_opts);
}
}
@@ -2151,7 +2148,8 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
*/
static bool is_qemuopts_group(const char *group)
{
- if (g_str_equal(group, "object")) {
+ if (g_str_equal(group, "object") ||
+ g_str_equal(group, "machine")) {
return false;
}
return true;
@@ -2164,6 +2162,13 @@ static void qemu_record_config_group(const char *group, QDict *dict,
Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
object_option_add_visitor(v);
visit_free(v);
+ } else if (g_str_equal(group, "machine")) {
+ /*
+ * Cannot merge string-valued and type-safe dictionaries, so JSON
+ * is not accepted yet for -M.
+ */
+ assert(!from_json);
+ keyval_merge(machine_opts_dict, dict, errp);
} else {
abort();
}
@@ -2294,13 +2299,11 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
static void configure_accelerators(const char *progname)
{
- const char *accelerators;
bool init_failed = false;
qemu_opts_foreach(qemu_find_opts("icount"),
do_configure_icount, NULL, &error_fatal);
- accelerators = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (QTAILQ_EMPTY(&qemu_accel_opts.head)) {
char **accel_list, **tmp;
@@ -2388,12 +2391,11 @@ static void create_default_memdev(MachineState *ms, const char *path)
&error_fatal);
}
-static void qemu_validate_options(void)
+static void qemu_validate_options(const QDict *machine_opts)
{
- QemuOpts *machine_opts = qemu_get_machine_opts();
- const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
- const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
- const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
+ const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
+ const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd");
+ const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
if (kernel_filename == NULL) {
if (kernel_cmdline != NULL) {
@@ -2733,7 +2735,6 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_trace_opts);
qemu_plugin_add_opts();
qemu_add_opts(&qemu_option_rom_opts);
- qemu_add_opts(&qemu_machine_opts);
qemu_add_opts(&qemu_accel_opts);
qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
@@ -2774,6 +2775,7 @@ void qemu_init(int argc, char **argv, char **envp)
}
}
+ machine_opts_dict = qdict_new();
if (userconfig) {
qemu_read_default_config_file(&error_fatal);
}
@@ -2863,8 +2865,7 @@ void qemu_init(int argc, char **argv, char **envp)
parse_display(optarg);
break;
case QEMU_OPTION_nographic:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "graphics=off", false);
+ qdict_put_str(machine_opts_dict, "graphics", "off");
nographic = true;
dpy.type = DISPLAY_TYPE_NONE;
break;
@@ -2888,16 +2889,16 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_kernel:
- qemu_opts_set(qemu_find_opts("machine"), "kernel", optarg, &error_abort);
+ qdict_put_str(machine_opts_dict, "kernel", optarg);
break;
case QEMU_OPTION_initrd:
- qemu_opts_set(qemu_find_opts("machine"), "initrd", optarg, &error_abort);
+ qdict_put_str(machine_opts_dict, "initrd", optarg);
break;
case QEMU_OPTION_append:
- qemu_opts_set(qemu_find_opts("machine"), "append", optarg, &error_abort);
+ qdict_put_str(machine_opts_dict, "append", optarg);
break;
case QEMU_OPTION_dtb:
- qemu_opts_set(qemu_find_opts("machine"), "dtb", optarg, &error_abort);
+ qdict_put_str(machine_opts_dict, "dtb", optarg);
break;
case QEMU_OPTION_cdrom:
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
@@ -3007,7 +3008,7 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_bios:
- qemu_opts_set(qemu_find_opts("machine"), "firmware", optarg, &error_abort);
+ qdict_put_str(machine_opts_dict, "firmware", optarg);
break;
case QEMU_OPTION_singlestep:
singlestep = 1;
@@ -3234,6 +3235,8 @@ void qemu_init(int argc, char **argv, char **envp)
case QEMU_OPTION_no_quit:
dpy.has_window_close = true;
dpy.window_close = false;
+ warn_report("-no-quit is deprecated, please use "
+ "-display ...,window-close=off instead.");
break;
case QEMU_OPTION_sdl:
#ifdef CONFIG_SDL
@@ -3276,17 +3279,20 @@ void qemu_init(int argc, char **argv, char **envp)
preconfig_requested = true;
break;
case QEMU_OPTION_enable_kvm:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "accel=kvm", false);
+ qdict_put_str(machine_opts_dict, "accel", "kvm");
break;
case QEMU_OPTION_M:
case QEMU_OPTION_machine:
- olist = qemu_find_opts("machine");
- opts = qemu_opts_parse_noisily(olist, optarg, true);
- if (!opts) {
- exit(1);
+ {
+ bool help;
+
+ keyval_parse_into(machine_opts_dict, optarg, "type", &help, &error_fatal);
+ if (help) {
+ machine_help_func(machine_opts_dict);
+ exit(EXIT_SUCCESS);
+ }
+ break;
}
- break;
case QEMU_OPTION_accel:
accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
optarg, true);
@@ -3313,12 +3319,10 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_usb:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "usb=on", false);
+ qdict_put_str(machine_opts_dict, "usb", "on");
break;
case QEMU_OPTION_usbdevice:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "usb=on", false);
+ qdict_put_str(machine_opts_dict, "usb", "on");
add_device_config(DEV_USB, optarg);
break;
case QEMU_OPTION_device:
@@ -3328,21 +3332,16 @@ void qemu_init(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_smp:
- if (!qemu_opts_parse_noisily(qemu_find_opts("smp-opts"),
- optarg, true)) {
- exit(1);
- }
+ machine_parse_property_opt(qemu_find_opts("smp-opts"), "smp", optarg, &error_fatal);
break;
case QEMU_OPTION_vnc:
vnc_parse(optarg);
break;
case QEMU_OPTION_no_acpi:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "acpi=off", false);
+ qdict_put_str(machine_opts_dict, "acpi", "off");
break;
case QEMU_OPTION_no_hpet:
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "hpet=off", false);
+ qdict_put_str(machine_opts_dict, "hpet", "off");
break;
case QEMU_OPTION_no_reboot:
olist = qemu_find_opts("action");
@@ -3595,7 +3594,7 @@ void qemu_init(int argc, char **argv, char **envp)
*/
loc_set_none();
- qemu_validate_options();
+ qemu_validate_options(machine_opts_dict);
qemu_process_sugar_options();
/*
@@ -3628,7 +3627,7 @@ void qemu_init(int argc, char **argv, char **envp)
configure_rtc(qemu_find_opts_singleton("rtc"));
- qemu_create_machine(select_machine());
+ qemu_create_machine(machine_opts_dict);
suspend_mux_open();
@@ -3636,12 +3635,14 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_create_default_devices();
qemu_create_early_backends();
- qemu_apply_machine_options();
+ qemu_apply_legacy_machine_options(machine_opts_dict);
+ qemu_apply_machine_options(machine_opts_dict);
+ qobject_unref(machine_opts_dict);
phase_advance(PHASE_MACHINE_CREATED);
/*
* Note: uses machine properties such as kernel-irqchip, must run
- * after machine_set_property().
+ * after qemu_apply_machine_options.
*/
configure_accelerators(argv[0]);
phase_advance(PHASE_ACCEL_CREATED);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d8f3ab3192..5f595a0d7e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1304,53 +1304,37 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
};
#undef REGISTER
-typedef struct ExtSaveArea {
- uint32_t feature, bits;
- uint32_t offset, size;
-} ExtSaveArea;
-
-static const ExtSaveArea x86_ext_save_areas[] = {
+ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = {
[XSTATE_FP_BIT] = {
/* x87 FP state component is always enabled if XSAVE is supported */
.feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
- /* x87 state is in the legacy region of the XSAVE area */
- .offset = 0,
.size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
},
[XSTATE_SSE_BIT] = {
/* SSE state component is always enabled if XSAVE is supported */
.feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
- /* SSE state is in the legacy region of the XSAVE area */
- .offset = 0,
.size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
},
[XSTATE_YMM_BIT] =
{ .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
- .offset = offsetof(X86XSaveArea, avx_state),
.size = sizeof(XSaveAVX) },
[XSTATE_BNDREGS_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
- .offset = offsetof(X86XSaveArea, bndreg_state),
.size = sizeof(XSaveBNDREG) },
[XSTATE_BNDCSR_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
- .offset = offsetof(X86XSaveArea, bndcsr_state),
.size = sizeof(XSaveBNDCSR) },
[XSTATE_OPMASK_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
- .offset = offsetof(X86XSaveArea, opmask_state),
.size = sizeof(XSaveOpmask) },
[XSTATE_ZMM_Hi256_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
- .offset = offsetof(X86XSaveArea, zmm_hi256_state),
.size = sizeof(XSaveZMM_Hi256) },
[XSTATE_Hi16_ZMM_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
- .offset = offsetof(X86XSaveArea, hi16_zmm_state),
.size = sizeof(XSaveHi16_ZMM) },
[XSTATE_PKRU_BIT] =
{ .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
- .offset = offsetof(X86XSaveArea, pkru_state),
.size = sizeof(XSavePKRU) },
};
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index f7fa5870b1..0f7ddbfeae 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1305,41 +1305,23 @@ typedef struct XSavePKRU {
uint32_t padding;
} XSavePKRU;
-typedef struct X86XSaveArea {
- X86LegacyXSaveArea legacy;
- X86XSaveHeader header;
-
- /* Extended save areas: */
-
- /* AVX State: */
- XSaveAVX avx_state;
- uint8_t padding[960 - 576 - sizeof(XSaveAVX)];
- /* MPX State: */
- XSaveBNDREG bndreg_state;
- XSaveBNDCSR bndcsr_state;
- /* AVX-512 State: */
- XSaveOpmask opmask_state;
- XSaveZMM_Hi256 zmm_hi256_state;
- XSaveHi16_ZMM hi16_zmm_state;
- /* PKRU State: */
- XSavePKRU pkru_state;
-} X86XSaveArea;
-
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, avx_state) != 0x240);
QEMU_BUILD_BUG_ON(sizeof(XSaveAVX) != 0x100);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndreg_state) != 0x3c0);
QEMU_BUILD_BUG_ON(sizeof(XSaveBNDREG) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndcsr_state) != 0x400);
QEMU_BUILD_BUG_ON(sizeof(XSaveBNDCSR) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, opmask_state) != 0x440);
QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != 0x480);
QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != 0x680);
QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400);
-QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != 0xA80);
QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8);
+typedef struct ExtSaveArea {
+ uint32_t feature, bits;
+ uint32_t offset, size;
+} ExtSaveArea;
+
+#define XSAVE_STATE_AREA_COUNT (XSTATE_PKRU_BIT + 1)
+
+extern ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT];
+
typedef enum TPRAccess {
TPR_ACCESS_READ,
TPR_ACCESS_WRITE,
@@ -1637,6 +1619,7 @@ typedef struct CPUX86State {
uint64_t apic_bus_freq;
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
void *xsave_buf;
+ uint32_t xsave_buf_len;
#endif
#if defined(CONFIG_KVM)
struct kvm_nested_state *nested_state;
@@ -2197,8 +2180,8 @@ void x86_cpu_dump_local_apic_state(CPUState *cs, int flags);
/* cpu.c */
bool cpu_is_bsp(X86CPU *cpu);
-void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
-void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
+void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen);
+void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen);
void x86_update_hflags(CPUX86State* env);
static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat)
diff --git a/target/i386/hvf/hvf-cpu.c b/target/i386/hvf/hvf-cpu.c
index 8fbc423888..333db59898 100644
--- a/target/i386/hvf/hvf-cpu.c
+++ b/target/i386/hvf/hvf-cpu.c
@@ -30,6 +30,33 @@ static void hvf_cpu_max_instance_init(X86CPU *cpu)
hvf_get_supported_cpuid(0xC0000000, 0, R_EAX);
}
+static void hvf_cpu_xsave_init(void)
+{
+ static bool first = true;
+ int i;
+
+ if (!first) {
+ return;
+ }
+ first = false;
+
+ /* x87 and SSE states are in the legacy region of the XSAVE area. */
+ x86_ext_save_areas[XSTATE_FP_BIT].offset = 0;
+ x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0;
+
+ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
+ ExtSaveArea *esa = &x86_ext_save_areas[i];
+
+ if (esa->size) {
+ int sz = hvf_get_supported_cpuid(0xd, i, R_EAX);
+ if (sz != 0) {
+ assert(esa->size == sz);
+ esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX);
+ }
+ }
+ }
+}
+
static void hvf_cpu_instance_init(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
@@ -42,6 +69,8 @@ static void hvf_cpu_instance_init(CPUState *cs)
if (cpu->max_features) {
hvf_cpu_max_instance_init(cpu);
}
+
+ hvf_cpu_xsave_init();
}
static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 346dbcc26f..79ba4ed93a 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -267,7 +267,14 @@ int hvf_arch_init_vcpu(CPUState *cpu)
wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
x86cpu = X86_CPU(cpu);
- x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
+ x86cpu->env.xsave_buf_len = 4096;
+ x86cpu->env.xsave_buf = qemu_memalign(4096, x86cpu->env.xsave_buf_len);
+
+ /*
+ * The allocated storage must be large enough for all of the
+ * possible XSAVE state components.
+ */
+ assert(hvf_get_supported_cpuid(0xd, 0, R_ECX) <= x86cpu->env.xsave_buf_len);
hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_STAR, 1);
hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
index 2ced2c2478..05ec1bddc4 100644
--- a/target/i386/hvf/x86hvf.c
+++ b/target/i386/hvf/x86hvf.c
@@ -73,14 +73,12 @@ void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg)
void hvf_put_xsave(CPUState *cpu_state)
{
+ void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
+ uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
- struct X86XSaveArea *xsave;
+ x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
- xsave = X86_CPU(cpu_state)->env.xsave_buf;
-
- x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
-
- if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
+ if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, xsave, xsave_len)) {
abort();
}
}
@@ -158,15 +156,14 @@ void hvf_put_msrs(CPUState *cpu_state)
void hvf_get_xsave(CPUState *cpu_state)
{
- struct X86XSaveArea *xsave;
-
- xsave = X86_CPU(cpu_state)->env.xsave_buf;
+ void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
+ uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
- if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
+ if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, xsave, xsave_len)) {
abort();
}
- x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave);
+ x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
}
void hvf_get_segments(CPUState *cpu_state)
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 00369c2000..bbe817764d 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -122,6 +122,34 @@ static void kvm_cpu_max_instance_init(X86CPU *cpu)
kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
}
+static void kvm_cpu_xsave_init(void)
+{
+ static bool first = true;
+ KVMState *s = kvm_state;
+ int i;
+
+ if (!first) {
+ return;
+ }
+ first = false;
+
+ /* x87 and SSE states are in the legacy region of the XSAVE area. */
+ x86_ext_save_areas[XSTATE_FP_BIT].offset = 0;
+ x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0;
+
+ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
+ ExtSaveArea *esa = &x86_ext_save_areas[i];
+
+ if (esa->size) {
+ int sz = kvm_arch_get_supported_cpuid(s, 0xd, i, R_EAX);
+ if (sz != 0) {
+ assert(esa->size == sz);
+ esa->offset = kvm_arch_get_supported_cpuid(s, 0xd, i, R_EBX);
+ }
+ }
+ }
+}
+
static void kvm_cpu_instance_init(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
@@ -141,6 +169,8 @@ static void kvm_cpu_instance_init(CPUState *cs)
if (cpu->max_features) {
kvm_cpu_max_instance_init(cpu);
}
+
+ kvm_cpu_xsave_init();
}
static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 04e4ec063f..a85035492f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1888,8 +1888,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
if (has_xsave) {
- env->xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
- memset(env->xsave_buf, 0, sizeof(struct kvm_xsave));
+ env->xsave_buf_len = sizeof(struct kvm_xsave);
+ env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len);
+ memset(env->xsave_buf, 0, env->xsave_buf_len);
+
+ /*
+ * The allocated storage must be large enough for all of the
+ * possible XSAVE state components.
+ */
+ assert(kvm_arch_get_supported_cpuid(kvm_state, 0xd, 0, R_ECX)
+ <= env->xsave_buf_len);
}
max_nested_state_len = kvm_max_nested_state_length();
@@ -2466,54 +2474,15 @@ static int kvm_put_fpu(X86CPU *cpu)
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu);
}
-#define XSAVE_FCW_FSW 0
-#define XSAVE_FTW_FOP 1
-#define XSAVE_CWD_RIP 2
-#define XSAVE_CWD_RDP 4
-#define XSAVE_MXCSR 6
-#define XSAVE_ST_SPACE 8
-#define XSAVE_XMM_SPACE 40
-#define XSAVE_XSTATE_BV 128
-#define XSAVE_YMMH_SPACE 144
-#define XSAVE_BNDREGS 240
-#define XSAVE_BNDCSR 256
-#define XSAVE_OPMASK 272
-#define XSAVE_ZMM_Hi256 288
-#define XSAVE_Hi16_ZMM 416
-#define XSAVE_PKRU 672
-
-#define XSAVE_BYTE_OFFSET(word_offset) \
- ((word_offset) * sizeof_field(struct kvm_xsave, region[0]))
-
-#define ASSERT_OFFSET(word_offset, field) \
- QEMU_BUILD_BUG_ON(XSAVE_BYTE_OFFSET(word_offset) != \
- offsetof(X86XSaveArea, field))
-
-ASSERT_OFFSET(XSAVE_FCW_FSW, legacy.fcw);
-ASSERT_OFFSET(XSAVE_FTW_FOP, legacy.ftw);
-ASSERT_OFFSET(XSAVE_CWD_RIP, legacy.fpip);
-ASSERT_OFFSET(XSAVE_CWD_RDP, legacy.fpdp);
-ASSERT_OFFSET(XSAVE_MXCSR, legacy.mxcsr);
-ASSERT_OFFSET(XSAVE_ST_SPACE, legacy.fpregs);
-ASSERT_OFFSET(XSAVE_XMM_SPACE, legacy.xmm_regs);
-ASSERT_OFFSET(XSAVE_XSTATE_BV, header.xstate_bv);
-ASSERT_OFFSET(XSAVE_YMMH_SPACE, avx_state);
-ASSERT_OFFSET(XSAVE_BNDREGS, bndreg_state);
-ASSERT_OFFSET(XSAVE_BNDCSR, bndcsr_state);
-ASSERT_OFFSET(XSAVE_OPMASK, opmask_state);
-ASSERT_OFFSET(XSAVE_ZMM_Hi256, zmm_hi256_state);
-ASSERT_OFFSET(XSAVE_Hi16_ZMM, hi16_zmm_state);
-ASSERT_OFFSET(XSAVE_PKRU, pkru_state);
-
static int kvm_put_xsave(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
- X86XSaveArea *xsave = env->xsave_buf;
+ void *xsave = env->xsave_buf;
if (!has_xsave) {
return kvm_put_fpu(cpu);
}
- x86_cpu_xsave_all_areas(cpu, xsave);
+ x86_cpu_xsave_all_areas(cpu, xsave, env->xsave_buf_len);
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
}
@@ -3158,7 +3127,7 @@ static int kvm_get_fpu(X86CPU *cpu)
static int kvm_get_xsave(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
- X86XSaveArea *xsave = env->xsave_buf;
+ void *xsave = env->xsave_buf;
int ret;
if (!has_xsave) {
@@ -3169,7 +3138,7 @@ static int kvm_get_xsave(X86CPU *cpu)
if (ret < 0) {
return ret;
}
- x86_cpu_xrstor_all_areas(cpu, xsave);
+ x86_cpu_xrstor_all_areas(cpu, xsave, env->xsave_buf_len);
return 0;
}
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 4e11965067..74bbe94b80 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include <math.h>
#include "cpu.h"
+#include "tcg-cpu.h"
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
#include "fpu/softfloat-macros.h"
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 014ebea2f6..e96ec9bbcc 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -80,6 +80,24 @@ static void tcg_cpu_class_init(CPUClass *cc)
cc->init_accel_cpu = tcg_cpu_init_ops;
}
+static void tcg_cpu_xsave_init(void)
+{
+#define XO(bit, field) \
+ x86_ext_save_areas[bit].offset = offsetof(X86XSaveArea, field);
+
+ XO(XSTATE_FP_BIT, legacy);
+ XO(XSTATE_SSE_BIT, legacy);
+ XO(XSTATE_YMM_BIT, avx_state);
+ XO(XSTATE_BNDREGS_BIT, bndreg_state);
+ XO(XSTATE_BNDCSR_BIT, bndcsr_state);
+ XO(XSTATE_OPMASK_BIT, opmask_state);
+ XO(XSTATE_ZMM_Hi256_BIT, zmm_hi256_state);
+ XO(XSTATE_Hi16_ZMM_BIT, hi16_zmm_state);
+ XO(XSTATE_PKRU_BIT, pkru_state);
+
+#undef XO
+}
+
/*
* TCG-specific defaults that override all CPU models when using TCG
*/
@@ -93,6 +111,8 @@ static void tcg_cpu_instance_init(CPUState *cs)
X86CPU *cpu = X86_CPU(cs);
/* Special cases not set in the X86CPUDefinition structs: */
x86_cpu_apply_props(cpu, tcg_default_props);
+
+ tcg_cpu_xsave_init();
}
static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
diff --git a/target/i386/tcg/tcg-cpu.h b/target/i386/tcg/tcg-cpu.h
index 36bd300af0..53a8494455 100644
--- a/target/i386/tcg/tcg-cpu.h
+++ b/target/i386/tcg/tcg-cpu.h
@@ -19,6 +19,63 @@
#ifndef TCG_CPU_H
#define TCG_CPU_H
+#define XSAVE_FCW_FSW_OFFSET 0x000
+#define XSAVE_FTW_FOP_OFFSET 0x004
+#define XSAVE_CWD_RIP_OFFSET 0x008
+#define XSAVE_CWD_RDP_OFFSET 0x010
+#define XSAVE_MXCSR_OFFSET 0x018
+#define XSAVE_ST_SPACE_OFFSET 0x020
+#define XSAVE_XMM_SPACE_OFFSET 0x0a0
+#define XSAVE_XSTATE_BV_OFFSET 0x200
+#define XSAVE_AVX_OFFSET 0x240
+#define XSAVE_BNDREG_OFFSET 0x3c0
+#define XSAVE_BNDCSR_OFFSET 0x400
+#define XSAVE_OPMASK_OFFSET 0x440
+#define XSAVE_ZMM_HI256_OFFSET 0x480
+#define XSAVE_HI16_ZMM_OFFSET 0x680
+#define XSAVE_PKRU_OFFSET 0xa80
+
+typedef struct X86XSaveArea {
+ X86LegacyXSaveArea legacy;
+ X86XSaveHeader header;
+
+ /* Extended save areas: */
+
+ /* AVX State: */
+ XSaveAVX avx_state;
+
+ /* Ensure that XSaveBNDREG is properly aligned. */
+ uint8_t padding[XSAVE_BNDREG_OFFSET
+ - sizeof(X86LegacyXSaveArea)
+ - sizeof(X86XSaveHeader)
+ - sizeof(XSaveAVX)];
+
+ /* MPX State: */
+ XSaveBNDREG bndreg_state;
+ XSaveBNDCSR bndcsr_state;
+ /* AVX-512 State: */
+ XSaveOpmask opmask_state;
+ XSaveZMM_Hi256 zmm_hi256_state;
+ XSaveHi16_ZMM hi16_zmm_state;
+ /* PKRU State: */
+ XSavePKRU pkru_state;
+} X86XSaveArea;
+
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.fcw) != XSAVE_FCW_FSW_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.ftw) != XSAVE_FTW_FOP_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.fpip) != XSAVE_CWD_RIP_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.fpdp) != XSAVE_CWD_RDP_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.mxcsr) != XSAVE_MXCSR_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.fpregs) != XSAVE_ST_SPACE_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, legacy.xmm_regs) != XSAVE_XMM_SPACE_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, avx_state) != XSAVE_AVX_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndreg_state) != XSAVE_BNDREG_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndcsr_state) != XSAVE_BNDCSR_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, opmask_state) != XSAVE_OPMASK_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != XSAVE_ZMM_HI256_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != XSAVE_HI16_ZMM_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != XSAVE_PKRU_OFFSET);
+
bool tcg_cpu_realizefn(CPUState *cs, Error **errp);
#endif /* TCG_CPU_H */
diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c
index 818115e7d2..ac61a96344 100644
--- a/target/i386/xsave_helper.c
+++ b/target/i386/xsave_helper.c
@@ -6,14 +6,23 @@
#include "cpu.h"
-void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
+void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen)
{
CPUX86State *env = &cpu->env;
- X86XSaveArea *xsave = buf;
+ const ExtSaveArea *e, *f;
+ int i;
+ X86LegacyXSaveArea *legacy;
+ X86XSaveHeader *header;
uint16_t cwd, swd, twd;
- int i;
- memset(xsave, 0, sizeof(X86XSaveArea));
+
+ memset(buf, 0, buflen);
+
+ e = &x86_ext_save_areas[XSTATE_FP_BIT];
+
+ legacy = buf + e->offset;
+ header = buf + e->offset + sizeof(*legacy);
+
twd = 0;
swd = env->fpus & ~(7 << 11);
swd |= (env->fpstt & 7) << 11;
@@ -21,92 +30,222 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
for (i = 0; i < 8; ++i) {
twd |= (!env->fptags[i]) << i;
}
- xsave->legacy.fcw = cwd;
- xsave->legacy.fsw = swd;
- xsave->legacy.ftw = twd;
- xsave->legacy.fpop = env->fpop;
- xsave->legacy.fpip = env->fpip;
- xsave->legacy.fpdp = env->fpdp;
- memcpy(&xsave->legacy.fpregs, env->fpregs,
- sizeof env->fpregs);
- xsave->legacy.mxcsr = env->mxcsr;
- xsave->header.xstate_bv = env->xstate_bv;
- memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs,
- sizeof env->bnd_regs);
- xsave->bndcsr_state.bndcsr = env->bndcs_regs;
- memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs,
- sizeof env->opmask_regs);
+ legacy->fcw = cwd;
+ legacy->fsw = swd;
+ legacy->ftw = twd;
+ legacy->fpop = env->fpop;
+ legacy->fpip = env->fpip;
+ legacy->fpdp = env->fpdp;
+ memcpy(&legacy->fpregs, env->fpregs,
+ sizeof(env->fpregs));
+ legacy->mxcsr = env->mxcsr;
for (i = 0; i < CPU_NB_REGS; i++) {
- uint8_t *xmm = xsave->legacy.xmm_regs[i];
- uint8_t *ymmh = xsave->avx_state.ymmh[i];
- uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
+ uint8_t *xmm = legacy->xmm_regs[i];
+
stq_p(xmm, env->xmm_regs[i].ZMM_Q(0));
- stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1));
- stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2));
- stq_p(ymmh+8, env->xmm_regs[i].ZMM_Q(3));
- stq_p(zmmh, env->xmm_regs[i].ZMM_Q(4));
- stq_p(zmmh+8, env->xmm_regs[i].ZMM_Q(5));
- stq_p(zmmh+16, env->xmm_regs[i].ZMM_Q(6));
- stq_p(zmmh+24, env->xmm_regs[i].ZMM_Q(7));
+ stq_p(xmm + 8, env->xmm_regs[i].ZMM_Q(1));
}
+ header->xstate_bv = env->xstate_bv;
+
+ e = &x86_ext_save_areas[XSTATE_YMM_BIT];
+ if (e->size && e->offset) {
+ XSaveAVX *avx;
+
+ avx = buf + e->offset;
+
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ uint8_t *ymmh = avx->ymmh[i];
+
+ stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2));
+ stq_p(ymmh + 8, env->xmm_regs[i].ZMM_Q(3));
+ }
+ }
+
+ e = &x86_ext_save_areas[XSTATE_BNDREGS_BIT];
+ if (e->size && e->offset) {
+ XSaveBNDREG *bndreg;
+ XSaveBNDCSR *bndcsr;
+
+ f = &x86_ext_save_areas[XSTATE_BNDCSR_BIT];
+ assert(f->size);
+ assert(f->offset);
+
+ bndreg = buf + e->offset;
+ bndcsr = buf + f->offset;
+
+ memcpy(&bndreg->bnd_regs, env->bnd_regs,
+ sizeof(env->bnd_regs));
+ bndcsr->bndcsr = env->bndcs_regs;
+ }
+
+ e = &x86_ext_save_areas[XSTATE_OPMASK_BIT];
+ if (e->size && e->offset) {
+ XSaveOpmask *opmask;
+ XSaveZMM_Hi256 *zmm_hi256;
+#ifdef TARGET_X86_64
+ XSaveHi16_ZMM *hi16_zmm;
+#endif
+
+ f = &x86_ext_save_areas[XSTATE_ZMM_Hi256_BIT];
+ assert(f->size);
+ assert(f->offset);
+
+ opmask = buf + e->offset;
+ zmm_hi256 = buf + f->offset;
+
+ memcpy(&opmask->opmask_regs, env->opmask_regs,
+ sizeof(env->opmask_regs));
+
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ uint8_t *zmmh = zmm_hi256->zmm_hi256[i];
+
+ stq_p(zmmh, env->xmm_regs[i].ZMM_Q(4));
+ stq_p(zmmh + 8, env->xmm_regs[i].ZMM_Q(5));
+ stq_p(zmmh + 16, env->xmm_regs[i].ZMM_Q(6));
+ stq_p(zmmh + 24, env->xmm_regs[i].ZMM_Q(7));
+ }
+
#ifdef TARGET_X86_64
- memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16],
- 16 * sizeof env->xmm_regs[16]);
- memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
+ f = &x86_ext_save_areas[XSTATE_Hi16_ZMM_BIT];
+ assert(f->size);
+ assert(f->offset);
+
+ hi16_zmm = buf + f->offset;
+
+ memcpy(&hi16_zmm->hi16_zmm, &env->xmm_regs[16],
+ 16 * sizeof(env->xmm_regs[16]));
#endif
+ }
+#ifdef TARGET_X86_64
+ e = &x86_ext_save_areas[XSTATE_PKRU_BIT];
+ if (e->size && e->offset) {
+ XSavePKRU *pkru = buf + e->offset;
+
+ memcpy(pkru, &env->pkru, sizeof(env->pkru));
+ }
+#endif
}
-void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
+void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen)
{
-
CPUX86State *env = &cpu->env;
- const X86XSaveArea *xsave = buf;
-
+ const ExtSaveArea *e, *f, *g;
int i;
+
+ const X86LegacyXSaveArea *legacy;
+ const X86XSaveHeader *header;
uint16_t cwd, swd, twd;
- cwd = xsave->legacy.fcw;
- swd = xsave->legacy.fsw;
- twd = xsave->legacy.ftw;
- env->fpop = xsave->legacy.fpop;
+
+ e = &x86_ext_save_areas[XSTATE_FP_BIT];
+
+ legacy = buf + e->offset;
+ header = buf + e->offset + sizeof(*legacy);
+
+ cwd = legacy->fcw;
+ swd = legacy->fsw;
+ twd = legacy->ftw;
+ env->fpop = legacy->fpop;
env->fpstt = (swd >> 11) & 7;
env->fpus = swd;
env->fpuc = cwd;
for (i = 0; i < 8; ++i) {
env->fptags[i] = !((twd >> i) & 1);
}
- env->fpip = xsave->legacy.fpip;
- env->fpdp = xsave->legacy.fpdp;
- env->mxcsr = xsave->legacy.mxcsr;
- memcpy(env->fpregs, &xsave->legacy.fpregs,
- sizeof env->fpregs);
- env->xstate_bv = xsave->header.xstate_bv;
- memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs,
- sizeof env->bnd_regs);
- env->bndcs_regs = xsave->bndcsr_state.bndcsr;
- memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs,
- sizeof env->opmask_regs);
+ env->fpip = legacy->fpip;
+ env->fpdp = legacy->fpdp;
+ env->mxcsr = legacy->mxcsr;
+ memcpy(env->fpregs, &legacy->fpregs,
+ sizeof(env->fpregs));
for (i = 0; i < CPU_NB_REGS; i++) {
- const uint8_t *xmm = xsave->legacy.xmm_regs[i];
- const uint8_t *ymmh = xsave->avx_state.ymmh[i];
- const uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
+ const uint8_t *xmm = legacy->xmm_regs[i];
+
env->xmm_regs[i].ZMM_Q(0) = ldq_p(xmm);
- env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8);
- env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh);
- env->xmm_regs[i].ZMM_Q(3) = ldq_p(ymmh+8);
- env->xmm_regs[i].ZMM_Q(4) = ldq_p(zmmh);
- env->xmm_regs[i].ZMM_Q(5) = ldq_p(zmmh+8);
- env->xmm_regs[i].ZMM_Q(6) = ldq_p(zmmh+16);
- env->xmm_regs[i].ZMM_Q(7) = ldq_p(zmmh+24);
+ env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm + 8);
+ }
+
+ env->xstate_bv = header->xstate_bv;
+
+ e = &x86_ext_save_areas[XSTATE_YMM_BIT];
+ if (e->size && e->offset) {
+ const XSaveAVX *avx;
+
+ avx = buf + e->offset;
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ const uint8_t *ymmh = avx->ymmh[i];
+
+ env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh);
+ env->xmm_regs[i].ZMM_Q(3) = ldq_p(ymmh + 8);
+ }
+ }
+
+ e = &x86_ext_save_areas[XSTATE_BNDREGS_BIT];
+ if (e->size && e->offset) {
+ const XSaveBNDREG *bndreg;
+ const XSaveBNDCSR *bndcsr;
+
+ f = &x86_ext_save_areas[XSTATE_BNDCSR_BIT];
+ assert(f->size);
+ assert(f->offset);
+
+ bndreg = buf + e->offset;
+ bndcsr = buf + f->offset;
+
+ memcpy(env->bnd_regs, &bndreg->bnd_regs,
+ sizeof(env->bnd_regs));
+ env->bndcs_regs = bndcsr->bndcsr;
}
+ e = &x86_ext_save_areas[XSTATE_OPMASK_BIT];
+ if (e->size && e->offset) {
+ const XSaveOpmask *opmask;
+ const XSaveZMM_Hi256 *zmm_hi256;
#ifdef TARGET_X86_64
- memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm,
- 16 * sizeof env->xmm_regs[16]);
- memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
+ const XSaveHi16_ZMM *hi16_zmm;
#endif
+ f = &x86_ext_save_areas[XSTATE_ZMM_Hi256_BIT];
+ assert(f->size);
+ assert(f->offset);
+
+ g = &x86_ext_save_areas[XSTATE_Hi16_ZMM_BIT];
+ assert(g->size);
+ assert(g->offset);
+
+ opmask = buf + e->offset;
+ zmm_hi256 = buf + f->offset;
+#ifdef TARGET_X86_64
+ hi16_zmm = buf + g->offset;
+#endif
+
+ memcpy(env->opmask_regs, &opmask->opmask_regs,
+ sizeof(env->opmask_regs));
+
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ const uint8_t *zmmh = zmm_hi256->zmm_hi256[i];
+
+ env->xmm_regs[i].ZMM_Q(4) = ldq_p(zmmh);
+ env->xmm_regs[i].ZMM_Q(5) = ldq_p(zmmh + 8);
+ env->xmm_regs[i].ZMM_Q(6) = ldq_p(zmmh + 16);
+ env->xmm_regs[i].ZMM_Q(7) = ldq_p(zmmh + 24);
+ }
+
+#ifdef TARGET_X86_64
+ memcpy(&env->xmm_regs[16], &hi16_zmm->hi16_zmm,
+ 16 * sizeof(env->xmm_regs[16]));
+#endif
+ }
+
+#ifdef TARGET_X86_64
+ e = &x86_ext_save_areas[XSTATE_PKRU_BIT];
+ if (e->size && e->offset) {
+ const XSavePKRU *pkru;
+
+ pkru = buf + e->offset;
+ memcpy(&env->pkru, pkru, sizeof(env->pkru));
+ }
+#endif
}
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
index dc0ec571ca..c677cd63c4 100644
--- a/tests/qtest/numa-test.c
+++ b/tests/qtest/numa-test.c
@@ -25,7 +25,7 @@ static void test_mon_explicit(const void *data)
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
+ cli = make_cli(data, "-machine smp.cpus=8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
"-numa node,nodeid=1,cpus=4-7");
qts = qtest_init(cli);
@@ -42,7 +42,7 @@ static void test_def_cpu_split(const void *data)
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 8 -numa node,memdev=ram -numa node");
+ cli = make_cli(data, "-machine smp.cpus=8 -numa node,memdev=ram -numa node");
qts = qtest_init(cli);
s = qtest_hmp(qts, "info numa");
@@ -58,7 +58,7 @@ static void test_mon_partial(const void *data)
g_autofree char *s = NULL;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 8 "
+ cli = make_cli(data, "-machine smp.cpus=8 "
"-numa node,nodeid=0,memdev=ram,cpus=0-1 "
"-numa node,nodeid=1,cpus=4-5 ");
qts = qtest_init(cli);
@@ -86,7 +86,7 @@ static void test_query_cpus(const void *data)
QTestState *qts;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 8 -numa node,memdev=ram,cpus=0-3 "
+ cli = make_cli(data, "-machine smp.cpus=8 -numa node,memdev=ram,cpus=0-3 "
"-numa node,cpus=4-7");
qts = qtest_init(cli);
cpus = get_cpus(qts, &resp);
@@ -124,7 +124,7 @@ static void pc_numa_cpu(const void *data)
QTestState *qts;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 "
+ cli = make_cli(data, "-cpu pentium -machine smp.cpus=8,smp.sockets=2,smp.cores=2,smp.threads=2 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=1,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1,core-id=0 "
@@ -177,7 +177,7 @@ static void spapr_numa_cpu(const void *data)
QTestState *qts;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 4,cores=4 "
+ cli = make_cli(data, "-machine smp.cpus=4,smp.cores=4 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=0,core-id=0 "
"-numa cpu,node-id=0,core-id=1 "
@@ -222,7 +222,7 @@ static void aarch64_numa_cpu(const void *data)
QTestState *qts;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-smp 2 "
+ cli = make_cli(data, "-machine smp.cpus=2 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=1,thread-id=0 "
"-numa cpu,node-id=0,thread-id=1");
@@ -265,7 +265,7 @@ static void pc_dynamic_cpu_cfg(const void *data)
QTestState *qs;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-nodefaults --preconfig -smp 2");
+ cli = make_cli(data, "-nodefaults --preconfig -machine smp.cpus=2");
qs = qtest_init(cli);
/* create 2 numa nodes */
@@ -324,7 +324,7 @@ static void pc_hmat_build_cfg(const void *data)
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
- "-smp 2,sockets=2 "
+ "-machine smp.cpus=2,smp.sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
@@ -453,7 +453,7 @@ static void pc_hmat_off_cfg(const void *data)
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig "
- "-smp 2,sockets=2 "
+ "-machine smp.cpus=2,smp.sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0,prealloc=y "
"-object memory-backend-ram,size=64M,id=m1 "
@@ -492,7 +492,7 @@ static void pc_hmat_erange_cfg(const void *data)
g_autofree char *cli = NULL;
cli = make_cli(data, "-nodefaults --preconfig -machine hmat=on "
- "-smp 2,sockets=2 "
+ "-machine smp.cpus=2,smp.sockets=2 "
"-m 128M,slots=2,maxmem=1G "
"-object memory-backend-ram,size=64M,id=m0 "
"-object memory-backend-ram,size=64M,id=m1 "
diff --git a/tests/unit/test-keyval.c b/tests/unit/test-keyval.c
index e20c07cf3e..af0581ae6c 100644
--- a/tests/unit/test-keyval.c
+++ b/tests/unit/test-keyval.c
@@ -747,6 +747,61 @@ static void test_keyval_visit_any(void)
visit_free(v);
}
+static void test_keyval_merge_dict(void)
+{
+ QDict *first = keyval_parse("opt1=abc,opt2.sub1=def,opt2.sub2=ghi,opt3=xyz",
+ NULL, NULL, &error_abort);
+ QDict *second = keyval_parse("opt1=ABC,opt2.sub2=GHI,opt2.sub3=JKL",
+ NULL, NULL, &error_abort);
+ QDict *combined = keyval_parse("opt1=ABC,opt2.sub1=def,opt2.sub2=GHI,opt2.sub3=JKL,opt3=xyz",
+ NULL, NULL, &error_abort);
+ Error *err = NULL;
+
+ keyval_merge(first, second, &err);
+ g_assert(!err);
+ g_assert(qobject_is_equal(QOBJECT(combined), QOBJECT(first)));
+ qobject_unref(first);
+ qobject_unref(second);
+ qobject_unref(combined);
+}
+
+static void test_keyval_merge_list(void)
+{
+ QDict *first = keyval_parse("opt1.0=abc,opt2.0=xyz",
+ NULL, NULL, &error_abort);
+ QDict *second = keyval_parse("opt1.0=def",
+ NULL, NULL, &error_abort);
+ QDict *combined = keyval_parse("opt1.0=abc,opt1.1=def,opt2.0=xyz",
+ NULL, NULL, &error_abort);
+ Error *err = NULL;
+
+ keyval_merge(first, second, &err);
+ g_assert(!err);
+ g_assert(qobject_is_equal(QOBJECT(combined), QOBJECT(first)));
+ qobject_unref(first);
+ qobject_unref(second);
+ qobject_unref(combined);
+}
+
+static void test_keyval_merge_conflict(void)
+{
+ QDict *first = keyval_parse("opt2=ABC",
+ NULL, NULL, &error_abort);
+ QDict *second = keyval_parse("opt2.sub1=def,opt2.sub2=ghi",
+ NULL, NULL, &error_abort);
+ QDict *third = qdict_clone_shallow(first);
+ Error *err = NULL;
+
+ keyval_merge(first, second, &err);
+ error_free_or_abort(&err);
+ keyval_merge(second, third, &err);
+ error_free_or_abort(&err);
+
+ qobject_unref(first);
+ qobject_unref(second);
+ qobject_unref(third);
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -760,6 +815,9 @@ int main(int argc, char *argv[])
g_test_add_func("/keyval/visit/optional", test_keyval_visit_optional);
g_test_add_func("/keyval/visit/alternate", test_keyval_visit_alternate);
g_test_add_func("/keyval/visit/any", test_keyval_visit_any);
+ g_test_add_func("/keyval/merge/dict", test_keyval_merge_dict);
+ g_test_add_func("/keyval/merge/list", test_keyval_merge_list);
+ g_test_add_func("/keyval/merge/conflict", test_keyval_merge_conflict);
g_test_run();
return 0;
}
diff --git a/tests/unit/test-qemu-opts.c b/tests/unit/test-qemu-opts.c
index 6568e31a72..828d40e928 100644
--- a/tests/unit/test-qemu-opts.c
+++ b/tests/unit/test-qemu-opts.c
@@ -410,40 +410,6 @@ static void test_qemu_opts_reset(void)
g_assert(opts == NULL);
}
-static void test_qemu_opts_set(void)
-{
- QemuOptsList *list;
- QemuOpts *opts;
- const char *opt;
-
- list = qemu_find_opts("opts_list_04");
- g_assert(list != NULL);
- g_assert(QTAILQ_EMPTY(&list->head));
- g_assert_cmpstr(list->name, ==, "opts_list_04");
-
- /* should not find anything at this point */
- opts = qemu_opts_find(list, NULL);
- g_assert(opts == NULL);
-
- /* implicitly create opts and set str3 value */
- qemu_opts_set(list, "str3", "value", &error_abort);
- g_assert(!QTAILQ_EMPTY(&list->head));
-
- /* get the just created opts */
- opts = qemu_opts_find(list, NULL);
- g_assert(opts != NULL);
-
- /* check the str3 value */
- opt = qemu_opt_get(opts, "str3");
- g_assert_cmpstr(opt, ==, "value");
-
- qemu_opts_del(opts);
-
- /* should not find anything at this point */
- opts = qemu_opts_find(list, NULL);
- g_assert(opts == NULL);
-}
-
static int opts_count_iter(void *opaque, const char *name, const char *value,
Error **errp)
{
@@ -1041,7 +1007,6 @@ int main(int argc, char *argv[])
g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
- g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set);
g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
diff --git a/util/keyval.c b/util/keyval.c
index be34928813..904337c8a1 100644
--- a/util/keyval.c
+++ b/util/keyval.c
@@ -311,6 +311,86 @@ static char *reassemble_key(GSList *key)
}
/*
+ * Recursive worker for keyval_merge.
+ *
+ * @str is the path that led to the * current dictionary (to be used for
+ * error messages). It is modified internally but restored before the
+ * function returns.
+ */
+static void keyval_do_merge(QDict *dest, const QDict *merged, GString *str, Error **errp)
+{
+ size_t save_len = str->len;
+ const QDictEntry *ent;
+ QObject *old_value;
+
+ for (ent = qdict_first(merged); ent; ent = qdict_next(merged, ent)) {
+ old_value = qdict_get(dest, ent->key);
+ if (old_value) {
+ if (qobject_type(old_value) != qobject_type(ent->value)) {
+ error_setg(errp, "Parameter '%s%s' used inconsistently",
+ str->str, ent->key);
+ return;
+ } else if (qobject_type(ent->value) == QTYPE_QDICT) {
+ /* Merge sub-dictionaries. */
+ g_string_append(str, ent->key);
+ g_string_append_c(str, '.');
+ keyval_do_merge(qobject_to(QDict, old_value),
+ qobject_to(QDict, ent->value),
+ str, errp);
+ g_string_truncate(str, save_len);
+ continue;
+ } else if (qobject_type(ent->value) == QTYPE_QLIST) {
+ /* Append to old list. */
+ QList *old = qobject_to(QList, old_value);
+ QList *new = qobject_to(QList, ent->value);
+ const QListEntry *item;
+ QLIST_FOREACH_ENTRY(new, item) {
+ qobject_ref(item->value);
+ qlist_append_obj(old, item->value);
+ }
+ continue;
+ } else {
+ assert(qobject_type(ent->value) == QTYPE_QSTRING);
+ }
+ }
+
+ qobject_ref(ent->value);
+ qdict_put_obj(dest, ent->key, ent->value);
+ }
+}
+
+/* Merge the @merged dictionary into @dest.
+ *
+ * The dictionaries are expected to be returned by the keyval parser, and
+ * therefore the only expected scalar type is the string. In case the same
+ * path is present in both @dest and @merged, the semantics are as follows:
+ *
+ * - lists are concatenated
+ *
+ * - dictionaries are merged recursively
+ *
+ * - for scalar values, @merged wins
+ *
+ * In case an error is reported, @dest may already have been modified.
+ *
+ * This function can be used to implement semantics analogous to QemuOpts's
+ * .merge_lists = true case, or to implement -set for options backed by QDicts.
+ *
+ * Note: while QemuOpts is commonly used so that repeated keys overwrite
+ * ("last one wins"), it can also be used so that repeated keys build up
+ * a list. keyval_merge() can only be used when the options' semantics are
+ * the former, not the latter.
+ */
+void keyval_merge(QDict *dest, const QDict *merged, Error **errp)
+{
+ GString *str;
+
+ str = g_string_new("");
+ keyval_do_merge(dest, merged, str, errp);
+ g_string_free(str, TRUE);
+}
+
+/*
* Listify @cur recursively.
* Replace QDicts whose keys are all valid list indexes by QLists.
* @key_of_cur is the list of key fragments leading up to @cur.
@@ -431,13 +511,14 @@ static QObject *keyval_listify(QDict *cur, GSList *key_of_cur, Error **errp)
* If @p_help is not NULL, store whether help is requested there.
* If @p_help is NULL and help is requested, fail.
*
- * On success, return a dictionary of the parsed keys and values.
- * On failure, store an error through @errp and return NULL.
+ * On success, return @dict, now filled with the parsed keys and values.
+ *
+ * On failure, store an error through @errp and return NULL. Any keys
+ * and values parsed so far will be in @dict nevertheless.
*/
-QDict *keyval_parse(const char *params, const char *implied_key,
- bool *p_help, Error **errp)
+QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
+ bool *p_help, Error **errp)
{
- QDict *qdict = qdict_new();
QObject *listified;
const char *s;
bool help = false;
@@ -446,7 +527,6 @@ QDict *keyval_parse(const char *params, const char *implied_key,
while (*s) {
s = keyval_parse_one(qdict, s, implied_key, &help, errp);
if (!s) {
- qobject_unref(qdict);
return NULL;
}
implied_key = NULL;
@@ -456,15 +536,42 @@ QDict *keyval_parse(const char *params, const char *implied_key,
*p_help = help;
} else if (help) {
error_setg(errp, "Help is not available for this option");
- qobject_unref(qdict);
return NULL;
}
listified = keyval_listify(qdict, NULL, errp);
if (!listified) {
- qobject_unref(qdict);
return NULL;
}
assert(listified == QOBJECT(qdict));
return qdict;
}
+
+/*
+ * Parse @params in QEMU's traditional KEY=VALUE,... syntax.
+ *
+ * If @implied_key, the first KEY= can be omitted. @implied_key is
+ * implied then, and VALUE can't be empty or contain ',' or '='.
+ *
+ * A parameter "help" or "?" without a value isn't added to the
+ * resulting dictionary, but instead is interpreted as help request.
+ * All other options are parsed and returned normally so that context
+ * specific help can be printed.
+ *
+ * If @p_help is not NULL, store whether help is requested there.
+ * If @p_help is NULL and help is requested, fail.
+ *
+ * On success, return a dictionary of the parsed keys and values.
+ * On failure, store an error through @errp and return NULL.
+ */
+QDict *keyval_parse(const char *params, const char *implied_key,
+ bool *p_help, Error **errp)
+{
+ QDict *qdict = qdict_new();
+ QDict *ret = keyval_parse_into(qdict, params, implied_key, p_help, errp);
+
+ if (!ret) {
+ qobject_unref(qdict);
+ }
+ return ret;
+}
diff --git a/util/meson.build b/util/meson.build
index 97fad44105..0ffd7f4bde 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -1,9 +1,10 @@
-util_ss.add(dependency('threads'))
util_ss.add(files('osdep.c', 'cutils.c', 'unicode.c', 'qemu-timer-common.c'))
util_ss.add(when: 'CONFIG_ATOMIC64', if_false: files('atomic64.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('aio-posix.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('fdmon-poll.c'))
-util_ss.add(when: 'CONFIG_EPOLL_CREATE1', if_true: files('fdmon-epoll.c'))
+if config_host_data.get('CONFIG_EPOLL_CREATE1')
+ util_ss.add(files('fdmon-epoll.c'))
+endif
util_ss.add(when: ['CONFIG_LINUX_IO_URING', linux_io_uring], if_true: files('fdmon-io_uring.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('compatfd.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('event_notifier-posix.c'))
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 4944015a25..ee78e42216 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -479,19 +479,14 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
}
}
-static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value,
- bool prepend)
+static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value)
{
QemuOpt *opt = g_malloc0(sizeof(*opt));
opt->name = g_strdup(name);
opt->str = value;
opt->opts = opts;
- if (prepend) {
- QTAILQ_INSERT_HEAD(&opts->head, opt, next);
- } else {
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
- }
+ QTAILQ_INSERT_TAIL(&opts->head, opt, next);
return opt;
}
@@ -518,7 +513,7 @@ static bool opt_validate(QemuOpt *opt, Error **errp)
bool qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
Error **errp)
{
- QemuOpt *opt = opt_create(opts, name, g_strdup(value), false);
+ QemuOpt *opt = opt_create(opts, name, g_strdup(value));
if (!opt_validate(opt, errp)) {
qemu_opt_del(opt);
@@ -662,15 +657,6 @@ void qemu_opts_loc_restore(QemuOpts *opts)
loc_restore(&opts->loc);
}
-bool qemu_opts_set(QemuOptsList *list, const char *name, const char *value, Error **errp)
-{
- QemuOpts *opts;
-
- assert(list->merge_lists);
- opts = qemu_opts_create(list, NULL, 0, &error_abort);
- return qemu_opt_set(opts, name, value, errp);
-}
-
const char *qemu_opts_id(QemuOpts *opts)
{
return opts->id;
@@ -811,7 +797,7 @@ static const char *get_opt_name_value(const char *params,
}
static bool opts_do_parse(QemuOpts *opts, const char *params,
- const char *firstname, bool prepend,
+ const char *firstname,
bool warn_on_flag, bool *help_wanted, Error **errp)
{
char *option, *value;
@@ -833,7 +819,7 @@ static bool opts_do_parse(QemuOpts *opts, const char *params,
continue;
}
- opt = opt_create(opts, option, value, prepend);
+ opt = opt_create(opts, option, value);
g_free(option);
if (!opt_validate(opt, errp)) {
qemu_opt_del(opt);
@@ -889,11 +875,11 @@ bool has_help_option(const char *params)
bool qemu_opts_do_parse(QemuOpts *opts, const char *params,
const char *firstname, Error **errp)
{
- return opts_do_parse(opts, params, firstname, false, false, NULL, errp);
+ return opts_do_parse(opts, params, firstname, false, NULL, errp);
}
static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
- bool permit_abbrev, bool defaults,
+ bool permit_abbrev,
bool warn_on_flag, bool *help_wanted, Error **errp)
{
const char *firstname;
@@ -903,21 +889,13 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
assert(!permit_abbrev || list->implied_opt_name);
firstname = permit_abbrev ? list->implied_opt_name : NULL;
- /*
- * This code doesn't work for defaults && !list->merge_lists: when
- * params has no id=, and list has an element with !opts->id, it
- * appends a new element instead of returning the existing opts.
- * However, we got no use for this case. Guard against possible
- * (if unlikely) future misuse:
- */
- assert(!defaults || list->merge_lists);
opts = qemu_opts_create(list, id, !list->merge_lists, errp);
g_free(id);
if (opts == NULL) {
return NULL;
}
- if (!opts_do_parse(opts, params, firstname, defaults,
+ if (!opts_do_parse(opts, params, firstname,
warn_on_flag, help_wanted, errp)) {
qemu_opts_del(opts);
return NULL;
@@ -936,7 +914,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
bool permit_abbrev, Error **errp)
{
- return opts_parse(list, params, permit_abbrev, false, false, NULL, errp);
+ return opts_parse(list, params, permit_abbrev, false, NULL, errp);
}
/**
@@ -954,7 +932,7 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
QemuOpts *opts;
bool help_wanted = false;
- opts = opts_parse(list, params, permit_abbrev, false, true,
+ opts = opts_parse(list, params, permit_abbrev, true,
opts_accepts_any(list) ? NULL : &help_wanted,
&err);
if (!opts) {
@@ -968,15 +946,6 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
return opts;
}
-void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
- int permit_abbrev)
-{
- QemuOpts *opts;
-
- opts = opts_parse(list, params, permit_abbrev, true, false, NULL, NULL);
- assert(opts);
-}
-
static bool qemu_opts_from_qdict_entry(QemuOpts *opts,
const QDictEntry *entry,
Error **errp)