diff options
67 files changed, 1013 insertions, 874 deletions
diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml index bd6473a75a..66547b6683 100644 --- a/.gitlab-ci.d/crossbuilds.yml +++ b/.gitlab-ci.d/crossbuilds.yml @@ -7,10 +7,10 @@ - cd build - PKG_CONFIG_PATH=$PKG_CONFIG_PATH ../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-user - --target-list-exclude="aarch64-softmmu i386-softmmu microblaze-softmmu - mips-softmmu mipsel-softmmu mips64-softmmu ppc64-softmmu sh4-softmmu - xtensa-softmmu" - - make -j$(expr $(nproc) + 1) all check-build + --target-list-exclude="arm-softmmu cris-softmmu i386-softmmu + microblaze-softmmu mips-softmmu mipsel-softmmu mips64-softmmu + ppc-softmmu sh4-softmmu xtensa-softmmu" + - make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS # Job to cross-build specific accelerators. # @@ -37,7 +37,7 @@ - cd build - PKG_CONFIG_PATH=$PKG_CONFIG_PATH ../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-system - - make -j$(expr $(nproc) + 1) all check-build + - make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS cross-armel-system: extends: .cross_system_build_job @@ -69,6 +69,18 @@ cross-arm64-user: variables: IMAGE: debian-arm64-cross +cross-i386-system: + extends: .cross_system_build_job + variables: + IMAGE: fedora-i386-cross + MAKE_CHECK_ARGS: check-qtest + +cross-i386-user: + extends: .cross_user_build_job + variables: + IMAGE: fedora-i386-cross + MAKE_CHECK_ARGS: check + cross-mips-system: extends: .cross_system_build_job variables: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bf3df843e2..01c9e46410 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -519,6 +519,20 @@ build-trace-ust-system: IMAGE: ubuntu2004 CONFIGURE_ARGS: --enable-trace-backends=ust --target-list=x86_64-softmmu +# Check our reduced build configurations +build-without-default-devices: + <<: *native_build_job_definition + variables: + IMAGE: centos8 + CONFIGURE_ARGS: --without-default-devices --disable-user + +build-without-default-features: + <<: *native_build_job_definition + variables: + IMAGE: debian-amd64 + CONFIGURE_ARGS: --without-default-features --disable-user + MAKE_CHECK_ARGS: check-unit + check-patch: stage: build image: $CI_REGISTRY_IMAGE/qemu/centos8:latest diff --git a/.travis.yml b/.travis.yml index d01714a5ae..f2a101936c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -205,14 +205,6 @@ jobs: - ${SRC_DIR}/scripts/travis/coverage-summary.sh - # We manually include builds which we disable "make check" for - - name: "GCC without-default-devices (softmmu)" - env: - - CONFIG="--without-default-devices --disable-user" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-default" - - TEST_CMD="" - - # Using newer GCC with sanitizers - name: "GCC9 with sanitizers (softmmu)" dist: bionic diff --git a/MAINTAINERS b/MAINTAINERS index 171e7047aa..4be087b88e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -119,6 +119,8 @@ F: softmmu/cpus.c F: cpus-common.c F: accel/tcg/ F: accel/stubs/tcg-stub.c +F: util/cacheinfo.c +F: util/cacheflush.c F: scripts/decodetree.py F: docs/devel/decodetree.rst F: include/exec/cpu*.h @@ -133,6 +133,7 @@ Makefile.ninja: build.ninja # A separate rule is needed for Makefile dependencies to avoid -n build.ninja: build.ninja.stamp +$(build-files): build.ninja.stamp: meson.stamp $(build-files) $(NINJA) $(if $V,-v,) build.ninja && touch $@ endif diff --git a/accel/Kconfig b/accel/Kconfig index 2ad94a3839..461104c771 100644 --- a/accel/Kconfig +++ b/accel/Kconfig @@ -1,3 +1,12 @@ +config WHPX + bool + +config HAX + bool + +config HVF + bool + config TCG bool diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c index e4bbf997aa..8c18d3eabd 100644 --- a/accel/stubs/tcg-stub.c +++ b/accel/stubs/tcg-stub.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "tcg/tcg.h" #include "exec/exec-all.h" void tb_flush(CPUState *cpu) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 8689c54499..fa325bb3d8 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -26,6 +26,7 @@ #include "exec/exec-all.h" #include "tcg/tcg.h" #include "qemu/atomic.h" +#include "qemu/compiler.h" #include "sysemu/qtest.h" #include "qemu/timer.h" #include "qemu/rcu.h" @@ -144,6 +145,16 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) #endif /* CONFIG USER ONLY */ /* Execute a TB, and fix up the CPU state afterwards if necessary */ +/* + * Disable CFI checks. + * TCG creates binary blobs at runtime, with the transformed code. + * A TB is a blob of binary code, created at runtime and called with an + * indirect function call. Since such function did not exist at compile time, + * the CFI runtime has no way to verify its signature and would fail. + * TCG is not considered a security-sensitive part of QEMU so this does not + * affect the impact of CFI in environment with high security requirements + */ +QEMU_DISABLE_CFI static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) { CPUArchState *env = cpu->env_ptr; diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 42ab79c1a5..ced3dc077e 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -33,7 +33,7 @@ #include "exec/helper-proto.h" #include "qemu/atomic.h" #include "qemu/atomic128.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "trace/trace-root.h" #include "trace/mem.h" #ifdef CONFIG_PLUGIN diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index b7d50a73d4..a1803a1026 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -49,7 +49,7 @@ #include "exec/cputlb.h" #include "exec/tb-hash.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "qemu/bitmap.h" #include "qemu/error-report.h" #include "qemu/qemu-print.h" diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 293ee86ea4..1215b55ca0 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -23,7 +23,7 @@ #include "tcg/tcg.h" #include "qemu/bitops.h" #include "exec/cpu_ldst.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "exec/helper-proto.h" #include "qemu/atomic128.h" #include "trace/trace-root.h" diff --git a/block/curl.c b/block/curl.c index d24a4c5897..4ff895df8f 100644 --- a/block/curl.c +++ b/block/curl.c @@ -37,26 +37,6 @@ // #define DEBUG_VERBOSE -#if LIBCURL_VERSION_NUM >= 0x071000 -/* The multi interface timer callback was introduced in 7.16.0 */ -#define NEED_CURL_TIMER_CALLBACK -#define HAVE_SOCKET_ACTION -#endif - -#ifndef HAVE_SOCKET_ACTION -/* If curl_multi_socket_action isn't available, define it statically here in - * terms of curl_multi_socket. Note that ev_bitmask will be ignored, which is - * less efficient but still safe. */ -static CURLMcode __curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t sockfd, - int ev_bitmask, - int *running_handles) -{ - return curl_multi_socket(multi_handle, sockfd, running_handles); -} -#define curl_multi_socket_action __curl_multi_socket_action -#endif - #define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \ CURLPROTO_FTP | CURLPROTO_FTPS) @@ -140,7 +120,6 @@ typedef struct BDRVCURLState { static void curl_clean_state(CURLState *s); static void curl_multi_do(void *arg); -#ifdef NEED_CURL_TIMER_CALLBACK /* Called from curl_multi_do_locked, with s->mutex held. */ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque) { @@ -156,7 +135,6 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque) } return 0; } -#endif /* Called from curl_multi_do_locked, with s->mutex held. */ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, @@ -433,7 +411,6 @@ static void curl_multi_do(void *arg) static void curl_multi_timeout_do(void *arg) { -#ifdef NEED_CURL_TIMER_CALLBACK BDRVCURLState *s = (BDRVCURLState *)arg; int running; @@ -446,9 +423,6 @@ static void curl_multi_timeout_do(void *arg) curl_multi_check_completion(s); qemu_mutex_unlock(&s->mutex); -#else - abort(); -#endif } /* Called with s->mutex held. */ @@ -598,10 +572,8 @@ static void curl_attach_aio_context(BlockDriverState *bs, s->multi = curl_multi_init(); s->aio_context = new_context; curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb); -#ifdef NEED_CURL_TIMER_CALLBACK curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s); curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb); -#endif } static QemuOptsList runtime_opts = { diff --git a/block/meson.build b/block/meson.build index 7595d86c41..d44c92ab04 100644 --- a/block/meson.build +++ b/block/meson.build @@ -60,7 +60,7 @@ block_ss.add(when: 'CONFIG_QED', if_true: files( block_ss.add(when: [libxml2, 'CONFIG_PARALLELS'], if_true: files('parallels.c')) block_ss.add(when: 'CONFIG_WIN32', if_true: files('file-win32.c', 'win32-aio.c')) block_ss.add(when: 'CONFIG_POSIX', if_true: [files('file-posix.c'), coref, iokit]) -block_ss.add(when: 'CONFIG_LIBISCSI', if_true: files('iscsi-opts.c')) +block_ss.add(when: libiscsi, if_true: files('iscsi-opts.c')) block_ss.add(when: 'CONFIG_LINUX', if_true: files('nvme.c')) block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c')) block_ss.add(when: 'CONFIG_SHEEPDOG', if_true: files('sheepdog.c')) @@ -71,14 +71,14 @@ block_modules = {} modsrc = [] foreach m : [ - ['CONFIG_CURL', 'curl', [curl, glib], 'curl.c'], - ['CONFIG_GLUSTERFS', 'gluster', glusterfs, 'gluster.c'], - ['CONFIG_LIBISCSI', 'iscsi', libiscsi, 'iscsi.c'], - ['CONFIG_LIBNFS', 'nfs', libnfs, 'nfs.c'], - ['CONFIG_LIBSSH', 'ssh', libssh, 'ssh.c'], - ['CONFIG_RBD', 'rbd', rbd, 'rbd.c'], + [curl, 'curl', [curl, glib], 'curl.c'], + [glusterfs, 'gluster', glusterfs, 'gluster.c'], + [libiscsi, 'iscsi', libiscsi, 'iscsi.c'], + [libnfs, 'nfs', libnfs, 'nfs.c'], + [libssh, 'ssh', libssh, 'ssh.c'], + [rbd, 'rbd', rbd, 'rbd.c'], ] - if config_host.has_key(m[0]) + if m[0].found() if enable_modules modsrc += files(m[3]) endif @@ -91,10 +91,10 @@ endforeach # those are not exactly regular block modules, so treat them apart if 'CONFIG_DMG' in config_host foreach m : [ - ['CONFIG_LZFSE', 'dmg-lzfse', liblzfse, 'dmg-lzfse.c'], - ['CONFIG_BZIP2', 'dmg-bz2', [glib, libbzip2], 'dmg-bz2.c'] + [liblzfse, 'dmg-lzfse', liblzfse, 'dmg-lzfse.c'], + [libbzip2, 'dmg-bz2', [glib, libbzip2], 'dmg-bz2.c'] ] - if config_host.has_key(m[0]) + if m[0].found() module_ss = ss.source_set() module_ss.add(when: m[2], if_true: files(m[3])) block_modules += {m[1] : module_ss} diff --git a/chardev/meson.build b/chardev/meson.build index 4e19722c5e..32377af383 100644 --- a/chardev/meson.build +++ b/chardev/meson.build @@ -29,7 +29,7 @@ softmmu_ss.add(files('msmouse.c', 'wctablet.c', 'testdev.c')) chardev_modules = {} -if config_host.has_key('CONFIG_BRLAPI') +if brlapi.found() module_ss = ss.source_set() module_ss.add(when: [brlapi], if_true: [files('baum.c'), pixman]) chardev_modules += { 'baum': module_ss } @@ -242,6 +242,7 @@ host_cc="cc" audio_win_int="" libs_qga="" debug_info="yes" +lto="false" stack_protector="" safe_stack="" use_containers="yes" @@ -293,8 +294,19 @@ unset target_list_exclude # Distributions want to ensure that several features are compiled in, and it # is impossible without a --enable-foo that exits if a feature is not found. -brlapi="" -curl="" +default_feature="" +# parse CC options second +for opt do + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') + case "$opt" in + --without-default-features) + default_feature="no" + ;; + esac +done + +brlapi="auto" +curl="auto" iconv="auto" curses="auto" docs="auto" @@ -303,52 +315,51 @@ netmap="no" sdl="auto" sdl_image="auto" virtiofsd="auto" -virtfs="" +virtfs="auto" libudev="auto" mpath="auto" vnc="enabled" sparse="auto" -vde="" +vde="$default_feature" vnc_sasl="auto" vnc_jpeg="auto" vnc_png="auto" xkbcommon="auto" -xen="" -xen_ctrl_version="" +xen="$default_feature" +xen_ctrl_version="$default_feature" xen_pci_passthrough="auto" -linux_aio="" -linux_io_uring="" -cap_ng="" -attr="" -libattr="" -xfs="" +linux_aio="$default_feature" +linux_io_uring="$default_feature" +cap_ng="auto" +attr="auto" +xfs="$default_feature" tcg="enabled" -membarrier="" -vhost_net="" -vhost_crypto="" -vhost_scsi="" -vhost_vsock="" +membarrier="$default_feature" +vhost_net="$default_feature" +vhost_crypto="$default_feature" +vhost_scsi="$default_feature" +vhost_vsock="$default_feature" vhost_user="no" vhost_user_blk_server="auto" -vhost_user_fs="" +vhost_user_fs="$default_feature" kvm="auto" hax="auto" hvf="auto" whpx="auto" -rdma="" -pvrdma="" +rdma="$default_feature" +pvrdma="$default_feature" gprof="no" debug_tcg="no" debug="no" sanitizers="no" tsan="no" -fortify_source="" +fortify_source="$default_feature" strip_opt="yes" tcg_interpreter="no" bigendian="no" mingw32="no" gcov="no" -EXESUF="" +EXESUF="$default_feature" HOST_DSOSUF=".so" modules="no" module_upgrades="no" @@ -370,92 +381,87 @@ pie="" qom_cast_debug="yes" trace_backends="log" trace_file="trace" -spice="" -rbd="" -smartcard="" +spice="$default_feature" +rbd="auto" +smartcard="$default_feature" u2f="auto" -libusb="" -usb_redir="" -opengl="" +libusb="$default_feature" +usb_redir="$default_feature" +opengl="$default_feature" opengl_dmabuf="no" cpuid_h="no" -avx2_opt="" +avx2_opt="$default_feature" capstone="auto" -lzo="" -snappy="" -bzip2="" -lzfse="" -zstd="" -guest_agent="" +lzo="auto" +snappy="auto" +bzip2="auto" +lzfse="auto" +zstd="auto" +guest_agent="$default_feature" guest_agent_with_vss="no" guest_agent_ntddscsi="no" -guest_agent_msi="" -vss_win32_sdk="" +guest_agent_msi="$default_feature" +vss_win32_sdk="$default_feature" win_sdk="no" -want_tools="" -libiscsi="" -libnfs="" +want_tools="$default_feature" +libiscsi="auto" +libnfs="auto" coroutine="" -coroutine_pool="" +coroutine_pool="$default_feature" debug_stack_usage="no" crypto_afalg="no" -seccomp="" -glusterfs="" -glusterfs_xlator_opt="no" -glusterfs_discard="no" -glusterfs_fallocate="no" -glusterfs_zerofill="no" -glusterfs_ftruncate_has_stat="no" -glusterfs_iocb_has_stat="no" -gtk="" +cfi="false" +cfi_debug="false" +seccomp="auto" +glusterfs="auto" +gtk="$default_feature" gtk_gl="no" tls_priority="NORMAL" -gnutls="" -nettle="" +gnutls="$default_feature" +nettle="$default_feature" nettle_xts="no" -gcrypt="" +gcrypt="$default_feature" gcrypt_hmac="no" gcrypt_xts="no" qemu_private_xts="yes" -auth_pam="" -vte="" -virglrenderer="" -tpm="" -libssh="" -live_block_migration="yes" -numa="" +auth_pam="$default_feature" +vte="$default_feature" +virglrenderer="$default_feature" +tpm="$default_feature" +libssh="$default_feature" +live_block_migration=${default_feature:-yes} +numa="$default_feature" tcmalloc="no" jemalloc="no" -replication="yes" -bochs="yes" -cloop="yes" -dmg="yes" -qcow1="yes" -vdi="yes" -vvfat="yes" -qed="yes" -parallels="yes" +replication=${default_feature:-yes} +bochs=${default_feature:-yes} +cloop=${default_feature:-yes} +dmg=${default_feature:-yes} +qcow1=${default_feature:-yes} +vdi=${default_feature:-yes} +vvfat=${default_feature:-yes} +qed=${default_feature:-yes} +parallels=${default_feature:-yes} sheepdog="no" -libxml2="" +libxml2="$default_feature" debug_mutex="no" -libpmem="" -default_devices="yes" +libpmem="$default_feature" +default_devices="true" plugins="no" fuzzing="no" rng_none="no" -secret_keyring="" -libdaxctl="" +secret_keyring="$default_feature" +libdaxctl="$default_feature" meson="" ninja="" skip_meson=no -gettext="" +gettext="auto" fuse="auto" fuse_lseek="auto" -bogus_os="no" malloc_trim="auto" -# parse CC options first +# parse CC options second for opt do optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') case "$opt" in @@ -605,7 +611,6 @@ else # might be going to just print the --help text, or it might # be the result of a missing compiler. targetos='bogus' - bogus_os='yes' fi # Some host OSes need non-standard checks for which CPU to use. @@ -798,7 +803,7 @@ Linux) audio_possible_drivers="oss alsa sdl pa" linux="yes" linux_user="yes" - vhost_user="yes" + vhost_user=${default_feature:-yes} ;; esac @@ -938,9 +943,11 @@ for opt do ;; --with-trace-file=*) trace_file="$optarg" ;; - --with-default-devices) default_devices="yes" + --with-default-devices) default_devices="true" ;; - --without-default-devices) default_devices="no" + --without-default-devices) default_devices="false" + ;; + --without-default-features) # processed above ;; --enable-gprof) gprof="yes" ;; @@ -996,9 +1003,9 @@ for opt do ;; --enable-qom-cast-debug) qom_cast_debug="yes" ;; - --disable-virtfs) virtfs="no" + --disable-virtfs) virtfs="disabled" ;; - --enable-virtfs) virtfs="yes" + --enable-virtfs) virtfs="enabled" ;; --disable-libudev) libudev="disabled" ;; @@ -1016,9 +1023,9 @@ for opt do ;; --enable-vnc) vnc="enabled" ;; - --disable-gettext) gettext="false" + --disable-gettext) gettext="disabled" ;; - --enable-gettext) gettext="true" + --enable-gettext) gettext="enabled" ;; --oss-lib=*) oss_lib="$optarg" ;; @@ -1068,6 +1075,8 @@ for opt do ;; --disable-slirp) slirp="disabled" ;; + --enable-slirp) slirp="enabled" + ;; --enable-slirp=git) slirp="internal" ;; --enable-slirp=system) slirp="system" @@ -1088,9 +1097,9 @@ for opt do ;; --enable-xen-pci-passthrough) xen_pci_passthrough="enabled" ;; - --disable-brlapi) brlapi="no" + --disable-brlapi) brlapi="disabled" ;; - --enable-brlapi) brlapi="yes" + --enable-brlapi) brlapi="enabled" ;; --disable-kvm) kvm="disabled" ;; @@ -1112,9 +1121,9 @@ for opt do ;; --enable-tcg-interpreter) tcg_interpreter="yes" ;; - --disable-cap-ng) cap_ng="no" + --disable-cap-ng) cap_ng="disabled" ;; - --enable-cap-ng) cap_ng="yes" + --enable-cap-ng) cap_ng="enabled" ;; --disable-tcg) tcg="disabled" ;; @@ -1128,13 +1137,13 @@ for opt do ;; --enable-spice) spice="yes" ;; - --disable-libiscsi) libiscsi="no" + --disable-libiscsi) libiscsi="disabled" ;; - --enable-libiscsi) libiscsi="yes" + --enable-libiscsi) libiscsi="enabled" ;; - --disable-libnfs) libnfs="no" + --disable-libnfs) libnfs="disabled" ;; - --enable-libnfs) libnfs="yes" + --enable-libnfs) libnfs="enabled" ;; --enable-profiler) profiler="yes" ;; @@ -1169,6 +1178,10 @@ for opt do ;; --disable-werror) werror="no" ;; + --enable-lto) lto="true" + ;; + --disable-lto) lto="false" + ;; --enable-stack-protector) stack_protector="yes" ;; --disable-stack-protector) stack_protector="no" @@ -1177,6 +1190,16 @@ for opt do ;; --disable-safe-stack) safe_stack="no" ;; + --enable-cfi) + cfi="true"; + lto="true"; + ;; + --disable-cfi) cfi="false" + ;; + --enable-cfi-debug) cfi_debug="true" + ;; + --disable-cfi-debug) cfi_debug="false" + ;; --disable-curses) curses="disabled" ;; --enable-curses) curses="enabled" @@ -1185,9 +1208,9 @@ for opt do ;; --enable-iconv) iconv="enabled" ;; - --disable-curl) curl="no" + --disable-curl) curl="disabled" ;; - --enable-curl) curl="yes" + --enable-curl) curl="enabled" ;; --disable-fdt) fdt="disabled" ;; @@ -1205,9 +1228,9 @@ for opt do ;; --enable-linux-io-uring) linux_io_uring="yes" ;; - --disable-attr) attr="no" + --disable-attr) attr="disabled" ;; - --enable-attr) attr="yes" + --enable-attr) attr="enabled" ;; --disable-membarrier) membarrier="no" ;; @@ -1261,9 +1284,9 @@ for opt do ;; --enable-opengl) opengl="yes" ;; - --disable-rbd) rbd="no" + --disable-rbd) rbd="disabled" ;; - --enable-rbd) rbd="yes" + --enable-rbd) rbd="enabled" ;; --disable-xfsctl) xfs="no" ;; @@ -1287,25 +1310,25 @@ for opt do ;; --disable-zlib-test) ;; - --disable-lzo) lzo="no" + --disable-lzo) lzo="disabled" ;; - --enable-lzo) lzo="yes" + --enable-lzo) lzo="enabled" ;; - --disable-snappy) snappy="no" + --disable-snappy) snappy="disabled" ;; - --enable-snappy) snappy="yes" + --enable-snappy) snappy="enabled" ;; - --disable-bzip2) bzip2="no" + --disable-bzip2) bzip2="disabled" ;; - --enable-bzip2) bzip2="yes" + --enable-bzip2) bzip2="enabled" ;; - --enable-lzfse) lzfse="yes" + --enable-lzfse) lzfse="enabled" ;; - --disable-lzfse) lzfse="no" + --disable-lzfse) lzfse="disabled" ;; - --disable-zstd) zstd="no" + --disable-zstd) zstd="disabled" ;; - --enable-zstd) zstd="yes" + --enable-zstd) zstd="enabled" ;; --enable-guest-agent) guest_agent="yes" ;; @@ -1331,11 +1354,11 @@ for opt do ;; --disable-tools) want_tools="no" ;; - --enable-seccomp) seccomp="yes" + --enable-seccomp) seccomp="enabled" ;; - --disable-seccomp) seccomp="no" + --disable-seccomp) seccomp="disabled" ;; - --disable-glusterfs) glusterfs="no" + --disable-glusterfs) glusterfs="disabled" ;; --disable-avx2) avx2_opt="no" ;; @@ -1346,7 +1369,7 @@ for opt do --enable-avx512f) avx512f_opt="yes" ;; - --enable-glusterfs) glusterfs="yes" + --enable-glusterfs) glusterfs="enabled" ;; --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane) echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2 @@ -1706,6 +1729,10 @@ Advanced options (experts only): --efi-aarch64=PATH PATH of efi file to use for aarch64 VMs. --with-suffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir/docdir [$qemu_suffix] --with-pkgversion=VERS use specified string as sub-version of the package + --without-default-features default all --enable-* options to "disabled" + --without-default-devices do not include any device that is not needed to + start the emulator (only use if you are including + desired devices in default-configs/devices/) --enable-debug enable common debug build options --enable-sanitizers enable default sanitizers --enable-tsan enable thread sanitizer @@ -1747,7 +1774,8 @@ Advanced options (experts only): --gdb=GDB-path gdb to use for gdbstub tests [$gdb_bin] Optional features, enabled with --enable-FEATURE and -disabled with --disable-FEATURE, default is enabled if available: +disabled with --disable-FEATURE, default is enabled if available +(unless built with --without-default-features): system all system emulation targets user supported user emulation targets @@ -1761,10 +1789,17 @@ disabled with --disable-FEATURE, default is enabled if available: module-upgrades try to load modules from alternate paths for upgrades debug-tcg TCG debugging (default is disabled) debug-info debugging information + lto Enable Link-Time Optimization. sparse sparse checker safe-stack SafeStack Stack Smash Protection. Depends on clang/llvm >= 3.7 and requires coroutine backend ucontext. - + cfi Enable Control-Flow Integrity for indirect function calls. + In case of a cfi violation, QEMU is terminated with SIGILL + Depends on lto and is incompatible with modules + Automatically enables Link-Time Optimization (lto) + cfi-debug In case of a cfi violation, a message containing the line that + triggered the error is written to stderr. After the error, + QEMU is still terminated with SIGILL gnutls GNUTLS cryptography support nettle nettle cryptography support gcrypt libgcrypt cryptography support @@ -1972,7 +2007,7 @@ if test -z "$werror" ; then fi fi -if test "$bogus_os" = "yes"; then +if test "$targetos" = "bogus"; then # Now that we know that we're not printing the help and that # the compiler works (so the results of the check_defines we used # to identify the OS are reliable), if we didn't recognize the @@ -2422,115 +2457,6 @@ EOF fi ########################################## -# lzo check - -if test "$lzo" != "no" ; then - cat > $TMPC << EOF -#include <lzo/lzo1x.h> -int main(void) { lzo_version(); return 0; } -EOF - if compile_prog "" "-llzo2" ; then - lzo_libs="-llzo2" - lzo="yes" - else - if test "$lzo" = "yes"; then - feature_not_found "liblzo2" "Install liblzo2 devel" - fi - lzo="no" - fi -fi - -########################################## -# snappy check - -if test "$snappy" != "no" ; then - cat > $TMPC << EOF -#include <snappy-c.h> -int main(void) { snappy_max_compressed_length(4096); return 0; } -EOF - if compile_prog "" "-lsnappy" ; then - snappy_libs='-lsnappy' - snappy="yes" - else - if test "$snappy" = "yes"; then - feature_not_found "libsnappy" "Install libsnappy devel" - fi - snappy="no" - fi -fi - -########################################## -# bzip2 check - -if test "$bzip2" != "no" ; then - cat > $TMPC << EOF -#include <bzlib.h> -int main(void) { BZ2_bzlibVersion(); return 0; } -EOF - if compile_prog "" "-lbz2" ; then - bzip2="yes" - else - if test "$bzip2" = "yes"; then - feature_not_found "libbzip2" "Install libbzip2 devel" - fi - bzip2="no" - fi -fi - -########################################## -# lzfse check - -if test "$lzfse" != "no" ; then - cat > $TMPC << EOF -#include <lzfse.h> -int main(void) { lzfse_decode_scratch_size(); return 0; } -EOF - if compile_prog "" "-llzfse" ; then - lzfse="yes" - else - if test "$lzfse" = "yes"; then - feature_not_found "lzfse" "Install lzfse devel" - fi - lzfse="no" - fi -fi - -########################################## -# zstd check - -if test "$zstd" != "no" ; then - libzstd_minver="1.4.0" - if $pkg_config --atleast-version=$libzstd_minver libzstd ; then - zstd_cflags="$($pkg_config --cflags libzstd)" - zstd_libs="$($pkg_config --libs libzstd)" - zstd="yes" - else - if test "$zstd" = "yes" ; then - feature_not_found "libzstd" "Install libzstd devel" - fi - zstd="no" - fi -fi - -########################################## -# libseccomp check - -if test "$seccomp" != "no" ; then - libseccomp_minver="2.3.0" - if $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then - seccomp_cflags="$($pkg_config --cflags libseccomp)" - seccomp_libs="$($pkg_config --libs libseccomp)" - seccomp="yes" - else - if test "$seccomp" = "yes" ; then - feature_not_found "libseccomp" \ - "Install libseccomp devel >= $libseccomp_minver" - fi - seccomp="no" - fi -fi - -########################################## # xen probe if test "$xen" != "disabled" ; then @@ -2836,31 +2762,6 @@ EOF fi fi -if test "$xen_pci_passthrough" != "disabled"; then - if test "$xen" = "enabled" && test "$linux" = "yes"; then - xen_pci_passthrough=enabled - else - if test "$xen_pci_passthrough" = "enabled"; then - error_exit "User requested feature Xen PCI Passthrough" \ - " but this feature requires /sys from Linux" - fi - xen_pci_passthrough=disabled - fi -fi - -########################################## -# gettext probe -if test "$gettext" != "false" ; then - if has xgettext; then - gettext=true - else - if test "$gettext" = "true" ; then - feature_not_found "gettext" "Install xgettext binary" - fi - gettext=false - fi -fi - ########################################## # X11 probe if $pkg_config --exists "x11"; then @@ -3291,28 +3192,6 @@ EOF fi ########################################## -# libcap-ng library probe -if test "$cap_ng" != "no" ; then - cap_libs="-lcap-ng" - cat > $TMPC << EOF -#include <cap-ng.h> -int main(void) -{ - capng_capability_to_name(CAPNG_EFFECTIVE); - return 0; -} -EOF - if compile_prog "" "$cap_libs" ; then - cap_ng=yes - else - if test "$cap_ng" = "yes" ; then - feature_not_found "cap_ng" "Install libcap-ng devel" - fi - cap_ng=no - fi -fi - -########################################## # Sound support libraries probe audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/,/ /g') @@ -3408,50 +3287,6 @@ for drv in $audio_drv_list; do done ########################################## -# BrlAPI probe - -if test "$brlapi" != "no" ; then - brlapi_libs="-lbrlapi" - cat > $TMPC << EOF -#include <brlapi.h> -#include <stddef.h> -int main( void ) { return brlapi__openConnection (NULL, NULL, NULL); } -EOF - if compile_prog "" "$brlapi_libs" ; then - brlapi=yes - else - if test "$brlapi" = "yes" ; then - feature_not_found "brlapi" "Install brlapi devel" - fi - brlapi=no - fi -fi - -########################################## -# curl probe -if test "$curl" != "no" ; then - if $pkg_config libcurl --exists; then - curlconfig="$pkg_config libcurl" - else - curlconfig=curl-config - fi - cat > $TMPC << EOF -#include <curl/curl.h> -int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; } -EOF - curl_cflags=$($curlconfig --cflags 2>/dev/null) - curl_libs=$($curlconfig --libs 2>/dev/null) - if compile_prog "$curl_cflags" "$curl_libs" ; then - curl=yes - else - if test "$curl" = "yes" ; then - feature_not_found "curl" "Install libcurl devel" - fi - curl=no - fi -fi # test "$curl" - -########################################## # glib support probe glib_req_ver=2.48 @@ -3658,29 +3493,6 @@ if compile_prog "" "$pthread_lib" ; then fi ########################################## -# rbd probe -if test "$rbd" != "no" ; then - cat > $TMPC <<EOF -#include <stdio.h> -#include <rbd/librbd.h> -int main(void) { - rados_t cluster; - rados_create(&cluster, NULL); - return 0; -} -EOF - rbd_libs="-lrbd -lrados" - if compile_prog "" "$rbd_libs" ; then - rbd=yes - else - if test "$rbd" = "yes" ; then - feature_not_found "rados block device" "Install librbd/ceph devel" - fi - rbd=no - fi -fi - -########################################## # libssh probe if test "$libssh" != "no" ; then if $pkg_config --exists libssh; then @@ -3763,36 +3575,6 @@ elif test "$tpm" = "yes"; then fi ########################################## -# attr probe - -libattr_libs= -if test "$attr" != "no" ; then - cat > $TMPC <<EOF -#include <stdio.h> -#include <sys/types.h> -#ifdef CONFIG_LIBATTR -#include <attr/xattr.h> -#else -#include <sys/xattr.h> -#endif -int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; } -EOF - if compile_prog "" "" ; then - attr=yes - # Older distros have <attr/xattr.h>, and need -lattr: - elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then - attr=yes - libattr_libs="-lattr" - libattr=yes - else - if test "$attr" = "yes" ; then - feature_not_found "ATTR" "Install libc6 or libattr devel" - fi - attr=no - fi -fi - -########################################## # iovec probe cat > $TMPC <<EOF #include <sys/types.h> @@ -3897,64 +3679,6 @@ if test "$libxml2" != "no" ; then fi fi -########################################## -# glusterfs probe -if test "$glusterfs" != "no" ; then - if $pkg_config --atleast-version=3 glusterfs-api; then - glusterfs="yes" - glusterfs_cflags=$($pkg_config --cflags glusterfs-api) - glusterfs_libs=$($pkg_config --libs glusterfs-api) - if $pkg_config --atleast-version=4 glusterfs-api; then - glusterfs_xlator_opt="yes" - fi - if $pkg_config --atleast-version=5 glusterfs-api; then - glusterfs_discard="yes" - fi - if $pkg_config --atleast-version=6 glusterfs-api; then - glusterfs_fallocate="yes" - glusterfs_zerofill="yes" - fi - cat > $TMPC << EOF -#include <glusterfs/api/glfs.h> - -int -main(void) -{ - /* new glfs_ftruncate() passes two additional args */ - return glfs_ftruncate(NULL, 0, NULL, NULL); -} -EOF - if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then - glusterfs_ftruncate_has_stat="yes" - fi - cat > $TMPC << EOF -#include <glusterfs/api/glfs.h> - -/* new glfs_io_cbk() passes two additional glfs_stat structs */ -static void -glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data) -{} - -int -main(void) -{ - glfs_io_cbk iocb = &glusterfs_iocb; - iocb(NULL, 0 , NULL, NULL, NULL); - return 0; -} -EOF - if compile_prog "$glusterfs_cflags" "$glusterfs_libs" ; then - glusterfs_iocb_has_stat="yes" - fi - else - if test "$glusterfs" = "yes" ; then - feature_not_found "GlusterFS backend support" \ - "Install glusterfs-api devel >= 3" - fi - glusterfs="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 @@ -4424,21 +4148,6 @@ if compile_prog "" "" ; then fi ########################################## -# Do we have libiscsi >= 1.9.0 -if test "$libiscsi" != "no" ; then - if $pkg_config --atleast-version=1.9.0 libiscsi; then - libiscsi="yes" - libiscsi_cflags=$($pkg_config --cflags libiscsi) - libiscsi_libs=$($pkg_config --libs libiscsi) - else - if test "$libiscsi" = "yes" ; then - feature_not_found "libiscsi" "Install libiscsi >= 1.9.0" - fi - libiscsi="no" - fi -fi - -########################################## # Do we need librt # uClibc provides 2 versions of clock_gettime(), one with realtime # support and one without. This means that the clock_gettime() don't @@ -5685,20 +5394,6 @@ if test "$have_ubsan" = "yes"; then fi ########################################## -# Do we have libnfs -if test "$libnfs" != "no" ; then - if $pkg_config --atleast-version=1.9.3 libnfs; then - libnfs="yes" - libnfs_libs=$($pkg_config --libs libnfs) - else - if test "$libnfs" = "yes" ; then - feature_not_found "libnfs" "Install libnfs devel >= 1.9.3" - fi - libnfs="no" - fi -fi - -########################################## # Exclude --warn-common with TSan to suppress warnings from the TSan libraries. if test "$solaris" = "no" && test "$tsan" = "no"; then @@ -5728,24 +5423,6 @@ if [ "$eventfd" = "yes" ]; then ivshmem=yes fi -if test "$softmmu" = yes ; then - if test "$linux" = yes; then - if test "$virtfs" != no && test "$cap_ng" = yes && test "$attr" = yes ; then - virtfs=yes - else - if test "$virtfs" = yes; then - error_exit "VirtFS requires libcap-ng devel and libattr devel" - fi - virtfs=no - fi - else - if test "$virtfs" = yes; then - error_exit "VirtFS is supported only on Linux" - fi - virtfs=no - fi -fi - # Probe for guest agent support/options if [ "$guest_agent" != "no" ]; then @@ -5895,11 +5572,6 @@ echo "GIT_UPDATE=$git_update" >> $config_host_mak echo "ARCH=$ARCH" >> $config_host_mak -if test "$default_devices" = "yes" ; then - echo "CONFIG_MINIKCONF_MODE=--defconfig" >> $config_host_mak -else - echo "CONFIG_MINIKCONF_MODE=--allnoconfig" >> $config_host_mak -fi if test "$debug_tcg" = "yes" ; then echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak fi @@ -5911,15 +5583,6 @@ if test "$bigendian" = "yes" ; then fi if test "$mingw32" = "yes" ; then echo "CONFIG_WIN32=y" >> $config_host_mak - rc_version=$(cat $source_path/VERSION) - version_major=${rc_version%%.*} - rc_version=${rc_version#*.} - version_minor=${rc_version%%.*} - rc_version=${rc_version#*.} - version_subminor=${rc_version%%.*} - version_micro=0 - echo "CONFIG_FILEVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak - echo "CONFIG_PRODUCTVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak if test "$guest_agent_with_vss" = "yes" ; then echo "CONFIG_QGA_VSS=y" >> $config_host_mak echo "QGA_VSS_PROVIDER=$qga_vss_provider" >> $config_host_mak @@ -5981,10 +5644,6 @@ fi if test "$gprof" = "yes" ; then echo "CONFIG_GPROF=y" >> $config_host_mak fi -if test "$cap_ng" = "yes" ; then - echo "CONFIG_LIBCAP_NG=y" >> $config_host_mak - echo "LIBCAP_NG_LIBS=$cap_libs" >> $config_host_mak -fi echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak for drv in $audio_drv_list; do def=CONFIG_AUDIO_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]') @@ -6120,15 +5779,6 @@ fi if test "$bswap_h" = "yes" ; then echo "CONFIG_MACHINE_BSWAP_H=y" >> $config_host_mak fi -if test "$curl" = "yes" ; then - echo "CONFIG_CURL=y" >> $config_host_mak - echo "CURL_CFLAGS=$curl_cflags" >> $config_host_mak - echo "CURL_LIBS=$curl_libs" >> $config_host_mak -fi -if test "$brlapi" = "yes" ; then - echo "CONFIG_BRLAPI=y" >> $config_host_mak - echo "BRLAPI_LIBS=$brlapi_libs" >> $config_host_mak -fi if test "$gtk" = "yes" ; then echo "CONFIG_GTK=y" >> $config_host_mak echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak @@ -6213,16 +5863,6 @@ if test "$linux_io_uring" = "yes" ; then 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 "$attr" = "yes" ; then - echo "CONFIG_ATTR=y" >> $config_host_mak - echo "LIBATTR_LIBS=$libattr_libs" >> $config_host_mak -fi -if test "$libattr" = "yes" ; then - echo "CONFIG_LIBATTR=y" >> $config_host_mak -fi -if test "$virtfs" = "yes" ; then - echo "CONFIG_VIRTFS=y" >> $config_host_mak -fi if test "$vhost_scsi" = "yes" ; then echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak fi @@ -6336,49 +5976,6 @@ if test "$avx512f_opt" = "yes" ; then echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak fi -if test "$lzo" = "yes" ; then - echo "CONFIG_LZO=y" >> $config_host_mak - echo "LZO_LIBS=$lzo_libs" >> $config_host_mak -fi - -if test "$snappy" = "yes" ; then - echo "CONFIG_SNAPPY=y" >> $config_host_mak - echo "SNAPPY_LIBS=$snappy_libs" >> $config_host_mak -fi - -if test "$bzip2" = "yes" ; then - echo "CONFIG_BZIP2=y" >> $config_host_mak - echo "BZIP2_LIBS=-lbz2" >> $config_host_mak -fi - -if test "$lzfse" = "yes" ; then - echo "CONFIG_LZFSE=y" >> $config_host_mak - echo "LZFSE_LIBS=-llzfse" >> $config_host_mak -fi - -if test "$zstd" = "yes" ; then - echo "CONFIG_ZSTD=y" >> $config_host_mak - echo "ZSTD_CFLAGS=$zstd_cflags" >> $config_host_mak - echo "ZSTD_LIBS=$zstd_libs" >> $config_host_mak -fi - -if test "$libiscsi" = "yes" ; then - echo "CONFIG_LIBISCSI=y" >> $config_host_mak - echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak - echo "LIBISCSI_LIBS=$libiscsi_libs" >> $config_host_mak -fi - -if test "$libnfs" = "yes" ; then - echo "CONFIG_LIBNFS=y" >> $config_host_mak - echo "LIBNFS_LIBS=$libnfs_libs" >> $config_host_mak -fi - -if test "$seccomp" = "yes"; then - echo "CONFIG_SECCOMP=y" >> $config_host_mak - echo "SECCOMP_CFLAGS=$seccomp_cflags" >> $config_host_mak - echo "SECCOMP_LIBS=$seccomp_libs" >> $config_host_mak -fi - # XXX: suppress that if [ "$bsd" = "yes" ] ; then echo "CONFIG_BSD=y" >> $config_host_mak @@ -6387,10 +5984,6 @@ fi if test "$qom_cast_debug" = "yes" ; then echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak fi -if test "$rbd" = "yes" ; then - echo "CONFIG_RBD=y" >> $config_host_mak - echo "RBD_LIBS=$rbd_libs" >> $config_host_mak -fi echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak if test "$coroutine_pool" = "yes" ; then @@ -6459,36 +6052,6 @@ if test "$getauxval" = "yes" ; then echo "CONFIG_GETAUXVAL=y" >> $config_host_mak fi -if test "$glusterfs" = "yes" ; then - echo "CONFIG_GLUSTERFS=y" >> $config_host_mak - echo "GLUSTERFS_CFLAGS=$glusterfs_cflags" >> $config_host_mak - echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak -fi - -if test "$glusterfs_xlator_opt" = "yes" ; then - echo "CONFIG_GLUSTERFS_XLATOR_OPT=y" >> $config_host_mak -fi - -if test "$glusterfs_discard" = "yes" ; then - echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak -fi - -if test "$glusterfs_fallocate" = "yes" ; then - echo "CONFIG_GLUSTERFS_FALLOCATE=y" >> $config_host_mak -fi - -if test "$glusterfs_zerofill" = "yes" ; then - echo "CONFIG_GLUSTERFS_ZEROFILL=y" >> $config_host_mak -fi - -if test "$glusterfs_ftruncate_has_stat" = "yes" ; then - echo "CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT=y" >> $config_host_mak -fi - -if test "$glusterfs_iocb_has_stat" = "yes" ; then - echo "CONFIG_GLUSTERFS_IOCB_HAS_STAT=y" >> $config_host_mak -fi - if test "$libssh" = "yes" ; then echo "CONFIG_LIBSSH=y" >> $config_host_mak echo "LIBSSH_CFLAGS=$libssh_cflags" >> $config_host_mak @@ -6870,13 +6433,6 @@ for rom in seabios; do echo "RANLIB=$ranlib" >> $config_mak done -# set up qemu-iotests in this build directory -iotests_common_env="tests/qemu-iotests/common.env" - -echo "# Automatically generated by configure - do not modify" > "$iotests_common_env" -echo >> "$iotests_common_env" -echo "export PYTHON='$python'" >> "$iotests_common_env" - if test "$skip_meson" = no; then cross="config-meson.cross.new" meson_quote() { @@ -6960,17 +6516,23 @@ NINJA=$ninja $meson setup \ -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \ ${staticpic:+-Db_staticpic=$staticpic} \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ + -Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \ -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \ -Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \ -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \ -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 \ - -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\ + -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 \ + -Dzstd=$zstd -Dseccomp=$seccomp -Dvirtfs=$virtfs -Dcap_ng=$cap_ng \ + -Dattr=$attr -Ddefault_devices=$default_devices \ -Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \ -Dvhost_user_blk_server=$vhost_user_blk_server \ -Dfuse=$fuse -Dfuse_lseek=$fuse_lseek \ + $(if test "$default_features" = no; then echo "-Dauto_features=disabled"; fi) \ $cross_arg \ "$PWD" "$source_path" diff --git a/contrib/elf2dmp/meson.build b/contrib/elf2dmp/meson.build index b3de173316..4d86cb390a 100644 --- a/contrib/elf2dmp/meson.build +++ b/contrib/elf2dmp/meson.build @@ -1,4 +1,4 @@ -if 'CONFIG_CURL' in config_host +if curl.found() executable('elf2dmp', files('main.c', 'addrspace.c', 'download.c', 'pdb.c', 'qemu_elf.c'), dependencies: [glib, curl], install: true) diff --git a/contrib/vhost-user-scsi/meson.build b/contrib/vhost-user-scsi/meson.build index 044c50bf43..cc893f6f20 100644 --- a/contrib/vhost-user-scsi/meson.build +++ b/contrib/vhost-user-scsi/meson.build @@ -1,4 +1,4 @@ -if 'CONFIG_LIBISCSI' in config_host +if libiscsi.found() executable('vhost-user-scsi', files('vhost-user-scsi.c'), dependencies: [qemuutil, libiscsi, vhost_user], build_by_default: targetos == 'linux', @@ -34,7 +34,7 @@ #include "sysemu/tcg.h" #include "sysemu/kvm.h" #include "sysemu/replay.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "exec/log.h" uintptr_t qemu_host_page_size; diff --git a/docs/devel/control-flow-integrity.rst b/docs/devel/control-flow-integrity.rst new file mode 100644 index 0000000000..d89d70733d --- /dev/null +++ b/docs/devel/control-flow-integrity.rst @@ -0,0 +1,137 @@ +============================ +Control-Flow Integrity (CFI) +============================ + +This document describes the current control-flow integrity (CFI) mechanism in +QEMU. How it can be enabled, its benefits and deficiencies, and how it affects +new and existing code in QEMU + +Basics +------ + +CFI is a hardening technique that focusing on guaranteeing that indirect +function calls have not been altered by an attacker. +The type used in QEMU is a forward-edge control-flow integrity that ensures +function calls performed through function pointers, always call a "compatible" +function. A compatible function is a function with the same signature of the +function pointer declared in the source code. + +This type of CFI is entirely compiler-based and relies on the compiler knowing +the signature of every function and every function pointer used in the code. +As of now, the only compiler that provides support for CFI is Clang. + +CFI is best used on production binaries, to protect against unknown attack +vectors. + +In case of a CFI violation (i.e. call to a non-compatible function) QEMU will +terminate abruptly, to stop the possible attack. + +Building with CFI +----------------- + +NOTE: CFI requires the use of link-time optimization. Therefore, when CFI is +selected, LTO will be automatically enabled. + +To build with CFI, the minimum requirement is Clang 6+. If you +are planning to also enable fuzzing, then Clang 11+ is needed (more on this +later). + +Given the use of LTO, a version of AR that supports LLVM IR is required. +The easies way of doing this is by selecting the AR provided by LLVM:: + + AR=llvm-ar-9 CC=clang-9 CXX=lang++-9 /path/to/configure --enable-cfi + +CFI is enabled on every binary produced. + +If desired, an additional flag to increase the verbosity of the output in case +of a CFI violation is offered (``--enable-debug-cfi``). + +Using QEMU built with CFI +------------------------- + +A binary with CFI will work exactly like a standard binary. In case of a CFI +violation, the binary will terminate with an illegal instruction signal. + +Incompatible code with CFI +-------------------------- + +As mentioned above, CFI is entirely compiler-based and therefore relies on +compile-time knowledge of the code. This means that, while generally supported +for most code, some specific use pattern can break CFI compatibility, and +create false-positives. The two main patterns that can cause issues are: + +* Just-in-time compiled code: since such code is created at runtime, the jump + to the buffer containing JIT code will fail. + +* Libraries loaded dynamically, e.g. with dlopen/dlsym, since the library was + not known at compile time. + +Current areas of QEMU that are not entirely compatible with CFI are: + +1. TCG, since the idea of TCG is to pre-compile groups of instructions at + runtime to speed-up interpretation, quite similarly to a JIT compiler + +2. TCI, where the interpreter has to interpret the generic *call* operation + +3. Plugins, since a plugin is implemented as an external library + +4. Modules, since they are implemented as an external library + +5. Directly calling signal handlers from the QEMU source code, since the + signal handler may have been provided by an external library or even plugged + at runtime. + +Disabling CFI for a specific function +------------------------------------- + +If you are working on function that is performing a call using an +incompatible way, as described before, you can selectively disable CFI checks +for such function by using the decorator ``QEMU_DISABLE_CFI`` at function +definition, and add an explanation on why the function is not compatible +with CFI. An example of the use of ``QEMU_DISABLE_CFI`` is provided here:: + + /* + * Disable CFI checks. + * TCG creates binary blobs at runtime, with the transformed code. + * A TB is a blob of binary code, created at runtime and called with an + * indirect function call. Since such function did not exist at compile time, + * the CFI runtime has no way to verify its signature and would fail. + * TCG is not considered a security-sensitive part of QEMU so this does not + * affect the impact of CFI in environment with high security requirements + */ + QEMU_DISABLE_CFI + static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) + +NOTE: CFI needs to be disabled at the **caller** function, (i.e. a compatible +cfi function that calls a non-compatible one), since the check is performed +when the function call is performed. + +CFI and fuzzing +--------------- + +There is generally no advantage of using CFI and fuzzing together, because +they target different environments (production for CFI, debug for fuzzing). + +CFI could be used in conjunction with fuzzing to identify a broader set of +bugs that may not end immediately in a segmentation fault or triggering +an assertion. However, other sanitizers such as address and ub sanitizers +can identify such bugs in a more precise way than CFI. + +There is, however, an interesting use case in using CFI in conjunction with +fuzzing, that is to make sure that CFI is not triggering any false positive +in remote-but-possible parts of the code. + +CFI can be enabled with fuzzing, but with some caveats: +1. Fuzzing relies on the linker performing function wrapping at link-time. +The standard BFD linker does not support function wrapping when LTO is +also enabled. The workaround is to use LLVM's lld linker. +2. Fuzzing also relies on a custom linker script, which is only supported by +lld with version 11+. + +In other words, to compile with fuzzing and CFI, clang 11+ is required, and +lld needs to be used as a linker:: + + AR=llvm-ar-11 CC=clang-11 CXX=lang++-11 /path/to/configure --enable-cfi \ + -enable-fuzzing --extra-ldflags="-fuse-ld=lld" + +and then, compile the fuzzers as usual. diff --git a/docs/devel/index.rst b/docs/devel/index.rst index f10ed77e4c..ea0e1e17ae 100644 --- a/docs/devel/index.rst +++ b/docs/devel/index.rst @@ -15,14 +15,15 @@ Contents: build-system kconfig + testing + fuzzing + control-flow-integrity loads-stores memory migration atomics stable-process - testing qtest - fuzzing decodetree secure-coding-practices tcg diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst index 336ba0e8e5..cb2d7ffac0 100644 --- a/docs/devel/kconfig.rst +++ b/docs/devel/kconfig.rst @@ -288,21 +288,20 @@ they will include all these symbols and some help text on what they do. ---------------- In some special cases, a configurable element depends on host features -that are detected by QEMU's configure script; for example some devices -depend on the availability of KVM or on the presence of a library on -the host. +that are detected by QEMU's configure or ``meson.build`` scripts; for +example some devices depend on the availability of KVM or on the presence +of a library on the host. These symbols should be listed in ``Kconfig.host`` like this:: - config KVM + config TPM bool -and also listed as follows in the top-level Makefile's ``MINIKCONF_ARGS`` +and also listed as follows in the top-level meson.build's host_kconfig variable:: - MINIKCONF_ARGS = \ - $@ $*/config-devices.mak.d $< $(MINIKCONF_INPUTS) \ - CONFIG_KVM=$(CONFIG_KVM) \ - CONFIG_SPICE=$(CONFIG_SPICE) \ - CONFIG_TPM=$(CONFIG_TPM) \ + 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'] : []) + \ ... diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 077c3f4866..2c1898032e 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -21,7 +21,6 @@ #include "hw/sysbus.h" #include "hw/boards.h" #include "migration/vmstate.h" -#include "tcg/tcg.h" #include "qom/object.h" #define VAPIC_IO_PORT 0x7e diff --git a/accel/tcg/translate-all.h b/include/exec/translate-all.h index a557b4e2bb..a557b4e2bb 100644 --- a/accel/tcg/translate-all.h +++ b/include/exec/translate-all.h diff --git a/include/qemu/cacheflush.h b/include/qemu/cacheflush.h new file mode 100644 index 0000000000..58ae488491 --- /dev/null +++ b/include/qemu/cacheflush.h @@ -0,0 +1,24 @@ +/* + * Flush the host cpu caches. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef QEMU_CACHEFLUSH_H +#define QEMU_CACHEFLUSH_H + +#if defined(__i386__) || defined(__x86_64__) || defined(__s390__) + +static inline void flush_icache_range(uintptr_t start, uintptr_t stop) +{ + /* icache is coherent and does not require flushing. */ +} + +#else + +void flush_icache_range(uintptr_t start, uintptr_t stop); + +#endif + +#endif /* QEMU_CACHEFLUSH_H */ diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index df9ec08f8a..d620a841e4 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -233,4 +233,15 @@ extern void QEMU_NORETURN QEMU_ERROR("code path is reachable") # define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */ #endif +#ifdef CONFIG_CFI +/* + * If CFI is enabled, use an attribute to disable cfi-icall on the following + * function + */ +#define QEMU_DISABLE_CFI __attribute__((no_sanitize("cfi-icall"))) +#else +/* If CFI is not enabled, use an empty define to not change the behavior */ +#define QEMU_DISABLE_CFI +#endif + #endif /* COMPILER_H */ diff --git a/meson.build b/meson.build index 4a92213231..563688d682 100644 --- a/meson.build +++ b/meson.build @@ -268,7 +268,11 @@ endif # grandfathered in from the QEMU Makefiles. add_project_arguments(config_host['GLIB_CFLAGS'].split(), native: false, language: ['c', 'cpp', 'objc']) -glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split()) +glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(), + link_args: config_host['GLIB_LIBS'].split()) +# override glib dep with the configure results (for subprojects) +meson.override_dependency('glib-2.0', glib) + gio = not_found if 'CONFIG_GIO' in config_host gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(), @@ -319,22 +323,73 @@ if 'CONFIG_LIBXML2' in config_host link_args: config_host['LIBXML2_LIBS'].split()) endif libnfs = not_found -if 'CONFIG_LIBNFS' in config_host - libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split()) +if not get_option('libnfs').auto() or have_block + libnfs = dependency('libnfs', version: '>=1.9.3', + required: get_option('libnfs'), + method: 'pkg-config', static: enable_static) endif + +libattr_test = ''' + #include <stddef.h> + #include <sys/types.h> + #ifdef CONFIG_LIBATTR + #include <attr/xattr.h> + #else + #include <sys/xattr.h> + #endif + int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }''' + libattr = not_found -if 'CONFIG_ATTR' in config_host - libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split()) +have_old_libattr = false +if not get_option('attr').disabled() + if cc.links(libattr_test) + libattr = declare_dependency() + else + libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'], + required: get_option('attr'), + static: enable_static) + if libattr.found() and not \ + cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR') + libattr = not_found + if get_option('attr').enabled() + error('could not link libattr') + else + warning('could not link libattr, disabling') + endif + else + have_old_libattr = libattr.found() + endif + endif endif + seccomp = not_found -if 'CONFIG_SECCOMP' in config_host - seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(), - link_args: config_host['SECCOMP_LIBS'].split()) +if not get_option('seccomp').auto() or have_system or have_tools + seccomp = dependency('libseccomp', version: '>=2.3.0', + required: get_option('seccomp'), + method: 'pkg-config', static: enable_static) endif + libcap_ng = not_found -if 'CONFIG_LIBCAP_NG' in config_host - libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split()) +if not get_option('cap_ng').auto() or have_system or have_tools + libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'], + required: get_option('cap_ng'), + static: enable_static) +endif +if libcap_ng.found() and not cc.links(''' + #include <cap-ng.h> + int main(void) + { + capng_capability_to_name(CAPNG_EFFECTIVE); + return 0; + }''', dependencies: libcap_ng) + libcap_ng = not_found + if get_option('cap_ng').enabled() + error('could not link libcap-ng') + else + warning('could not link libcap-ng, disabling') + endif endif + if get_option('xkbcommon').auto() and not have_system and not have_tools xkbcommon = not_found else @@ -372,14 +427,16 @@ if 'CONFIG_PLUGIN' in config_host libdl = cc.find_library('dl', required: true) endif libiscsi = not_found -if 'CONFIG_LIBISCSI' in config_host - libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(), - link_args: config_host['LIBISCSI_LIBS'].split()) +if not get_option('libiscsi').auto() or have_block + libiscsi = dependency('libiscsi', version: '>=1.9.0', + required: get_option('libiscsi'), + method: 'pkg-config', static: enable_static) endif zstd = not_found -if 'CONFIG_ZSTD' in config_host - zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(), - link_args: config_host['ZSTD_LIBS'].split()) +if not get_option('zstd').auto() or have_block + zstd = dependency('libzstd', version: '>=1.4.0', + required: get_option('zstd'), + method: 'pkg-config', static: enable_static) endif gbm = not_found if 'CONFIG_GBM' in config_host @@ -392,13 +449,16 @@ if 'CONFIG_VIRGL' in config_host link_args: config_host['VIRGL_LIBS'].split()) endif curl = not_found -if 'CONFIG_CURL' in config_host - curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(), - link_args: config_host['CURL_LIBS'].split()) +if not get_option('curl').auto() or have_block + curl = dependency('libcurl', version: '>=7.29.0', + method: 'pkg-config', + required: get_option('curl'), + static: enable_static) endif libudev = not_found if targetos == 'linux' and (have_system or have_tools) libudev = dependency('libudev', + method: 'pkg-config', required: get_option('libudev'), static: enable_static) endif @@ -500,16 +560,16 @@ if have_system and not get_option('curses').disabled() endif endforeach msg = get_option('curses').enabled() ? 'curses library not found' : '' + curses_compile_args = ['-DNCURSES_WIDECHAR'] if curses.found() - if cc.links(curses_test, dependencies: [curses]) - curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [curses]) + if cc.links(curses_test, args: curses_compile_args, dependencies: [curses]) + curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses]) else msg = 'curses package not usable' curses = not_found endif endif if not curses.found() - curses_compile_args = ['-DNCURSES_WIDECHAR'] has_curses_h = cc.has_header('curses.h', args: curses_compile_args) if targetos != 'windows' and not has_curses_h message('Trying with /usr/include/ncursesw') @@ -569,8 +629,21 @@ if have_system and not get_option('curses').disabled() endif brlapi = not_found -if 'CONFIG_BRLAPI' in config_host - brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split()) +if not get_option('brlapi').auto() or have_system + brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'], + required: get_option('brlapi'), + static: enable_static) + if brlapi.found() and not cc.links(''' + #include <brlapi.h> + #include <stddef.h> + int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi) + brlapi = not_found + if get_option('brlapi').enabled() + error('could not link brlapi') + else + warning('could not link brlapi, disabling') + endif + endif endif sdl = not_found @@ -593,13 +666,59 @@ else endif rbd = not_found -if 'CONFIG_RBD' in config_host - rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split()) +if not get_option('rbd').auto() or have_block + librados = cc.find_library('rados', required: get_option('rbd'), + static: enable_static) + librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'], + required: get_option('rbd'), + static: enable_static) + if librados.found() and librbd.found() and cc.links(''' + #include <stdio.h> + #include <rbd/librbd.h> + int main(void) { + rados_t cluster; + rados_create(&cluster, NULL); + return 0; + }''', dependencies: [librbd, librados]) + rbd = declare_dependency(dependencies: [librbd, librados]) + endif endif + glusterfs = not_found -if 'CONFIG_GLUSTERFS' in config_host - glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(), - link_args: config_host['GLUSTERFS_LIBS'].split()) +glusterfs_ftruncate_has_stat = false +glusterfs_iocb_has_stat = false +if not get_option('glusterfs').auto() or have_block + glusterfs = dependency('glusterfs-api', version: '>=3', + required: get_option('glusterfs'), + method: 'pkg-config', static: enable_static) + if glusterfs.found() + glusterfs_ftruncate_has_stat = cc.links(''' + #include <glusterfs/api/glfs.h> + + int + main(void) + { + /* new glfs_ftruncate() passes two additional args */ + return glfs_ftruncate(NULL, 0, NULL, NULL); + } + ''', dependencies: glusterfs) + glusterfs_iocb_has_stat = cc.links(''' + #include <glusterfs/api/glfs.h> + + /* new glfs_io_cbk() passes two additional glfs_stat structs */ + static void + glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data) + {} + + int + main(void) + { + glfs_io_cbk iocb = &glusterfs_iocb; + iocb(NULL, 0 , NULL, NULL, NULL); + return 0; + } + ''', dependencies: glusterfs) + endif endif libssh = not_found if 'CONFIG_LIBSSH' in config_host @@ -607,13 +726,39 @@ if 'CONFIG_LIBSSH' in config_host link_args: config_host['LIBSSH_LIBS'].split()) endif libbzip2 = not_found -if 'CONFIG_BZIP2' in config_host - libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split()) +if not get_option('bzip2').auto() or have_block + libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'], + required: get_option('bzip2'), + static: enable_static) + if libbzip2.found() and not cc.links(''' + #include <bzlib.h> + int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2) + libbzip2 = not_found + if get_option('bzip2').enabled() + error('could not link libbzip2') + else + warning('could not link libbzip2, disabling') + endif + endif endif + liblzfse = not_found -if 'CONFIG_LZFSE' in config_host - liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split()) +if not get_option('lzfse').auto() or have_block + liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], + required: get_option('lzfse'), + static: enable_static) +endif +if liblzfse.found() and not cc.links(''' + #include <lzfse.h> + int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse) + liblzfse = not_found + if get_option('lzfse').enabled() + error('could not link liblzfse') + else + warning('could not link liblzfse, disabling') + endif endif + oss = not_found if 'CONFIG_AUDIO_OSS' in config_host oss = declare_dependency(link_args: config_host['OSS_LIBS'].split()) @@ -664,14 +809,41 @@ if get_option('vnc').enabled() compile_args: '-DSTRUCT_IOVEC_DEFINED') endif endif + snappy = not_found -if 'CONFIG_SNAPPY' in config_host - snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split()) +if not get_option('snappy').auto() or have_system + snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'], + required: get_option('snappy'), + static: enable_static) +endif +if snappy.found() and not cc.links(''' + #include <snappy-c.h> + int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy) + snappy = not_found + if get_option('snappy').enabled() + error('could not link libsnappy') + else + warning('could not link libsnappy, disabling') + endif endif + lzo = not_found -if 'CONFIG_LZO' in config_host - lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split()) +if not get_option('lzo').auto() or have_system + lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'], + required: get_option('lzo'), + static: enable_static) +endif +if lzo.found() and not cc.links(''' + #include <lzo/lzo1x.h> + int main(void) { lzo_version(); return 0; }''', dependencies: lzo) + lzo = not_found + if get_option('lzo').enabled() + error('could not link liblzo2') + else + warning('could not link liblzo2, disabling') + endif endif + rdma = not_found if 'CONFIG_RDMA' in config_host rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split()) @@ -773,6 +945,7 @@ elif get_option('vhost_user_blk_server').disabled() or not have_system have_vhost_user_blk_server = false endif + if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() error('Cannot enable fuse-lseek while fuse is disabled') endif @@ -795,10 +968,69 @@ if not get_option('fuse_lseek').disabled() endif endif +if get_option('cfi') + cfi_flags=[] + # Check for dependency on LTO + if not get_option('b_lto') + error('Selected Control-Flow Integrity but LTO is disabled') + endif + if config_host.has_key('CONFIG_MODULES') + error('Selected Control-Flow Integrity is not compatible with modules') + endif + # Check for cfi flags. CFI requires LTO so we can't use + # get_supported_arguments, but need a more complex "compiles" which allows + # custom arguments + if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall', + args: ['-flto', '-fsanitize=cfi-icall'] ) + cfi_flags += '-fsanitize=cfi-icall' + else + error('-fsanitize=cfi-icall is not supported by the compiler') + endif + if cc.compiles('int main () { return 0; }', + name: '-fsanitize-cfi-icall-generalize-pointers', + args: ['-flto', '-fsanitize=cfi-icall', + '-fsanitize-cfi-icall-generalize-pointers'] ) + cfi_flags += '-fsanitize-cfi-icall-generalize-pointers' + else + error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler') + endif + if get_option('cfi_debug') + if cc.compiles('int main () { return 0; }', + name: '-fno-sanitize-trap=cfi-icall', + args: ['-flto', '-fsanitize=cfi-icall', + '-fno-sanitize-trap=cfi-icall'] ) + cfi_flags += '-fno-sanitize-trap=cfi-icall' + else + error('-fno-sanitize-trap=cfi-icall is not supported by the compiler') + endif + endif + add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) + add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) +endif + ################# # config-host.h # ################# +have_virtfs = (targetos == 'linux' and + have_system and + libattr.found() and + libcap_ng.found()) + +if get_option('virtfs').enabled() + if not have_virtfs + if targetos != 'linux' + error('virtio-9p (virtfs) requires Linux') + elif not libcap_ng.found() or not libattr.found() + error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel') + elif not have_system + error('virtio-9p (virtfs) needs system emulation support') + endif + endif +elif get_option('virtfs').disabled() + have_virtfs = false +endif + config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) @@ -812,25 +1044,48 @@ config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) +config_host_data.set('CONFIG_ATTR', libattr.found()) +config_host_data.set('CONFIG_BRLAPI', brlapi.found()) config_host_data.set('CONFIG_COCOA', cocoa.found()) config_host_data.set('CONFIG_LIBUDEV', libudev.found()) +config_host_data.set('CONFIG_LZO', lzo.found()) config_host_data.set('CONFIG_MPATH', mpathpersist.found()) config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api) +config_host_data.set('CONFIG_CURL', curl.found()) config_host_data.set('CONFIG_CURSES', curses.found()) +config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) +if glusterfs.found() + config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4')) + config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5')) + config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6')) + config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6')) + config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat) + config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat) +endif +config_host_data.set('CONFIG_LIBATTR', have_old_libattr) +config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) +config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) +config_host_data.set('CONFIG_LIBNFS', libnfs.found()) +config_host_data.set('CONFIG_RBD', rbd.found()) config_host_data.set('CONFIG_SDL', sdl.found()) config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) +config_host_data.set('CONFIG_SECCOMP', seccomp.found()) +config_host_data.set('CONFIG_SNAPPY', snappy.found()) config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) config_host_data.set('CONFIG_VNC', vnc.found()) config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) config_host_data.set('CONFIG_VNC_PNG', png.found()) config_host_data.set('CONFIG_VNC_SASL', sasl.found()) +config_host_data.set('CONFIG_VIRTFS', have_virtfs) config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) config_host_data.set('CONFIG_GETTID', has_gettid) config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) config_host_data.set('CONFIG_STATX', has_statx) +config_host_data.set('CONFIG_ZSTD', zstd.found()) config_host_data.set('CONFIG_FUSE', fuse.found()) config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) +config_host_data.set('CONFIG_CFI', get_option('cfi')) config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) @@ -911,21 +1166,19 @@ if link_language == 'cpp' } endif -kconfig_external_symbols = [ - 'CONFIG_KVM', - 'CONFIG_XEN', - 'CONFIG_TPM', - 'CONFIG_SPICE', - 'CONFIG_IVSHMEM', - 'CONFIG_OPENGL', - 'CONFIG_X11', - 'CONFIG_VHOST_USER', - 'CONFIG_VHOST_VDPA', - 'CONFIG_VHOST_KERNEL', - 'CONFIG_VIRTFS', - 'CONFIG_LINUX', - 'CONFIG_PVRDMA', -] +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'] : []) + \ + ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \ + ('CONFIG_X11' in config_host ? ['CONFIG_X11=y'] : []) + \ + ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \ + ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \ + ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ + (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ + ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ + ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host @@ -960,7 +1213,7 @@ foreach target : target_dirs } endif - have_accel = false + accel_kconfig = [] foreach sym: accelerators if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) config_target += { sym: 'y' } @@ -968,10 +1221,10 @@ foreach target : target_dirs if sym == 'CONFIG_XEN' and have_xen_pci_passthrough config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } endif - have_accel = true + accel_kconfig += [ sym + '=y' ] endif endforeach - if not have_accel + if accel_kconfig.length() == 0 if default_targets continue endif @@ -1025,22 +1278,16 @@ foreach target : target_dirs configuration: config_target_data)} if target.endswith('-softmmu') - base_kconfig = [] - foreach sym : kconfig_external_symbols - if sym in config_target or sym in config_host - base_kconfig += '@0@=y'.format(sym) - endif - endforeach - config_devices_mak = target + '-config-devices.mak' config_devices_mak = configure_file( input: ['default-configs/devices' / target + '.mak', 'Kconfig'], output: config_devices_mak, depfile: config_devices_mak + '.d', capture: true, - command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'], + command: [minikconf, + get_option('default_devices') ? '--defconfig' : '--allnoconfig', config_devices_mak, '@DEPFILE@', '@INPUT@', - base_kconfig]) + host_kconfig, accel_kconfig]) config_devices_data = configuration_data() config_devices = keyval.load(config_devices_mak) @@ -2079,6 +2326,7 @@ summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} summary_info += {'sparse enabled': sparse.found()} summary_info += {'strip binaries': get_option('strip')} summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')} +summary_info += {'link-time optimization (LTO)': get_option('b_lto')} summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} if targetos == 'darwin' summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')} @@ -2111,12 +2359,12 @@ 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 += {'curl support': config_host.has_key('CONFIG_CURL')} +summary_info += {'curl support': curl.found()} summary_info += {'mingw32 support': targetos == 'windows'} summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']} summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} -summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')} +summary_info += {'VirtFS support': have_virtfs} summary_info += {'build virtiofs daemon': have_virtiofsd} summary_info += {'Multipath support': mpathpersist.found()} summary_info += {'VNC support': vnc.found()} @@ -2129,14 +2377,14 @@ summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')} if config_host.has_key('CONFIG_XEN_BACKEND') summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} endif -summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')} +summary_info += {'brlapi support': brlapi.found()} summary_info += {'Documentation': build_docs} summary_info += {'PIE': get_option('b_pie')} 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 += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')} +summary_info += {'ATTR/XATTR support': libattr.found()} summary_info += {'Install blobs': get_option('install_blobs')} summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} @@ -2157,7 +2405,7 @@ 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 += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')} +summary_info += {'libcap-ng support': libcap_ng.found()} summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')} summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} @@ -2173,7 +2421,7 @@ if config_host['TRACE_BACKENDS'].split().contains('simple') endif # TODO: add back protocol and server version summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')} -summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')} +summary_info += {'rbd support': rbd.found()} summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')} summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')} summary_info += {'U2F support': u2f.found()} @@ -2181,8 +2429,8 @@ summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')} summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')} summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')} -summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')} -summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')} +summary_info += {'libiscsi support': libiscsi.found()} +summary_info += {'libnfs support': libnfs.found()} summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')} if targetos == 'windows' if 'WIN_SDK' in config_host @@ -2192,23 +2440,25 @@ if targetos == 'windows' summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')} summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')} endif -summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')} +summary_info += {'seccomp support': seccomp.found()} +summary_info += {'CFI support': get_option('cfi')} +summary_info += {'CFI debug support': get_option('cfi_debug')} summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'} 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 += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')} -summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')} +summary_info += {'GlusterFS support': glusterfs.found()} summary_info += {'gcov': get_option('b_coverage')} summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')} summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')} summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')} summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')} -summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')} -summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')} -summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')} -summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')} -summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')} +summary_info += {'lzo support': lzo.found()} +summary_info += {'snappy support': snappy.found()} +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 += {'memory allocator': get_option('malloc')} @@ -2228,7 +2478,7 @@ summary_info += {'capstone': capstone_opt == 'disabled' ? false : capst summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')} summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')} summary_info += {'libudev': libudev.found()} -summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'} +summary_info += {'default devices': get_option('default_devices')} summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')} summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')} if config_host.has_key('HAVE_GDB_BIN') diff --git a/meson_options.txt b/meson_options.txt index 74ac853548..7948a8255c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -7,9 +7,11 @@ option('qemu_firmwarepath', type : 'string', value : '', option('sphinx_build', type : 'string', value : '', description: 'Use specified sphinx-build [$sphinx_build] for building document (default to be empty)') +option('default_devices', type : 'boolean', value : true, + description: 'Include a default selection of devices in emulators') option('docs', type : 'feature', value : 'auto', description: 'Documentations build support') -option('gettext', type : 'boolean', value : true, +option('gettext', type : 'feature', value : 'auto', description: 'Localization of the GTK+ user interface') option('install_blobs', type : 'boolean', value : true, description: 'install provided firmware blobs') @@ -35,9 +37,29 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto', description: 'Xen PCI passthrough support') option('tcg', type: 'feature', value: 'auto', description: 'TCG support') +option('cfi', type: 'boolean', value: 'false', + description: 'Control-Flow Integrity (CFI)') +option('cfi_debug', type: 'boolean', value: 'false', + description: 'Verbose errors in case of CFI violation') +option('attr', type : 'feature', value : 'auto', + description: 'attr/xattr support') +option('brlapi', type : 'feature', value : 'auto', + description: 'brlapi character device driver') +option('bzip2', type : 'feature', value : 'auto', + description: 'bzip2 support for DMG images') +option('cap_ng', type : 'feature', value : 'auto', + description: 'cap_ng support') option('cocoa', type : 'feature', value : 'auto', description: 'Cocoa user interface (macOS only)') +option('curl', type : 'feature', value : 'auto', + description: 'CURL block device driver') +option('glusterfs', type : 'feature', value : 'auto', + description: 'Glusterfs block device driver') +option('libiscsi', type : 'feature', value : 'auto', + description: 'libiscsi userspace initiator') +option('libnfs', type : 'feature', value : 'auto', + description: 'libnfs block device driver') option('mpath', type : 'feature', value : 'auto', description: 'Multipath persistent reservation passthrough') option('iconv', type : 'feature', value : 'auto', @@ -46,10 +68,20 @@ option('curses', type : 'feature', value : 'auto', description: 'curses UI') option('libudev', type : 'feature', value : 'auto', description: 'Use libudev to enumerate host devices') +option('lzfse', type : 'feature', value : 'auto', + description: 'lzfse support for DMG images') +option('lzo', type : 'feature', value : 'auto', + description: 'lzo compression support') +option('rbd', type : 'feature', value : 'auto', + description: 'Ceph block device driver') option('sdl', type : 'feature', value : 'auto', description: 'SDL user interface') option('sdl_image', type : 'feature', value : 'auto', description: 'SDL Image support for icons') +option('seccomp', type : 'feature', value : 'auto', + description: 'seccomp support') +option('snappy', type : 'feature', value : 'auto', + description: 'snappy compression support') option('u2f', type : 'feature', value : 'auto', description: 'U2F emulation support') option('vnc', type : 'feature', value : 'enabled', @@ -62,15 +94,20 @@ option('vnc_sasl', type : 'feature', value : 'auto', description: 'SASL authentication for VNC server') option('xkbcommon', type : 'feature', value : 'auto', description: 'xkbcommon support') -option('virtiofsd', type: 'feature', value: 'auto', - description: 'build virtiofs daemon (virtiofsd)') -option('vhost_user_blk_server', type: 'feature', value: 'auto', - description: 'build vhost-user-blk server') +option('zstd', type : 'feature', value : 'auto', + description: 'zstd compression support') option('fuse', type: 'feature', value: 'auto', description: 'FUSE block device export') option('fuse_lseek', type : 'feature', value : 'auto', description: 'SEEK_HOLE/SEEK_DATA support for FUSE exports') +option('vhost_user_blk_server', type: 'feature', value: 'auto', + description: 'build vhost-user-blk server') +option('virtfs', type: 'feature', value: 'auto', + description: 'virtio-9p support') +option('virtiofsd', type: 'feature', value: 'auto', + description: 'build virtiofs daemon (virtiofsd)') + option('capstone', type: 'combo', value: 'auto', choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], description: 'Whether and how to find the capstone library') diff --git a/migration/meson.build b/migration/meson.build index 291adc1337..9645f44005 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -28,6 +28,6 @@ softmmu_ss.add(files( softmmu_ss.add(when: ['CONFIG_RDMA', rdma], if_true: files('rdma.c')) softmmu_ss.add(when: 'CONFIG_LIVE_BLOCK_MIGRATION', if_true: files('block.c')) -softmmu_ss.add(when: 'CONFIG_ZSTD', if_true: [files('multifd-zstd.c'), zstd]) +softmmu_ss.add(when: zstd, if_true: files('multifd-zstd.c')) specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('dirtyrate.c', 'ram.c')) diff --git a/monitor/misc.c b/monitor/misc.c index a5d4d4e4f4..a7650ed747 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -77,7 +77,6 @@ #include "qapi/qmp-event.h" #include "sysemu/cpus.h" #include "qemu/cutils.h" -#include "tcg/tcg.h" #if defined(TARGET_S390X) #include "hw/s390x/storage-keys.h" diff --git a/plugins/core.c b/plugins/core.c index 51bfc94787..87b823bbc4 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -31,6 +31,7 @@ #include "tcg/tcg-op.h" #include "trace/mem-internal.h" /* mem_info macros */ #include "plugin.h" +#include "qemu/compiler.h" struct qemu_plugin_cb { struct qemu_plugin_ctx *ctx; @@ -90,6 +91,12 @@ void plugin_unregister_cb__locked(struct qemu_plugin_ctx *ctx, } } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI static void plugin_vcpu_cb__simple(CPUState *cpu, enum qemu_plugin_event ev) { struct qemu_plugin_cb *cb, *next; @@ -111,6 +118,12 @@ static void plugin_vcpu_cb__simple(CPUState *cpu, enum qemu_plugin_event ev) } } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI static void plugin_cb__simple(enum qemu_plugin_event ev) { struct qemu_plugin_cb *cb, *next; @@ -128,6 +141,12 @@ static void plugin_cb__simple(enum qemu_plugin_event ev) } } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI static void plugin_cb__udata(enum qemu_plugin_event ev) { struct qemu_plugin_cb *cb, *next; @@ -325,6 +344,12 @@ void plugin_register_vcpu_mem_cb(GArray **arr, dyn_cb->f.generic = cb; } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb) { struct qemu_plugin_cb *cb, *next; @@ -339,6 +364,12 @@ void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb) } } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI void qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, @@ -358,6 +389,12 @@ qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2, } } +/* + * Disable CFI checks. + * The callback function has been loaded from an external library so we do not + * have type information + */ +QEMU_DISABLE_CFI void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret) { struct qemu_plugin_cb *cb, *next; diff --git a/plugins/loader.c b/plugins/loader.c index 5cb9794fda..8550e61184 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -32,6 +32,7 @@ #ifndef CONFIG_USER_ONLY #include "hw/boards.h" #endif +#include "qemu/compiler.h" #include "plugin.h" @@ -150,6 +151,12 @@ static uint64_t xorshift64star(uint64_t x) return x * UINT64_C(2685821657736338717); } +/* + * Disable CFI checks. + * The install and version functions have been loaded from an external library + * so we do not have type information + */ +QEMU_DISABLE_CFI static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp) { qemu_plugin_install_func_t install; diff --git a/po/meson.build b/po/meson.build index 1387fd979a..a863f0575f 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,6 +1,6 @@ i18n = import('i18n') -if get_option('gettext') +if find_program('xgettext', required: get_option('gettext')).found() i18n.gettext(meson.project_name(), args: '--msgid-bugs-address=qemu-devel@nongnu.org', preset: 'glib') diff --git a/python/qemu/console_socket.py b/python/qemu/console_socket.py index f060d79e06..ac21130e44 100644 --- a/python/qemu/console_socket.py +++ b/python/qemu/console_socket.py @@ -45,6 +45,13 @@ class ConsoleSocket(socket.socket): if drain: self._drain_thread = self._thread_start() + def __repr__(self) -> str: + s = super().__repr__() + s = s.rstrip(">") + s = "%s, logfile=%s, drain_thread=%s>" % (s, self._logfile, + self._drain_thread) + return s + def _drain_fn(self) -> None: """Drains the socket and runs while the socket is open.""" while self._open: diff --git a/qom/object.c b/qom/object.c index 5cd43fe366..2fa0119647 100644 --- a/qom/object.c +++ b/qom/object.c @@ -685,6 +685,7 @@ static void object_finalize(void *data) object_deinit(obj, ti); g_assert(obj->ref == 0); + g_assert(obj->parent == NULL); if (obj->free) { obj->free(obj); } diff --git a/softmmu/meson.build b/softmmu/meson.build index 2dab6c7eb6..d8e03018ab 100644 --- a/softmmu/meson.build +++ b/softmmu/meson.build @@ -28,5 +28,5 @@ softmmu_ss.add(files( ), sdl, libpmem, libdaxctl) softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c')) -softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp]) +softmmu_ss.add(when: seccomp, if_true: files('qemu-seccomp.c')) softmmu_ss.add(when: fdt, if_true: files('device_tree.c')) diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 2cd1de4a2c..8b9ffc41c2 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -22,10 +22,10 @@ #include "qapi/error.h" #include "qemu/cutils.h" +#include "qemu/cacheflush.h" #include "cpu.h" #include "exec/exec-all.h" #include "exec/target_page.h" -#include "tcg/tcg.h" #include "hw/qdev-core.h" #include "hw/qdev-properties.h" #include "hw/boards.h" @@ -53,7 +53,7 @@ #include "qemu/rcu_queue.h" #include "qemu/main-loop.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "sysemu/replay.h" #include "exec/memory-internal.h" diff --git a/softmmu/qemu-seccomp.c b/softmmu/qemu-seccomp.c index 8325ecb766..377ef6937c 100644 --- a/softmmu/qemu-seccomp.c +++ b/softmmu/qemu-seccomp.c @@ -202,7 +202,6 @@ static int seccomp_start(uint32_t seccomp_opts, Error **errp) return rc < 0 ? -1 : 0; } -#ifdef CONFIG_SECCOMP int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp) { if (qemu_opt_get_bool(opts, "enable", false)) { @@ -328,4 +327,3 @@ static void seccomp_register(void) } } opts_init(seccomp_register); -#endif diff --git a/softmmu/vl.c b/softmmu/vl.c index 0ed5c5ba93..7ddf405d76 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -3529,10 +3529,10 @@ void qemu_init(int argc, char **argv, char **envp) exit(0); } - qemu_init_displays(); if (!preconfig_requested) { qmp_x_exit_preconfig(&error_fatal); } + qemu_init_displays(); accel_setup_post(current_machine); os_setup_post(); resume_mux_open(); diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 1255efe7e0..5f2ee6aa7e 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -634,6 +634,24 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; switch (type) { case 5: /* task gate */ + case 6: /* 286 interrupt gate */ + case 7: /* 286 trap gate */ + case 14: /* 386 interrupt gate */ + case 15: /* 386 trap gate */ + break; + default: + raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + break; + } + dpl = (e2 >> DESC_DPL_SHIFT) & 3; + cpl = env->hflags & HF_CPL_MASK; + /* check privilege if software int */ + if (is_int && dpl < cpl) { + raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + } + + if (type == 5) { + /* task gate */ /* must do that check here to return the correct error code */ if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); @@ -661,21 +679,10 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, SET_ESP(esp, mask); } return; - case 6: /* 286 interrupt gate */ - case 7: /* 286 trap gate */ - case 14: /* 386 interrupt gate */ - case 15: /* 386 trap gate */ - break; - default: - raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); - break; - } - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (is_int && dpl < cpl) { - raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); } + + /* Otherwise, trap or interrupt gate */ + /* check valid bit */ if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 663dd0b95e..8a6b97598e 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -148,11 +148,6 @@ typedef enum { #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - __builtin___clear_cache((char *)start, (char *)stop); -} - void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #ifdef CONFIG_SOFTMMU diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 17e771374d..f1955ce4ac 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -134,11 +134,6 @@ enum { #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - __builtin___clear_cache((char *) start, (char *) stop); -} - /* not defined -- call should be eliminated at compile time */ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index abd4ac7fc0..cd067e0b30 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -206,10 +206,6 @@ extern bool have_avx2; #define TCG_TARGET_extract_i64_valid(ofs, len) \ (((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32) -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ -} - static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, uintptr_t addr) { diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index c6b091d849..92c1d63da3 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -198,20 +198,9 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */ #endif -#ifdef __OpenBSD__ -#include <machine/sysarch.h> -#else -#include <sys/cachectl.h> -#endif - #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - cacheflush ((void *)start, stop-start, ICACHE); -} - void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #ifdef CONFIG_SOFTMMU diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 18ee989f95..0d068ec8ab 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -3863,25 +3863,3 @@ void tcg_register_jit(void *buf, size_t buf_size) tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); } #endif /* __ELF__ */ - -void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - uintptr_t p, start1, stop1; - size_t dsize = qemu_dcache_linesize; - size_t isize = qemu_icache_linesize; - - start1 = start & ~(dsize - 1); - stop1 = (stop + dsize - 1) & ~(dsize - 1); - for (p = start1; p < stop1; p += dsize) { - asm volatile ("dcbst 0,%0" : : "r"(p) : "memory"); - } - asm volatile ("sync" : : : "memory"); - - start &= start & ~(isize - 1); - stop1 = (stop + isize - 1) & ~(isize - 1); - for (p = start1; p < stop1; p += isize) { - asm volatile ("icbi 0,%0" : : "r"(p) : "memory"); - } - asm volatile ("sync" : : : "memory"); - asm volatile ("isync" : : : "memory"); -} diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index be10363956..a509a19628 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -175,7 +175,6 @@ extern bool have_vsx; #define TCG_TARGET_HAS_bitsel_vec have_vsx #define TCG_TARGET_HAS_cmpsel_vec 0 -void flush_icache_range(uintptr_t start, uintptr_t stop); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #define TCG_TARGET_DEFAULT_MO (0) diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h index 032439d806..c1bd52bb9a 100644 --- a/tcg/riscv/tcg-target.h +++ b/tcg/riscv/tcg-target.h @@ -159,11 +159,6 @@ typedef enum { #define TCG_TARGET_HAS_mulsh_i64 1 #endif -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - __builtin___clear_cache((char *)start, (char *)stop); -} - /* not defined -- call should be eliminated at compile time */ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index 63c8797bd3..b4feb2f55a 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -145,10 +145,6 @@ enum { TCG_AREG0 = TCG_REG_R10, }; -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ -} - static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr, uintptr_t addr) { diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 633841ebf2..d8b0e32e2e 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -168,14 +168,6 @@ extern bool use_vis3_instructions; #define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_HAS_MEMORY_BSWAP 1 -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ - uintptr_t p; - for (p = start & -8; p < ((stop + 7) & -8); p += 8) { - __asm__ __volatile__("flush\t%0" : : "r" (p)); - } -} - void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); #define TCG_TARGET_NEED_POOL_LABELS @@ -35,6 +35,7 @@ #include "qemu/host-utils.h" #include "qemu/qemu-print.h" #include "qemu/timer.h" +#include "qemu/cacheflush.h" /* Note: the long term plan is to reduce the dependencies on the QEMU CPU definitions. Currently they are used for qemu_ld/st @@ -31,6 +31,7 @@ #include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */ #include "exec/cpu_ldst.h" #include "tcg/tcg-op.h" +#include "qemu/compiler.h" /* Marker for missing code. */ #define TODO() \ @@ -475,6 +476,12 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition) #endif /* Interpret pseudo code in tb. */ +/* + * Disable CFI checks. + * One possible operation in the pseudo code is a call to binary code. + * Therefore, disable CFI checks in the interpreter function + */ +QEMU_DISABLE_CFI uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) { tcg_target_ulong regs[TCG_TARGET_NB_REGS]; diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 8c1c1d265d..b84480f989 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -191,10 +191,6 @@ void tci_disas(uint8_t opc); #define HAVE_TCG_QEMU_TB_EXEC -static inline void flush_icache_range(uintptr_t start, uintptr_t stop) -{ -} - /* We could notice __i386__ or __s390x__ and reduce the barriers depending on the host. But if you want performance, you use the normal backend. We prefer consistency across hosts on this. */ diff --git a/tests/check-block.sh b/tests/check-block.sh index f6b1bda7b9..fb4c1baae9 100755 --- a/tests/check-block.sh +++ b/tests/check-block.sh @@ -21,14 +21,18 @@ if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; then exit 0 fi -# Disable tests with any sanitizer except for SafeStack -CFLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ) -SANITIZE_FLAGS="" -#Remove all occurrencies of -fsanitize=safe-stack -for i in ${CFLAGS}; do - if [ "${i}" != "-fsanitize=safe-stack" ]; then - SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}" +# Disable tests with any sanitizer except for specific ones +SANITIZE_FLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ) +ALLOWED_SANITIZE_FLAGS="safe-stack cfi-icall" +#Remove all occurrencies of allowed Sanitize flags +for j in ${ALLOWED_SANITIZE_FLAGS}; do + TMP_FLAGS=${SANITIZE_FLAGS} + SANITIZE_FLAGS="" + for i in ${TMP_FLAGS}; do + if ! echo ${i} | grep -q "${j}" 2>/dev/null; then + SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}" fi + done done if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then # Have a sanitize flag that is not allowed, stop diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 02ec92830b..c254ac38d0 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -11,8 +11,7 @@ HOST_ARCH = $(if $(ARCH),$(ARCH),$(shell uname -m)) DOCKER_SUFFIX := .docker DOCKER_FILES_DIR := $(SRC_PATH)/tests/docker/dockerfiles # we don't run tests on intermediate images (used as base by another image) -DOCKER_PARTIAL_IMAGES := debian9 debian10 debian11 -DOCKER_PARTIAL_IMAGES += debian9-mxe debian-bootstrap +DOCKER_PARTIAL_IMAGES := debian10 debian11 debian-bootstrap DOCKER_IMAGES := $(sort $(notdir $(basename $(wildcard $(DOCKER_FILES_DIR)/*.docker)))) DOCKER_TARGETS := $(patsubst %,docker-image-%,$(DOCKER_IMAGES)) # Use a global constant ccache directory to speed up repetitive builds @@ -96,7 +95,6 @@ docker-binfmt-image-debian-%: $(DOCKER_FILES_DIR)/debian-bootstrap.docker endif # Enforce dependencies for composite images -docker-image-debian9-mxe: docker-image-debian9 ifeq ($(HOST_ARCH),x86_64) docker-image-debian-amd64: docker-image-debian10 DOCKER_PARTIAL_IMAGES += debian-amd64-cross @@ -104,8 +102,6 @@ else docker-image-debian-amd64-cross: docker-image-debian10 DOCKER_PARTIAL_IMAGES += debian-amd64 endif -docker-image-debian-win32-cross: docker-image-debian9-mxe -docker-image-debian-win64-cross: docker-image-debian9-mxe # For non-x86 hosts not all cross-compilers have been packaged ifneq ($(HOST_ARCH),x86_64) diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker index 54bc6d54cd..64cb7a6eda 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos8.docker @@ -1,4 +1,4 @@ -FROM centos:8.1.1911 +FROM centos:8.3.2011 RUN dnf -y update ENV PACKAGES \ @@ -6,6 +6,7 @@ ENV PACKAGES \ bzip2 \ bzip2-devel \ dbus-daemon \ + diffutils \ gcc \ gcc-c++ \ genisoimage \ @@ -31,6 +32,6 @@ ENV PACKAGES \ zlib-devel RUN dnf install -y dnf-plugins-core && \ - dnf config-manager --set-enabled PowerTools && \ + dnf config-manager --set-enabled powertools && \ dnf install -y $PACKAGES RUN rpm -q $PACKAGES | sort > /packages.txt diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker index cd16cd1bfa..a6e411291b 100644 --- a/tests/docker/dockerfiles/fedora-i386-cross.docker +++ b/tests/docker/dockerfiles/fedora-i386-cross.docker @@ -1,14 +1,26 @@ -FROM fedora:30 +FROM fedora:31 ENV PACKAGES \ + bzip2 \ + diffutils \ + findutils \ gcc \ + git \ + libtasn1-devel.i686 \ + libzstd-devel.i686 \ + make \ + meson \ + ninja-build \ glib2-devel.i686 \ glibc-devel.i686 \ glibc-static.i686 \ gnutls-devel.i686 \ nettle-devel.i686 \ + perl-Test-Harness \ pixman-devel.i686 \ - zlib-devel.i686 \ - libzstd-devel.i686 + zlib-devel.i686 + +ENV QEMU_CONFIGURE_OPTS --extra-cflags=-m32 --disable-vhost-user +ENV PKG_CONFIG_PATH /usr/lib/pkgconfig RUN dnf install -y $PACKAGES RUN rpm -q $PACKAGES | sort > /packages.txt diff --git a/tests/qemu-iotests/common.env.in b/tests/qemu-iotests/common.env.in new file mode 100644 index 0000000000..e565cdf40c --- /dev/null +++ b/tests/qemu-iotests/common.env.in @@ -0,0 +1,3 @@ +# Automatically generated by configure - do not modify + +export PYTHON='@PYTHON@' diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build index 67aed1e492..26658ce25c 100644 --- a/tests/qemu-iotests/meson.build +++ b/tests/qemu-iotests/meson.build @@ -3,3 +3,6 @@ if 'CONFIG_LINUX' in config_host else socket_scm_helper = [] endif +configure_file(output: 'common.env', + input: files('common.env.in'), + configuration: {'PYTHON': python.full_path()}) diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index 2ae86776cd..24d75a5801 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -94,7 +94,7 @@ ifdef CONFIG_USER_ONLY -include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.target # Add the common build options -CFLAGS+=-Wall -O0 -g -fno-strict-aliasing +CFLAGS+=-Wall -Werror -O0 -g -fno-strict-aliasing ifeq ($(BUILD_STATIC),y) LDFLAGS+=-static endif diff --git a/tests/test-char.c b/tests/test-char.c index 953e0d1c1f..06102977b6 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -1298,7 +1298,7 @@ static void char_file_test_internal(Chardev *ext_chr, const char *filepath) g_assert(strncmp(contents, "hello!", 6) == 0); if (!ext_chr) { - object_unref(OBJECT(chr)); + object_unparent(OBJECT(chr)); g_unlink(out); } g_free(contents); diff --git a/tools/meson.build b/tools/meson.build index 76bf84df52..fdce66857d 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -1,14 +1,14 @@ have_virtiofsd = (targetos == 'linux' and have_tools and - 'CONFIG_SECCOMP' in config_host and - 'CONFIG_LIBCAP_NG' in config_host and + seccomp.found() and + libcap_ng.found() and 'CONFIG_VHOST_USER' in config_host) if get_option('virtiofsd').enabled() if not have_virtiofsd if targetos != 'linux' error('virtiofsd requires Linux') - elif 'CONFIG_SECCOMP' not in config_host or 'CONFIG_LIBCAP_NG' not in config_host + elif not seccomp.found() or not libcap_ng.found() error('virtiofsd requires libcap-ng-devel and seccomp-devel') elif not have_tools or 'CONFIG_VHOST_USER' not in config_host error('virtiofsd needs tools and vhost-user support') diff --git a/trace/meson.build b/trace/meson.build index 8569e8a0c4..a0be8f9b0d 100644 --- a/trace/meson.build +++ b/trace/meson.build @@ -1,3 +1,4 @@ + specific_ss.add(files('control-target.c')) trace_events_files = [] @@ -66,7 +67,7 @@ foreach d : [ output: d[0], input: meson.source_root() / 'trace-events', command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ]) - specific_ss.add(gen) + specific_ss.add(when: 'CONFIG_TCG', if_true: gen) endforeach if 'CONFIG_TRACE_UST' in config_host diff --git a/util/cacheflush.c b/util/cacheflush.c new file mode 100644 index 0000000000..2881832a38 --- /dev/null +++ b/util/cacheflush.c @@ -0,0 +1,71 @@ +/* + * Flush the host cpu caches. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/cacheflush.h" + + +#if defined(__i386__) || defined(__x86_64__) || defined(__s390__) + +/* Caches are coherent and do not require flushing; symbol inline. */ + +#elif defined(__mips__) + +#ifdef __OpenBSD__ +#include <machine/sysarch.h> +#else +#include <sys/cachectl.h> +#endif + +void flush_icache_range(uintptr_t start, uintptr_t stop) +{ + cacheflush((void *)start, stop - start, ICACHE); +} + +#elif defined(__powerpc__) + +void flush_icache_range(uintptr_t start, uintptr_t stop) +{ + uintptr_t p, start1, stop1; + size_t dsize = qemu_dcache_linesize; + size_t isize = qemu_icache_linesize; + + start1 = start & ~(dsize - 1); + stop1 = (stop + dsize - 1) & ~(dsize - 1); + for (p = start1; p < stop1; p += dsize) { + asm volatile ("dcbst 0,%0" : : "r"(p) : "memory"); + } + asm volatile ("sync" : : : "memory"); + + start &= start & ~(isize - 1); + stop1 = (stop + isize - 1) & ~(isize - 1); + for (p = start1; p < stop1; p += isize) { + asm volatile ("icbi 0,%0" : : "r"(p) : "memory"); + } + asm volatile ("sync" : : : "memory"); + asm volatile ("isync" : : : "memory"); +} + +#elif defined(__sparc__) + +void flush_icache_range(uintptr_t start, uintptr_t stop) +{ + uintptr_t p; + + for (p = start & -8; p < ((stop + 7) & -8); p += 8) { + __asm__ __volatile__("flush\t%0" : : "r" (p)); + } +} + +#else + +void flush_icache_range(uintptr_t start, uintptr_t stop) +{ + __builtin___clear_cache((char *)start, (char *)stop); +} + +#endif diff --git a/util/main-loop.c b/util/main-loop.c index 6470f8eae3..6bfc7c46f5 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -33,6 +33,7 @@ #include "block/aio.h" #include "qemu/error-report.h" #include "qemu/queue.h" +#include "qemu/compiler.h" #ifndef _WIN32 #include <sys/wait.h> @@ -44,6 +45,16 @@ * use signalfd to listen for them. We rely on whatever the current signal * handler is to dispatch the signals when we receive them. */ +/* + * Disable CFI checks. + * We are going to call a signal hander directly. Such handler may or may not + * have been defined in our binary, so there's no guarantee that the pointer + * used to set the handler is a cfi-valid pointer. Since the handlers are + * stored in kernel memory, changing the handler to an attacker-defined + * function requires being able to call a sigaction() syscall, + * which is not as easy as overwriting a pointer in memory. + */ +QEMU_DISABLE_CFI static void sigfd_handler(void *opaque) { int fd = (intptr_t)opaque; diff --git a/util/meson.build b/util/meson.build index f359af0d46..a3dfc0f966 100644 --- a/util/meson.build +++ b/util/meson.build @@ -21,7 +21,7 @@ util_ss.add(files('envlist.c', 'path.c', 'module.c')) util_ss.add(files('host-utils.c')) util_ss.add(files('bitmap.c', 'bitops.c')) util_ss.add(files('fifo8.c')) -util_ss.add(files('cacheinfo.c')) +util_ss.add(files('cacheinfo.c', 'cacheflush.c')) util_ss.add(files('error.c', 'qemu-error.c')) util_ss.add(files('qemu-print.c')) util_ss.add(files('id.c')) diff --git a/util/oslib-posix.c b/util/oslib-posix.c index f15234b5c0..f1e2801b11 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -39,6 +39,7 @@ #include "qemu/thread.h" #include <libgen.h> #include "qemu/cutils.h" +#include "qemu/compiler.h" #ifdef CONFIG_LINUX #include <sys/syscall.h> @@ -773,6 +774,16 @@ void qemu_free_stack(void *stack, size_t sz) munmap(stack, sz); } +/* + * Disable CFI checks. + * We are going to call a signal hander directly. Such handler may or may not + * have been defined in our binary, so there's no guarantee that the pointer + * used to set the handler is a cfi-valid pointer. Since the handlers are + * stored in kernel memory, changing the handler to an attacker-defined + * function requires being able to call a sigaction() syscall, + * which is not as easy as overwriting a pointer in memory. + */ +QEMU_DISABLE_CFI void sigaction_invoke(struct sigaction *action, struct qemu_signalfd_siginfo *info) { diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 23a7c7320b..01787df74c 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -221,7 +221,6 @@ int qemu_try_set_nonblock(int fd) if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { return -socket_error(); } - qemu_fd_register(fd); return 0; } diff --git a/version.rc b/version.rc index d8e1569991..0daadbf981 100644 --- a/version.rc +++ b/version.rc @@ -2,8 +2,8 @@ #include "config-host.h" VS_VERSION_INFO VERSIONINFO -FILEVERSION CONFIG_FILEVERSION -PRODUCTVERSION CONFIG_PRODUCTVERSION +FILEVERSION QEMU_VERSION_MAJOR,QEMU_VERSION_MINOR,QEMU_VERSION_MICRO,0 +PRODUCTVERSION QEMU_VERSION_MAJOR,QEMU_VERSION_MINOR,QEMU_VERSION_MICRO,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP |