From Alex's pull request:

* improve cross-build KVM coverage
 * new --without-default-features configure flag
 * add __repr__ for ConsoleSocket for debugging
 * build tcg tests with -Werror
 * test 32 bit builds with fedora
 * remove last traces of debian9
 * hotfix for centos8 powertools repo
 
 * Move lots of feature detection code to meson (Alex, myself)
 * CFI and LTO support (Daniele)
 * test-char dangling pointer (Eduardo)
 * Build system and win32 fixes (Marc-André)
 * Initialization fixes (myself)
 * TCG include cleanup (Richard, myself)
 * x86 'int N' fix (Peter)
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAl/1gRUUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroPTwAf+J/ffnckmzpckB1gwZ5vEnkYNDreq
 NrYWDpmnOX6mICXC68WsTmyOvoAvn5es/PF36rOEZ3mDHdF7/RGn/5zxKculLTKp
 uISs0wdApEC5n78iQwIlec6nzgjteg+DIfaLqQ4P4sVuEtFkuAVsv5E3BJGVoHLg
 sXy8gTEf95KS9r5bZpzP70rAjIbmxcAjbET4fvdELjkGDNCTRKmpEYPj0sE6qaBp
 0/VdqVLpLthuEQoDuEWube7Y2LA/ZuY3Gfxq1em+abXqFJBTAXBf2GET6a/BjLU6
 N7wO5FEQ0CUG8fst/Zw3Xp1htGPZTYYMtr0dipYEI2np0A7/CITjTWsekg==
 =rsil
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

From Alex's pull request:
* improve cross-build KVM coverage
* new --without-default-features configure flag
* add __repr__ for ConsoleSocket for debugging
* build tcg tests with -Werror
* test 32 bit builds with fedora
* remove last traces of debian9
* hotfix for centos8 powertools repo

* Move lots of feature detection code to meson (Alex, myself)
* CFI and LTO support (Daniele)
* test-char dangling pointer (Eduardo)
* Build system and win32 fixes (Marc-André)
* Initialization fixes (myself)
* TCG include cleanup (Richard, myself)
* x86 'int N' fix (Peter)

# gpg: Signature made Wed 06 Jan 2021 09:21:25 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream: (52 commits)
  win32: drop fd registration to the main-loop on setting non-block
  configure: move tests/qemu-iotests/common.env generation to meson
  meson.build: convert --with-default-devices to meson
  libattr: convert to meson
  cap_ng: convert to meson
  virtfs: convert to meson
  seccomp: convert to meson
  zstd: convert to meson
  lzfse: convert to meson
  snappy: convert to meson
  lzo: convert to meson
  rbd: convert to meson
  libnfs: convert to meson
  libiscsi: convert to meson
  bzip2: convert to meson
  glusterfs: convert to meson
  curl: convert to meson
  curl: remove compatibility code, require 7.29.0
  brlapi: convert to meson
  configure: remove CONFIG_FILEVERSION and CONFIG_PRODUCTVERSION
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	trace/meson.build
This commit is contained in:
Peter Maydell 2021-01-06 15:55:29 +00:00
commit aadac5b3d9
67 changed files with 1013 additions and 874 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,3 +1,12 @@
config WHPX
bool
config HAX
bool
config HVF
bool
config TCG
bool

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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 = {

View File

@ -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}

View File

@ -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 }

756
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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',

2
cpu.c
View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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'] : []) + \
...

View File

@ -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

24
include/qemu/cacheflush.h Normal file
View File

@ -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 */

View File

@ -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 */

View File

@ -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')

View File

@ -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')

View File

@ -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'))

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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')

View File

@ -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:

View File

@ -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);
}

View File

@ -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'))

View File

@ -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"

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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");
}

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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. */

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
# Automatically generated by configure - do not modify
export PYTHON='@PYTHON@'

View File

@ -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()})

View File

@ -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

View File

@ -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);

View File

@ -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')

View File

@ -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

71
util/cacheflush.c Normal file
View File

@ -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

View File

@ -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;

View File

@ -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'))

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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