* Fuzzing improvements (Qiuhao, Alexander)
* i386: Fix BMI decoding for instructions with the 0x66 prefix (David) * initial attempt at fixing event_notifier emulation (Maxim) * i386: PKS emulation, fix for "qemu-system-i386 -cpu host" (myself) * meson: RBD test fixes (myself) * meson: TCI warnings (Philippe) * Leaner build for --disable-guest-agent, --disable-system and --disable-tools (Philippe, Stefan) * --enable-tcg-interpreter fix (Richard) * i386: SVM feature bits (Wei) * KVM bugfix (Thomas H.) * Add missing MemoryRegionOps callbacks (PJP) -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmAhR4cUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroOviAf/Ymk/KwHZKySVqHOjDZnvP5PXMAru p1zlMRLAorXK+CTbshkIliaQyD8ggzT4HCinJ2NisdfTWMmlWbgr8gahNqKyZ5UG HlL28va3dvGhelswh/CNso1ZhVb2Q+aAYn/c6LXQva2r0xi26ohJTkIkSCPP/bnI +73dGzwAilBOsBVbn4cCm/70XtwDpPkw41IZIDoy/4lhL8ZdpHMz8oOjNIlOdlcU aEDfM8vYE4C70OtUlRZ1OwVxzcjS1Bf6dQYcpg5gAKy/jAAqR+v2PStxXiUuj5D3 cAzd03Goh78Wcre+CbWxDKGcGtiooUT+J09wmvDPYVUHcpQMbumf4MufrQ== =INB5 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging * Fuzzing improvements (Qiuhao, Alexander) * i386: Fix BMI decoding for instructions with the 0x66 prefix (David) * initial attempt at fixing event_notifier emulation (Maxim) * i386: PKS emulation, fix for "qemu-system-i386 -cpu host" (myself) * meson: RBD test fixes (myself) * meson: TCI warnings (Philippe) * Leaner build for --disable-guest-agent, --disable-system and --disable-tools (Philippe, Stefan) * --enable-tcg-interpreter fix (Richard) * i386: SVM feature bits (Wei) * KVM bugfix (Thomas H.) * Add missing MemoryRegionOps callbacks (PJP) # gpg: Signature made Mon 08 Feb 2021 14:15:35 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: (46 commits) target/i386: Expose VMX entry/exit load pkrs control bits target/i386: Add support for save/load IA32_PKRS MSR imx7-ccm: add digprog mmio write method tz-ppc: add dummy read/write methods spapr_pci: add spapr msi read method nvram: add nrf51_soc flash read method prep: add ppc-parity write method vfio: add quirk device write method pci-host: designware: add pcie-msi read method hw/pci-host: add pci-intack write method cpu-throttle: Remove timer_mod() from cpu_throttle_set() replay: rng-builtin support pc-bios/descriptors: fix paths in json files replay: fix replay of the interrupts accel/kvm/kvm-all: Fix wrong return code handling in dirty log code qapi/meson: Restrict UI module to system emulation and tools qapi/meson: Restrict system-mode specific modules qapi/meson: Remove QMP from user-mode emulation qapi/meson: Restrict qdev code to system-mode emulation meson: Restrict emulation code ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
41d306ec7d
@ -2541,6 +2541,7 @@ F: qapi/qom.json
|
|||||||
F: qapi/qdev.json
|
F: qapi/qdev.json
|
||||||
F: scripts/coccinelle/qom-parent-type.cocci
|
F: scripts/coccinelle/qom-parent-type.cocci
|
||||||
F: softmmu/qdev-monitor.c
|
F: softmmu/qdev-monitor.c
|
||||||
|
F: stubs/qdev.c
|
||||||
F: qom/
|
F: qom/
|
||||||
F: tests/check-qom-interface.c
|
F: tests/check-qom-interface.c
|
||||||
F: tests/check-qom-proplist.c
|
F: tests/check-qom-proplist.c
|
||||||
|
@ -644,15 +644,18 @@ static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
|
|||||||
|
|
||||||
d.dirty_bitmap = mem->dirty_bmap;
|
d.dirty_bitmap = mem->dirty_bmap;
|
||||||
d.slot = mem->slot | (kml->as_id << 16);
|
d.slot = mem->slot | (kml->as_id << 16);
|
||||||
if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
|
ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
|
||||||
DPRINTF("ioctl failed %d\n", errno);
|
if (ret == -ENOENT) {
|
||||||
ret = -1;
|
/* kernel does not have dirty bitmap in this slot */
|
||||||
|
ret = 0;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
error_report("ioctl KVM_GET_DIRTY_LOG failed: %d", errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
subsection.offset_within_region += slot_offset;
|
subsection.offset_within_region += slot_offset;
|
||||||
subsection.size = int128_make64(slot_size);
|
subsection.size = int128_make64(slot_size);
|
||||||
kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
|
kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
slot_offset += slot_size;
|
slot_offset += slot_size;
|
||||||
start_addr += slot_size;
|
start_addr += slot_size;
|
||||||
@ -750,8 +753,8 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
|
|||||||
d.num_pages = bmap_npages;
|
d.num_pages = bmap_npages;
|
||||||
d.slot = mem->slot | (as_id << 16);
|
d.slot = mem->slot | (as_id << 16);
|
||||||
|
|
||||||
if (kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d) == -1) {
|
ret = kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d);
|
||||||
ret = -errno;
|
if (ret < 0 && ret != -ENOENT) {
|
||||||
error_report("%s: KVM_CLEAR_DIRTY_LOG failed, slot=%d, "
|
error_report("%s: KVM_CLEAR_DIRTY_LOG failed, slot=%d, "
|
||||||
"start=0x%"PRIx64", size=0x%"PRIx32", errno=%d",
|
"start=0x%"PRIx64", size=0x%"PRIx32", errno=%d",
|
||||||
__func__, d.slot, (uint64_t)d.first_page,
|
__func__, d.slot, (uint64_t)d.first_page,
|
||||||
|
@ -81,7 +81,13 @@ void icount_handle_deadline(void)
|
|||||||
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
|
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
|
||||||
QEMU_TIMER_ATTR_ALL);
|
QEMU_TIMER_ATTR_ALL);
|
||||||
|
|
||||||
if (deadline == 0) {
|
/*
|
||||||
|
* Instructions, interrupts, and exceptions are processed in cpu-exec.
|
||||||
|
* Don't interrupt cpu thread, when these events are waiting
|
||||||
|
* (i.e., there is no checkpoint)
|
||||||
|
*/
|
||||||
|
if (deadline == 0
|
||||||
|
&& (replay_mode != REPLAY_MODE_PLAY || replay_has_checkpoint())) {
|
||||||
icount_notify_aio_contexts();
|
icount_notify_aio_contexts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,6 +494,16 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
|
|||||||
host_memory_backend_get_share, host_memory_backend_set_share);
|
host_memory_backend_get_share, host_memory_backend_set_share);
|
||||||
object_class_property_set_description(oc, "share",
|
object_class_property_set_description(oc, "share",
|
||||||
"Mark the memory as private to QEMU or shared");
|
"Mark the memory as private to QEMU or shared");
|
||||||
|
/*
|
||||||
|
* Do not delete/rename option. This option must be considered stable
|
||||||
|
* (as if it didn't have the 'x-' prefix including deprecation period) as
|
||||||
|
* long as 4.0 and older machine types exists.
|
||||||
|
* Option will be used by upper layers to override (disable) canonical path
|
||||||
|
* for ramblock-id set by compat properties on old machine types ( <= 4.0),
|
||||||
|
* to keep migration working when backend is used for main RAM with
|
||||||
|
* -machine memory-backend= option (main RAM historically used prefix-less
|
||||||
|
* ramblock-id).
|
||||||
|
*/
|
||||||
object_class_property_add_bool(oc, "x-use-canonical-path-for-ramblock-id",
|
object_class_property_add_bool(oc, "x-use-canonical-path-for-ramblock-id",
|
||||||
host_memory_backend_get_use_canonical_path,
|
host_memory_backend_get_use_canonical_path,
|
||||||
host_memory_backend_set_use_canonical_path);
|
host_memory_backend_set_use_canonical_path);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
#include "sysemu/replay.h"
|
||||||
|
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN)
|
OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN)
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req)
|
|||||||
{
|
{
|
||||||
RngBuiltin *s = RNG_BUILTIN(b);
|
RngBuiltin *s = RNG_BUILTIN(b);
|
||||||
|
|
||||||
qemu_bh_schedule(s->bh);
|
replay_bh_schedule_event(s->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rng_builtin_init(Object *obj)
|
static void rng_builtin_init(Object *obj)
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -1764,7 +1764,7 @@ Advanced options (experts only):
|
|||||||
--with-trace-file=NAME Full PATH,NAME of file to store traces
|
--with-trace-file=NAME Full PATH,NAME of file to store traces
|
||||||
Default:trace-<pid>
|
Default:trace-<pid>
|
||||||
--disable-slirp disable SLIRP userspace network connectivity
|
--disable-slirp disable SLIRP userspace network connectivity
|
||||||
--enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
|
--enable-tcg-interpreter enable TCI (TCG with bytecode interpreter, experimental and slow)
|
||||||
--enable-malloc-trim enable libc malloc_trim() for memory optimization
|
--enable-malloc-trim enable libc malloc_trim() for memory optimization
|
||||||
--oss-lib path to OSS library
|
--oss-lib path to OSS library
|
||||||
--cpu=CPU Build for host CPU [$cpu]
|
--cpu=CPU Build for host CPU [$cpu]
|
||||||
|
@ -100,7 +100,7 @@ In meson.build::
|
|||||||
# Detect dependency
|
# Detect dependency
|
||||||
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
|
|
||||||
# Create config-host.h (if applicable)
|
# Create config-host.h (if applicable)
|
||||||
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@ -119,7 +119,7 @@ Adding a new fuzzer
|
|||||||
|
|
||||||
Coverage over virtual devices can be improved by adding additional fuzzers.
|
Coverage over virtual devices can be improved by adding additional fuzzers.
|
||||||
Fuzzers are kept in ``tests/qtest/fuzz/`` and should be added to
|
Fuzzers are kept in ``tests/qtest/fuzz/`` and should be added to
|
||||||
``tests/qtest/fuzz/Makefile.include``
|
``tests/qtest/fuzz/meson.build``
|
||||||
|
|
||||||
Fuzzers can rely on both qtest and libqos to communicate with virtual devices.
|
Fuzzers can rely on both qtest and libqos to communicate with virtual devices.
|
||||||
|
|
||||||
@ -128,8 +128,7 @@ Fuzzers can rely on both qtest and libqos to communicate with virtual devices.
|
|||||||
2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers
|
2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers
|
||||||
for reference.
|
for reference.
|
||||||
|
|
||||||
3. Register the fuzzer in ``tests/fuzz/Makefile.include`` by appending the
|
3. Add the fuzzer to ``tests/qtest/fuzz/meson.build``.
|
||||||
corresponding object to fuzz-obj-y
|
|
||||||
|
|
||||||
Fuzzers can be more-or-less thought of as special qtest programs which can
|
Fuzzers can be more-or-less thought of as special qtest programs which can
|
||||||
modify the qtest commands and/or qtest command arguments based on inputs
|
modify the qtest commands and/or qtest command arguments based on inputs
|
||||||
@ -181,6 +180,36 @@ To ensure that these env variables have been configured correctly, we can use::
|
|||||||
|
|
||||||
The output should contain a complete list of matched MemoryRegions.
|
The output should contain a complete list of matched MemoryRegions.
|
||||||
|
|
||||||
|
OSS-Fuzz
|
||||||
|
--------
|
||||||
|
QEMU is continuously fuzzed on `OSS-Fuzz` __(https://github.com/google/oss-fuzz).
|
||||||
|
By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
|
||||||
|
generic-fuzz target requires additional information provided in environment
|
||||||
|
variables, we pre-define some generic-fuzz configs in
|
||||||
|
``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
|
||||||
|
|
||||||
|
- ``.name``: To identify the fuzzer config
|
||||||
|
|
||||||
|
- ``.args`` OR ``.argfunc``: A string or pointer to a function returning a
|
||||||
|
string. These strings are used to specify the ``QEMU_FUZZ_ARGS``
|
||||||
|
environment variable. ``argfunc`` is useful when the config relies on e.g.
|
||||||
|
a dynamically created temp directory, or a free tcp/udp port.
|
||||||
|
|
||||||
|
- ``.objects``: A string that specifies the ``QEMU_FUZZ_OBJECTS`` environment
|
||||||
|
variable.
|
||||||
|
|
||||||
|
To fuzz additional devices/device configuration on OSS-Fuzz, send patches for
|
||||||
|
either a new device-specific fuzzer or a new generic-fuzz config.
|
||||||
|
|
||||||
|
Build details:
|
||||||
|
|
||||||
|
- The Dockerfile that sets up the environment for building QEMU's
|
||||||
|
fuzzers on OSS-Fuzz can be fund in the OSS-Fuzz repository
|
||||||
|
__(https://github.com/google/oss-fuzz/blob/master/projects/qemu/Dockerfile)
|
||||||
|
|
||||||
|
- The script responsible for building the fuzzers can be found in the
|
||||||
|
QEMU source tree at ``scripts/oss-fuzz/build.sh``
|
||||||
|
|
||||||
Implementation Details / Fuzzer Lifecycle
|
Implementation Details / Fuzzer Lifecycle
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
@ -46,9 +46,11 @@ if build_docs
|
|||||||
meson.source_root() / 'docs/sphinx/qmp_lexer.py',
|
meson.source_root() / 'docs/sphinx/qmp_lexer.py',
|
||||||
qapi_gen_depends ]
|
qapi_gen_depends ]
|
||||||
|
|
||||||
|
have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT')
|
||||||
|
|
||||||
man_pages = {
|
man_pages = {
|
||||||
'qemu-ga.8': (have_tools ? 'man8' : ''),
|
'qemu-ga.8': (have_ga ? 'man8' : ''),
|
||||||
'qemu-ga-ref.7': 'man7',
|
'qemu-ga-ref.7': (have_ga ? 'man7' : ''),
|
||||||
'qemu-qmp-ref.7': 'man7',
|
'qemu-qmp-ref.7': 'man7',
|
||||||
'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''),
|
'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''),
|
||||||
'qemu-img.1': (have_tools ? 'man1' : ''),
|
'qemu-img.1': (have_tools ? 'man1' : ''),
|
||||||
|
@ -131,8 +131,16 @@ static const struct MemoryRegionOps imx7_set_clr_tog_ops = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void imx7_digprog_write(void *opaque, hwaddr addr,
|
||||||
|
uint64_t data, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"Guest write to read-only ANALOG_DIGPROG register\n");
|
||||||
|
}
|
||||||
|
|
||||||
static const struct MemoryRegionOps imx7_digprog_ops = {
|
static const struct MemoryRegionOps imx7_digprog_ops = {
|
||||||
.read = imx7_set_clr_tog_read,
|
.read = imx7_set_clr_tog_read,
|
||||||
|
.write = imx7_digprog_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||||
.impl = {
|
.impl = {
|
||||||
.min_access_size = 4,
|
.min_access_size = 4,
|
||||||
|
@ -196,7 +196,21 @@ static bool tz_ppc_dummy_accepts(void *opaque, hwaddr addr,
|
|||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t tz_ppc_dummy_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
|
{
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tz_ppc_dummy_write(void *opaque, hwaddr addr,
|
||||||
|
uint64_t data, unsigned size)
|
||||||
|
{
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps tz_ppc_dummy_ops = {
|
static const MemoryRegionOps tz_ppc_dummy_ops = {
|
||||||
|
/* define r/w methods to avoid assert failure in memory_region_init_io */
|
||||||
|
.read = tz_ppc_dummy_read,
|
||||||
|
.write = tz_ppc_dummy_write,
|
||||||
.valid.accepts = tz_ppc_dummy_accepts,
|
.valid.accepts = tz_ppc_dummy_accepts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,6 +273,15 @@ static const MemoryRegionOps io_ops = {
|
|||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint64_t flash_read(void *opaque, hwaddr offset, unsigned size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is a rom_device MemoryRegion which is always in
|
||||||
|
* romd_mode (we never put it in MMIO mode), so reads always
|
||||||
|
* go directly to RAM and never come here.
|
||||||
|
*/
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
static void flash_write(void *opaque, hwaddr offset, uint64_t value,
|
static void flash_write(void *opaque, hwaddr offset, uint64_t value,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
@ -300,6 +309,7 @@ static void flash_write(void *opaque, hwaddr offset, uint64_t value,
|
|||||||
|
|
||||||
|
|
||||||
static const MemoryRegionOps flash_ops = {
|
static const MemoryRegionOps flash_ops = {
|
||||||
|
.read = flash_read,
|
||||||
.write = flash_write,
|
.write = flash_write,
|
||||||
.valid.min_access_size = 4,
|
.valid.min_access_size = 4,
|
||||||
.valid.max_access_size = 4,
|
.valid.max_access_size = 4,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "hw/pci/pci_bridge.h"
|
#include "hw/pci/pci_bridge.h"
|
||||||
#include "hw/pci/pci_host.h"
|
#include "hw/pci/pci_host.h"
|
||||||
@ -63,6 +64,23 @@ designware_pcie_root_to_host(DesignwarePCIERoot *root)
|
|||||||
return DESIGNWARE_PCIE_HOST(bus->parent);
|
return DESIGNWARE_PCIE_HOST(bus->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t designware_pcie_root_msi_read(void *opaque, hwaddr addr,
|
||||||
|
unsigned size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Attempts to read from the MSI address are undefined in
|
||||||
|
* the PCI specifications. For this hardware, the datasheet
|
||||||
|
* specifies that a read from the magic address is simply not
|
||||||
|
* intercepted by the MSI controller, and will go out to the
|
||||||
|
* AHB/AXI bus like any other PCI-device-initiated DMA read.
|
||||||
|
* This is not trivial to implement in QEMU, so since
|
||||||
|
* well-behaved guests won't ever ask a PCI device to DMA from
|
||||||
|
* this address we just log the missing functionality.
|
||||||
|
*/
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
|
static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
|
||||||
uint64_t val, unsigned len)
|
uint64_t val, unsigned len)
|
||||||
{
|
{
|
||||||
@ -77,6 +95,7 @@ static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps designware_pci_host_msi_ops = {
|
static const MemoryRegionOps designware_pci_host_msi_ops = {
|
||||||
|
.read = designware_pcie_root_msi_read,
|
||||||
.write = designware_pcie_root_msi_write,
|
.write = designware_pcie_root_msi_write,
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
.valid = {
|
.valid = {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/datadir.h"
|
#include "qemu/datadir.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "hw/pci/pci_bus.h"
|
#include "hw/pci/pci_bus.h"
|
||||||
@ -121,8 +122,15 @@ static uint64_t raven_intack_read(void *opaque, hwaddr addr,
|
|||||||
return pic_read_irq(isa_pic);
|
return pic_read_irq(isa_pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raven_intack_write(void *opaque, hwaddr addr,
|
||||||
|
uint64_t data, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps raven_intack_ops = {
|
static const MemoryRegionOps raven_intack_ops = {
|
||||||
.read = raven_intack_read,
|
.read = raven_intack_read,
|
||||||
|
.write = raven_intack_write,
|
||||||
.valid = {
|
.valid = {
|
||||||
.max_access_size = 1,
|
.max_access_size = 1,
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/isa/isa.h"
|
#include "hw/isa/isa.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
@ -235,8 +236,15 @@ static uint64_t ppc_parity_error_readl(void *opaque, hwaddr addr,
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ppc_parity_error_writel(void *opaque, hwaddr addr,
|
||||||
|
uint64_t data, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps ppc_parity_error_ops = {
|
static const MemoryRegionOps ppc_parity_error_ops = {
|
||||||
.read = ppc_parity_error_readl,
|
.read = ppc_parity_error_readl,
|
||||||
|
.write = ppc_parity_error_writel,
|
||||||
.valid = {
|
.valid = {
|
||||||
.min_access_size = 4,
|
.min_access_size = 4,
|
||||||
.max_access_size = 4,
|
.max_access_size = 4,
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "sysemu/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "sysemu/numa.h"
|
#include "sysemu/numa.h"
|
||||||
#include "hw/ppc/spapr_numa.h"
|
#include "hw/ppc/spapr_numa.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
|
|
||||||
/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
|
/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
|
||||||
#define RTAS_QUERY_FN 0
|
#define RTAS_QUERY_FN 0
|
||||||
@ -739,6 +740,12 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
|
|||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t spapr_msi_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MSI/MSIX memory region implementation.
|
* MSI/MSIX memory region implementation.
|
||||||
* The handler handles both MSI and MSIX.
|
* The handler handles both MSI and MSIX.
|
||||||
@ -756,8 +763,11 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps spapr_msi_ops = {
|
static const MemoryRegionOps spapr_msi_ops = {
|
||||||
/* There is no .read as the read result is undefined by PCI spec */
|
/*
|
||||||
.read = NULL,
|
* .read result is undefined by PCI spec.
|
||||||
|
* define .read method to avoid assert failure in memory_region_init_io
|
||||||
|
*/
|
||||||
|
.read = spapr_msi_read,
|
||||||
.write = spapr_msi_write,
|
.write = spapr_msi_write,
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN
|
.endianness = DEVICE_LITTLE_ENDIAN
|
||||||
};
|
};
|
||||||
|
@ -126,6 +126,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
int vq_init_count = 0;
|
||||||
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||||
@ -153,17 +154,22 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vq_init_count++;
|
||||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
|
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
|
||||||
virtio_scsi_data_plane_handle_event);
|
virtio_scsi_data_plane_handle_event);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vq_init_count++;
|
||||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
|
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
|
||||||
virtio_scsi_data_plane_handle_cmd);
|
virtio_scsi_data_plane_handle_cmd);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
|
vq_init_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->dataplane_starting = false;
|
s->dataplane_starting = false;
|
||||||
@ -174,7 +180,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
|
|||||||
fail_vrings:
|
fail_vrings:
|
||||||
aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s);
|
aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s);
|
||||||
aio_context_release(s->ctx);
|
aio_context_release(s->ctx);
|
||||||
for (i = 0; i < vs->conf.num_queues + 2; i++) {
|
for (i = 0; i < vq_init_count; i++) {
|
||||||
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
|
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
|
||||||
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
|
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include CONFIG_DEVICES
|
#include CONFIG_DEVICES
|
||||||
#include "exec/memop.h"
|
#include "exec/memop.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
@ -264,8 +265,15 @@ static uint64_t vfio_ati_3c3_quirk_read(void *opaque,
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vfio_ati_3c3_quirk_write(void *opaque, hwaddr addr,
|
||||||
|
uint64_t data, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps vfio_ati_3c3_quirk = {
|
static const MemoryRegionOps vfio_ati_3c3_quirk = {
|
||||||
.read = vfio_ati_3c3_quirk_read,
|
.read = vfio_ati_3c3_quirk_read,
|
||||||
|
.write = vfio_ati_3c3_quirk_write,
|
||||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,13 +45,11 @@ DECLARE_OBJ_CHECKERS(IOMMUMemoryRegion, IOMMUMemoryRegionClass,
|
|||||||
#ifdef CONFIG_FUZZ
|
#ifdef CONFIG_FUZZ
|
||||||
void fuzz_dma_read_cb(size_t addr,
|
void fuzz_dma_read_cb(size_t addr,
|
||||||
size_t len,
|
size_t len,
|
||||||
MemoryRegion *mr,
|
MemoryRegion *mr);
|
||||||
bool is_write);
|
|
||||||
#else
|
#else
|
||||||
static inline void fuzz_dma_read_cb(size_t addr,
|
static inline void fuzz_dma_read_cb(size_t addr,
|
||||||
size_t len,
|
size_t len,
|
||||||
MemoryRegion *mr,
|
MemoryRegion *mr)
|
||||||
bool is_write)
|
|
||||||
{
|
{
|
||||||
/* Do Nothing */
|
/* Do Nothing */
|
||||||
}
|
}
|
||||||
@ -2514,7 +2512,7 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
|
|||||||
void *buf, hwaddr len)
|
void *buf, hwaddr len)
|
||||||
{
|
{
|
||||||
assert(addr < cache->len && len <= cache->len - addr);
|
assert(addr < cache->len && len <= cache->len - addr);
|
||||||
fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr, false);
|
fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr);
|
||||||
if (likely(cache->ptr)) {
|
if (likely(cache->ptr)) {
|
||||||
memcpy(buf, cache->ptr + addr, len);
|
memcpy(buf, cache->ptr + addr, len);
|
||||||
return MEMTX_OK;
|
return MEMTX_OK;
|
||||||
|
@ -28,7 +28,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache,
|
|||||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||||
{
|
{
|
||||||
assert(addr < cache->len && 4 <= cache->len - addr);
|
assert(addr < cache->len && 4 <= cache->len - addr);
|
||||||
fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr, false);
|
fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr);
|
||||||
if (likely(cache->ptr)) {
|
if (likely(cache->ptr)) {
|
||||||
return LD_P(l)(cache->ptr + addr);
|
return LD_P(l)(cache->ptr + addr);
|
||||||
} else {
|
} else {
|
||||||
@ -40,7 +40,7 @@ static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache,
|
|||||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||||
{
|
{
|
||||||
assert(addr < cache->len && 8 <= cache->len - addr);
|
assert(addr < cache->len && 8 <= cache->len - addr);
|
||||||
fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr, false);
|
fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr);
|
||||||
if (likely(cache->ptr)) {
|
if (likely(cache->ptr)) {
|
||||||
return LD_P(q)(cache->ptr + addr);
|
return LD_P(q)(cache->ptr + addr);
|
||||||
} else {
|
} else {
|
||||||
@ -52,7 +52,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache,
|
|||||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||||
{
|
{
|
||||||
assert(addr < cache->len && 2 <= cache->len - addr);
|
assert(addr < cache->len && 2 <= cache->len - addr);
|
||||||
fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr, false);
|
fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr);
|
||||||
if (likely(cache->ptr)) {
|
if (likely(cache->ptr)) {
|
||||||
return LD_P(uw)(cache->ptr + addr);
|
return LD_P(uw)(cache->ptr + addr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,6 +24,7 @@ struct EventNotifier {
|
|||||||
#else
|
#else
|
||||||
int rfd;
|
int rfd;
|
||||||
int wfd;
|
int wfd;
|
||||||
|
bool initialized;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
|
|||||||
MO_32 | devend_memop(endian), attrs);
|
MO_32 | devend_memop(endian), attrs);
|
||||||
} else {
|
} else {
|
||||||
/* RAM case */
|
/* RAM case */
|
||||||
fuzz_dma_read_cb(addr, 4, mr, false);
|
fuzz_dma_read_cb(addr, 4, mr);
|
||||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||||
switch (endian) {
|
switch (endian) {
|
||||||
case DEVICE_LITTLE_ENDIAN:
|
case DEVICE_LITTLE_ENDIAN:
|
||||||
@ -111,7 +111,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
|
|||||||
MO_64 | devend_memop(endian), attrs);
|
MO_64 | devend_memop(endian), attrs);
|
||||||
} else {
|
} else {
|
||||||
/* RAM case */
|
/* RAM case */
|
||||||
fuzz_dma_read_cb(addr, 8, mr, false);
|
fuzz_dma_read_cb(addr, 8, mr);
|
||||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||||
switch (endian) {
|
switch (endian) {
|
||||||
case DEVICE_LITTLE_ENDIAN:
|
case DEVICE_LITTLE_ENDIAN:
|
||||||
@ -177,7 +177,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
|
|||||||
r = memory_region_dispatch_read(mr, addr1, &val, MO_8, attrs);
|
r = memory_region_dispatch_read(mr, addr1, &val, MO_8, attrs);
|
||||||
} else {
|
} else {
|
||||||
/* RAM case */
|
/* RAM case */
|
||||||
fuzz_dma_read_cb(addr, 1, mr, false);
|
fuzz_dma_read_cb(addr, 1, mr);
|
||||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||||
val = ldub_p(ptr);
|
val = ldub_p(ptr);
|
||||||
r = MEMTX_OK;
|
r = MEMTX_OK;
|
||||||
@ -215,7 +215,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
|
|||||||
MO_16 | devend_memop(endian), attrs);
|
MO_16 | devend_memop(endian), attrs);
|
||||||
} else {
|
} else {
|
||||||
/* RAM case */
|
/* RAM case */
|
||||||
fuzz_dma_read_cb(addr, 2, mr, false);
|
fuzz_dma_read_cb(addr, 2, mr);
|
||||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||||
switch (endian) {
|
switch (endian) {
|
||||||
case DEVICE_LITTLE_ENDIAN:
|
case DEVICE_LITTLE_ENDIAN:
|
||||||
|
122
meson.build
122
meson.build
@ -18,6 +18,9 @@ config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
|
|||||||
enable_modules = 'CONFIG_MODULES' in config_host
|
enable_modules = 'CONFIG_MODULES' in config_host
|
||||||
enable_static = 'CONFIG_STATIC' in config_host
|
enable_static = 'CONFIG_STATIC' in config_host
|
||||||
|
|
||||||
|
# Allow both shared and static libraries unless --enable-static
|
||||||
|
static_kwargs = enable_static ? {'static': true} : {}
|
||||||
|
|
||||||
# Temporary directory used for files created while
|
# Temporary directory used for files created while
|
||||||
# configure runs. Since it is in the build directory
|
# configure runs. Since it is in the build directory
|
||||||
# we can safely blow away any previous version of it
|
# we can safely blow away any previous version of it
|
||||||
@ -224,10 +227,17 @@ tcg_arch = config_host['ARCH']
|
|||||||
if not get_option('tcg').disabled()
|
if not get_option('tcg').disabled()
|
||||||
if cpu not in supported_cpus
|
if cpu not in supported_cpus
|
||||||
if get_option('tcg_interpreter')
|
if get_option('tcg_interpreter')
|
||||||
warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
|
warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
|
||||||
else
|
else
|
||||||
error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
|
error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
|
||||||
endif
|
endif
|
||||||
|
elif get_option('tcg_interpreter')
|
||||||
|
warning('Use of the TCG interpretor is not recommended on this host')
|
||||||
|
warning('architecture. There is a native TCG execution backend available')
|
||||||
|
warning('which provides substantially better performance and reliability.')
|
||||||
|
warning('It is strongly recommended to remove the --enable-tcg-interpreter')
|
||||||
|
warning('configuration option on this architecture to use the native')
|
||||||
|
warning('backend.')
|
||||||
endif
|
endif
|
||||||
if get_option('tcg_interpreter')
|
if get_option('tcg_interpreter')
|
||||||
tcg_arch = 'tci'
|
tcg_arch = 'tci'
|
||||||
@ -311,14 +321,14 @@ endif
|
|||||||
pixman = not_found
|
pixman = not_found
|
||||||
if have_system or have_tools
|
if have_system or have_tools
|
||||||
pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
|
pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
pam = not_found
|
pam = not_found
|
||||||
if 'CONFIG_AUTH_PAM' in config_host
|
if 'CONFIG_AUTH_PAM' in config_host
|
||||||
pam = cc.find_library('pam')
|
pam = cc.find_library('pam')
|
||||||
endif
|
endif
|
||||||
libaio = cc.find_library('aio', required: false)
|
libaio = cc.find_library('aio', required: false)
|
||||||
zlib = dependency('zlib', required: true, static: enable_static)
|
zlib = dependency('zlib', required: true, kwargs: static_kwargs)
|
||||||
linux_io_uring = not_found
|
linux_io_uring = not_found
|
||||||
if 'CONFIG_LINUX_IO_URING' in config_host
|
if 'CONFIG_LINUX_IO_URING' in config_host
|
||||||
linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
|
linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
|
||||||
@ -333,7 +343,7 @@ libnfs = not_found
|
|||||||
if not get_option('libnfs').auto() or have_block
|
if not get_option('libnfs').auto() or have_block
|
||||||
libnfs = dependency('libnfs', version: '>=1.9.3',
|
libnfs = dependency('libnfs', version: '>=1.9.3',
|
||||||
required: get_option('libnfs'),
|
required: get_option('libnfs'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libattr_test = '''
|
libattr_test = '''
|
||||||
@ -354,7 +364,7 @@ if not get_option('attr').disabled()
|
|||||||
else
|
else
|
||||||
libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
|
libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
|
||||||
required: get_option('attr'),
|
required: get_option('attr'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if libattr.found() and not \
|
if libattr.found() and not \
|
||||||
cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
|
cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
|
||||||
libattr = not_found
|
libattr = not_found
|
||||||
@ -381,14 +391,14 @@ seccomp = not_found
|
|||||||
if not get_option('seccomp').auto() or have_system or have_tools
|
if not get_option('seccomp').auto() or have_system or have_tools
|
||||||
seccomp = dependency('libseccomp', version: '>=2.3.0',
|
seccomp = dependency('libseccomp', version: '>=2.3.0',
|
||||||
required: get_option('seccomp'),
|
required: get_option('seccomp'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libcap_ng = not_found
|
libcap_ng = not_found
|
||||||
if not get_option('cap_ng').auto() or have_system or have_tools
|
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'],
|
libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
|
||||||
required: get_option('cap_ng'),
|
required: get_option('cap_ng'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
if libcap_ng.found() and not cc.links('''
|
if libcap_ng.found() and not cc.links('''
|
||||||
#include <cap-ng.h>
|
#include <cap-ng.h>
|
||||||
@ -409,7 +419,7 @@ if get_option('xkbcommon').auto() and not have_system and not have_tools
|
|||||||
xkbcommon = not_found
|
xkbcommon = not_found
|
||||||
else
|
else
|
||||||
xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
|
xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
vde = not_found
|
vde = not_found
|
||||||
if config_host.has_key('CONFIG_VDE')
|
if config_host.has_key('CONFIG_VDE')
|
||||||
@ -445,13 +455,13 @@ libiscsi = not_found
|
|||||||
if not get_option('libiscsi').auto() or have_block
|
if not get_option('libiscsi').auto() or have_block
|
||||||
libiscsi = dependency('libiscsi', version: '>=1.9.0',
|
libiscsi = dependency('libiscsi', version: '>=1.9.0',
|
||||||
required: get_option('libiscsi'),
|
required: get_option('libiscsi'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
zstd = not_found
|
zstd = not_found
|
||||||
if not get_option('zstd').auto() or have_block
|
if not get_option('zstd').auto() or have_block
|
||||||
zstd = dependency('libzstd', version: '>=1.4.0',
|
zstd = dependency('libzstd', version: '>=1.4.0',
|
||||||
required: get_option('zstd'),
|
required: get_option('zstd'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
gbm = not_found
|
gbm = not_found
|
||||||
if 'CONFIG_GBM' in config_host
|
if 'CONFIG_GBM' in config_host
|
||||||
@ -468,14 +478,14 @@ if not get_option('curl').auto() or have_block
|
|||||||
curl = dependency('libcurl', version: '>=7.29.0',
|
curl = dependency('libcurl', version: '>=7.29.0',
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
required: get_option('curl'),
|
required: get_option('curl'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
libudev = not_found
|
libudev = not_found
|
||||||
if targetos == 'linux' and (have_system or have_tools)
|
if targetos == 'linux' and (have_system or have_tools)
|
||||||
libudev = dependency('libudev',
|
libudev = dependency('libudev',
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
required: get_option('libudev'),
|
required: get_option('libudev'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
mpathlibs = [libudev]
|
mpathlibs = [libudev]
|
||||||
@ -511,17 +521,17 @@ if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
|
|||||||
}'''
|
}'''
|
||||||
libmpathpersist = cc.find_library('mpathpersist',
|
libmpathpersist = cc.find_library('mpathpersist',
|
||||||
required: get_option('mpath'),
|
required: get_option('mpath'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if libmpathpersist.found()
|
if libmpathpersist.found()
|
||||||
mpathlibs += libmpathpersist
|
mpathlibs += libmpathpersist
|
||||||
if enable_static
|
if enable_static
|
||||||
mpathlibs += cc.find_library('devmapper',
|
mpathlibs += cc.find_library('devmapper',
|
||||||
required: get_option('mpath'),
|
required: get_option('mpath'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
mpathlibs += cc.find_library('multipath',
|
mpathlibs += cc.find_library('multipath',
|
||||||
required: get_option('mpath'),
|
required: get_option('mpath'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
foreach lib: mpathlibs
|
foreach lib: mpathlibs
|
||||||
if not lib.found()
|
if not lib.found()
|
||||||
mpathlibs = []
|
mpathlibs = []
|
||||||
@ -571,7 +581,7 @@ if have_system and not get_option('curses').disabled()
|
|||||||
curses = dependency(curses_dep,
|
curses = dependency(curses_dep,
|
||||||
required: false,
|
required: false,
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
msg = get_option('curses').enabled() ? 'curses library not found' : ''
|
msg = get_option('curses').enabled() ? 'curses library not found' : ''
|
||||||
@ -596,7 +606,7 @@ if have_system and not get_option('curses').disabled()
|
|||||||
foreach curses_libname : curses_libname_list
|
foreach curses_libname : curses_libname_list
|
||||||
libcurses = cc.find_library(curses_libname,
|
libcurses = cc.find_library(curses_libname,
|
||||||
required: false,
|
required: false,
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if libcurses.found()
|
if libcurses.found()
|
||||||
if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
|
if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
|
||||||
curses = declare_dependency(compile_args: curses_compile_args,
|
curses = declare_dependency(compile_args: curses_compile_args,
|
||||||
@ -647,7 +657,7 @@ brlapi = not_found
|
|||||||
if not get_option('brlapi').auto() or have_system
|
if not get_option('brlapi').auto() or have_system
|
||||||
brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
|
brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
|
||||||
required: get_option('brlapi'),
|
required: get_option('brlapi'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if brlapi.found() and not cc.links('''
|
if brlapi.found() and not cc.links('''
|
||||||
#include <brlapi.h>
|
#include <brlapi.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -663,7 +673,7 @@ endif
|
|||||||
|
|
||||||
sdl = not_found
|
sdl = not_found
|
||||||
if not get_option('sdl').auto() or (have_system and not cocoa.found())
|
if not get_option('sdl').auto() or (have_system and not cocoa.found())
|
||||||
sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
|
sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
|
||||||
sdl_image = not_found
|
sdl_image = not_found
|
||||||
endif
|
endif
|
||||||
if sdl.found()
|
if sdl.found()
|
||||||
@ -671,7 +681,7 @@ if sdl.found()
|
|||||||
sdl = declare_dependency(compile_args: '-Wno-undef',
|
sdl = declare_dependency(compile_args: '-Wno-undef',
|
||||||
dependencies: sdl)
|
dependencies: sdl)
|
||||||
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
else
|
else
|
||||||
if get_option('sdl_image').enabled()
|
if get_option('sdl_image').enabled()
|
||||||
error('sdl-image required, but SDL was @0@'.format(
|
error('sdl-image required, but SDL was @0@'.format(
|
||||||
@ -683,11 +693,12 @@ endif
|
|||||||
rbd = not_found
|
rbd = not_found
|
||||||
if not get_option('rbd').auto() or have_block
|
if not get_option('rbd').auto() or have_block
|
||||||
librados = cc.find_library('rados', required: get_option('rbd'),
|
librados = cc.find_library('rados', required: get_option('rbd'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
|
librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
|
||||||
required: get_option('rbd'),
|
required: get_option('rbd'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if librados.found() and librbd.found() and cc.links('''
|
if librados.found() and librbd.found()
|
||||||
|
if cc.links('''
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <rbd/librbd.h>
|
#include <rbd/librbd.h>
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@ -696,6 +707,11 @@ if not get_option('rbd').auto() or have_block
|
|||||||
return 0;
|
return 0;
|
||||||
}''', dependencies: [librbd, librados])
|
}''', dependencies: [librbd, librados])
|
||||||
rbd = declare_dependency(dependencies: [librbd, librados])
|
rbd = declare_dependency(dependencies: [librbd, librados])
|
||||||
|
elif get_option('rbd').enabled()
|
||||||
|
error('could not link librados')
|
||||||
|
else
|
||||||
|
warning('could not link librados, disabling')
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -705,7 +721,7 @@ glusterfs_iocb_has_stat = false
|
|||||||
if not get_option('glusterfs').auto() or have_block
|
if not get_option('glusterfs').auto() or have_block
|
||||||
glusterfs = dependency('glusterfs-api', version: '>=3',
|
glusterfs = dependency('glusterfs-api', version: '>=3',
|
||||||
required: get_option('glusterfs'),
|
required: get_option('glusterfs'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
if glusterfs.found()
|
if glusterfs.found()
|
||||||
glusterfs_ftruncate_has_stat = cc.links('''
|
glusterfs_ftruncate_has_stat = cc.links('''
|
||||||
#include <glusterfs/api/glfs.h>
|
#include <glusterfs/api/glfs.h>
|
||||||
@ -744,7 +760,7 @@ libbzip2 = not_found
|
|||||||
if not get_option('bzip2').auto() or have_block
|
if not get_option('bzip2').auto() or have_block
|
||||||
libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
|
libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
|
||||||
required: get_option('bzip2'),
|
required: get_option('bzip2'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if libbzip2.found() and not cc.links('''
|
if libbzip2.found() and not cc.links('''
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
|
int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
|
||||||
@ -761,7 +777,7 @@ liblzfse = not_found
|
|||||||
if not get_option('lzfse').auto() or have_block
|
if not get_option('lzfse').auto() or have_block
|
||||||
liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
|
liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
|
||||||
required: get_option('lzfse'),
|
required: get_option('lzfse'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
if liblzfse.found() and not cc.links('''
|
if liblzfse.found() and not cc.links('''
|
||||||
#include <lzfse.h>
|
#include <lzfse.h>
|
||||||
@ -798,12 +814,12 @@ if not get_option('gtk').auto() or (have_system and not cocoa.found())
|
|||||||
gtk = dependency('gtk+-3.0', version: '>=3.22.0',
|
gtk = dependency('gtk+-3.0', version: '>=3.22.0',
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
required: get_option('gtk'),
|
required: get_option('gtk'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if gtk.found()
|
if gtk.found()
|
||||||
gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
|
gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
required: false,
|
required: false,
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
gtk = declare_dependency(dependencies: [gtk, gtkx11])
|
gtk = declare_dependency(dependencies: [gtk, gtkx11])
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -816,7 +832,7 @@ endif
|
|||||||
x11 = not_found
|
x11 = not_found
|
||||||
if gtkx11.found() or 'lm32-softmmu' in target_dirs
|
if gtkx11.found() or 'lm32-softmmu' in target_dirs
|
||||||
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
|
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
vnc = not_found
|
vnc = not_found
|
||||||
png = not_found
|
png = not_found
|
||||||
@ -825,12 +841,12 @@ sasl = not_found
|
|||||||
if get_option('vnc').enabled()
|
if get_option('vnc').enabled()
|
||||||
vnc = declare_dependency() # dummy dependency
|
vnc = declare_dependency() # dummy dependency
|
||||||
png = dependency('libpng', required: get_option('vnc_png'),
|
png = dependency('libpng', required: get_option('vnc_png'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
|
jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
|
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
|
||||||
required: get_option('vnc_sasl'),
|
required: get_option('vnc_sasl'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
if sasl.found()
|
if sasl.found()
|
||||||
sasl = declare_dependency(dependencies: sasl,
|
sasl = declare_dependency(dependencies: sasl,
|
||||||
compile_args: '-DSTRUCT_IOVEC_DEFINED')
|
compile_args: '-DSTRUCT_IOVEC_DEFINED')
|
||||||
@ -841,7 +857,7 @@ snappy = not_found
|
|||||||
if not get_option('snappy').auto() or have_system
|
if not get_option('snappy').auto() or have_system
|
||||||
snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
|
snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
|
||||||
required: get_option('snappy'),
|
required: get_option('snappy'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
if snappy.found() and not cc.links('''
|
if snappy.found() and not cc.links('''
|
||||||
#include <snappy-c.h>
|
#include <snappy-c.h>
|
||||||
@ -858,7 +874,7 @@ lzo = not_found
|
|||||||
if not get_option('lzo').auto() or have_system
|
if not get_option('lzo').auto() or have_system
|
||||||
lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
|
lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
|
||||||
required: get_option('lzo'),
|
required: get_option('lzo'),
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
if lzo.found() and not cc.links('''
|
if lzo.found() and not cc.links('''
|
||||||
#include <lzo/lzo1x.h>
|
#include <lzo/lzo1x.h>
|
||||||
@ -893,7 +909,7 @@ u2f = not_found
|
|||||||
if have_system
|
if have_system
|
||||||
u2f = dependency('u2f-emu', required: get_option('u2f'),
|
u2f = dependency('u2f-emu', required: get_option('u2f'),
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
endif
|
endif
|
||||||
usbredir = not_found
|
usbredir = not_found
|
||||||
if 'CONFIG_USB_REDIR' in config_host
|
if 'CONFIG_USB_REDIR' in config_host
|
||||||
@ -920,7 +936,7 @@ if 'CONFIG_TASN1' in config_host
|
|||||||
link_args: config_host['TASN1_LIBS'].split())
|
link_args: config_host['TASN1_LIBS'].split())
|
||||||
endif
|
endif
|
||||||
keyutils = dependency('libkeyutils', required: false,
|
keyutils = dependency('libkeyutils', required: false,
|
||||||
method: 'pkg-config', static: enable_static)
|
method: 'pkg-config', kwargs: static_kwargs)
|
||||||
|
|
||||||
has_gettid = cc.has_function('gettid')
|
has_gettid = cc.has_function('gettid')
|
||||||
|
|
||||||
@ -979,7 +995,7 @@ endif
|
|||||||
|
|
||||||
fuse = dependency('fuse3', required: get_option('fuse'),
|
fuse = dependency('fuse3', required: get_option('fuse'),
|
||||||
version: '>=3.1', method: 'pkg-config',
|
version: '>=3.1', method: 'pkg-config',
|
||||||
static: enable_static)
|
kwargs: static_kwargs)
|
||||||
|
|
||||||
fuse_lseek = not_found
|
fuse_lseek = not_found
|
||||||
if not get_option('fuse_lseek').disabled()
|
if not get_option('fuse_lseek').disabled()
|
||||||
@ -1367,7 +1383,7 @@ capstone_opt = get_option('capstone')
|
|||||||
if capstone_opt in ['enabled', 'auto', 'system']
|
if capstone_opt in ['enabled', 'auto', 'system']
|
||||||
have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
|
have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
|
||||||
capstone = dependency('capstone', version: '>=4.0',
|
capstone = dependency('capstone', version: '>=4.0',
|
||||||
static: enable_static, method: 'pkg-config',
|
kwargs: static_kwargs, method: 'pkg-config',
|
||||||
required: capstone_opt == 'system' or
|
required: capstone_opt == 'system' or
|
||||||
capstone_opt == 'enabled' and not have_internal)
|
capstone_opt == 'enabled' and not have_internal)
|
||||||
if capstone.found()
|
if capstone.found()
|
||||||
@ -1477,7 +1493,7 @@ if have_system
|
|||||||
slirp_opt = get_option('slirp')
|
slirp_opt = get_option('slirp')
|
||||||
if slirp_opt in ['enabled', 'auto', 'system']
|
if slirp_opt in ['enabled', 'auto', 'system']
|
||||||
have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
|
have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
|
||||||
slirp = dependency('slirp', static: enable_static,
|
slirp = dependency('slirp', kwargs: static_kwargs,
|
||||||
method: 'pkg-config',
|
method: 'pkg-config',
|
||||||
required: slirp_opt == 'system' or
|
required: slirp_opt == 'system' or
|
||||||
slirp_opt == 'enabled' and not have_internal)
|
slirp_opt == 'enabled' and not have_internal)
|
||||||
@ -1556,7 +1572,7 @@ fdt_opt = get_option('fdt')
|
|||||||
if have_system
|
if have_system
|
||||||
if fdt_opt in ['enabled', 'auto', 'system']
|
if fdt_opt in ['enabled', 'auto', 'system']
|
||||||
have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
|
have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
|
||||||
fdt = cc.find_library('fdt', static: enable_static,
|
fdt = cc.find_library('fdt', kwargs: static_kwargs,
|
||||||
required: fdt_opt == 'system' or
|
required: fdt_opt == 'system' or
|
||||||
fdt_opt == 'enabled' and not have_internal)
|
fdt_opt == 'enabled' and not have_internal)
|
||||||
if fdt.found() and cc.links('''
|
if fdt.found() and cc.links('''
|
||||||
@ -1725,10 +1741,11 @@ target_softmmu_arch = {}
|
|||||||
# TODO: add each directory to the subdirs from its own meson.build, once
|
# TODO: add each directory to the subdirs from its own meson.build, once
|
||||||
# we have those
|
# we have those
|
||||||
trace_events_subdirs = [
|
trace_events_subdirs = [
|
||||||
'accel/kvm',
|
|
||||||
'accel/tcg',
|
|
||||||
'crypto',
|
'crypto',
|
||||||
|
'qapi',
|
||||||
|
'qom',
|
||||||
'monitor',
|
'monitor',
|
||||||
|
'util',
|
||||||
]
|
]
|
||||||
if have_user
|
if have_user
|
||||||
trace_events_subdirs += [ 'linux-user' ]
|
trace_events_subdirs += [ 'linux-user' ]
|
||||||
@ -1744,6 +1761,7 @@ if have_block
|
|||||||
endif
|
endif
|
||||||
if have_system
|
if have_system
|
||||||
trace_events_subdirs += [
|
trace_events_subdirs += [
|
||||||
|
'accel/kvm',
|
||||||
'audio',
|
'audio',
|
||||||
'backends',
|
'backends',
|
||||||
'backends/tpm',
|
'backends/tpm',
|
||||||
@ -1801,10 +1819,10 @@ if have_system
|
|||||||
'ui',
|
'ui',
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
if have_system or have_user
|
||||||
trace_events_subdirs += [
|
trace_events_subdirs += [
|
||||||
|
'accel/tcg',
|
||||||
'hw/core',
|
'hw/core',
|
||||||
'qapi',
|
|
||||||
'qom',
|
|
||||||
'target/arm',
|
'target/arm',
|
||||||
'target/hppa',
|
'target/hppa',
|
||||||
'target/i386',
|
'target/i386',
|
||||||
@ -1814,8 +1832,8 @@ trace_events_subdirs += [
|
|||||||
'target/riscv',
|
'target/riscv',
|
||||||
'target/s390x',
|
'target/s390x',
|
||||||
'target/sparc',
|
'target/sparc',
|
||||||
'util',
|
|
||||||
]
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
vhost_user = not_found
|
vhost_user = not_found
|
||||||
if 'CONFIG_VHOST_USER' in config_host
|
if 'CONFIG_VHOST_USER' in config_host
|
||||||
@ -1849,18 +1867,21 @@ libqemuutil = static_library('qemuutil',
|
|||||||
qemuutil = declare_dependency(link_with: libqemuutil,
|
qemuutil = declare_dependency(link_with: libqemuutil,
|
||||||
sources: genh + version_res)
|
sources: genh + version_res)
|
||||||
|
|
||||||
|
if have_system or have_user
|
||||||
decodetree = generator(find_program('scripts/decodetree.py'),
|
decodetree = generator(find_program('scripts/decodetree.py'),
|
||||||
output: 'decode-@BASENAME@.c.inc',
|
output: 'decode-@BASENAME@.c.inc',
|
||||||
arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
|
arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
|
||||||
|
subdir('libdecnumber')
|
||||||
|
subdir('target')
|
||||||
|
endif
|
||||||
|
|
||||||
subdir('audio')
|
subdir('audio')
|
||||||
subdir('io')
|
subdir('io')
|
||||||
subdir('chardev')
|
subdir('chardev')
|
||||||
subdir('fsdev')
|
subdir('fsdev')
|
||||||
subdir('libdecnumber')
|
|
||||||
subdir('target')
|
|
||||||
subdir('dump')
|
subdir('dump')
|
||||||
|
|
||||||
|
if have_block
|
||||||
block_ss.add(files(
|
block_ss.add(files(
|
||||||
'block.c',
|
'block.c',
|
||||||
'blockjob.c',
|
'blockjob.c',
|
||||||
@ -1884,6 +1905,7 @@ blockdev_ss.add(files(
|
|||||||
# os-win32.c does not
|
# os-win32.c does not
|
||||||
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
|
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
|
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
|
||||||
|
endif
|
||||||
|
|
||||||
common_ss.add(files('cpus-common.c'))
|
common_ss.add(files('cpus-common.c'))
|
||||||
|
|
||||||
@ -2500,8 +2522,12 @@ if have_system
|
|||||||
endif
|
endif
|
||||||
summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
|
summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
|
||||||
if config_all.has_key('CONFIG_TCG')
|
if config_all.has_key('CONFIG_TCG')
|
||||||
|
if get_option('tcg_interpreter')
|
||||||
|
summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
|
||||||
|
else
|
||||||
|
summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
|
||||||
|
endif
|
||||||
summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
|
summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
|
||||||
summary_info += {'TCG interpreter': tcg_arch == 'tci'}
|
|
||||||
endif
|
endif
|
||||||
summary_info += {'target list': ' '.join(target_dirs)}
|
summary_info += {'target list': ' '.join(target_dirs)}
|
||||||
if have_system
|
if have_system
|
||||||
|
@ -40,7 +40,7 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto',
|
|||||||
option('tcg', type: 'feature', value: 'auto',
|
option('tcg', type: 'feature', value: 'auto',
|
||||||
description: 'TCG support')
|
description: 'TCG support')
|
||||||
option('tcg_interpreter', type: 'boolean', value: false,
|
option('tcg_interpreter', type: 'boolean', value: false,
|
||||||
description: 'TCG bytecode interpreter (TCI)')
|
description: 'TCG with bytecode interpreter (experimental and slow)')
|
||||||
option('cfi', type: 'boolean', value: 'false',
|
option('cfi', type: 'boolean', value: 'false',
|
||||||
description: 'Control-Flow Integrity (CFI)')
|
description: 'Control-Flow Integrity (CFI)')
|
||||||
option('cfi_debug', type: 'boolean', value: 'false',
|
option('cfi_debug', type: 'boolean', value: 'false',
|
||||||
|
@ -9,7 +9,7 @@ if install_edk2_blobs
|
|||||||
]
|
]
|
||||||
configure_file(input: files(f),
|
configure_file(input: files(f),
|
||||||
output: f,
|
output: f,
|
||||||
configuration: {'DATADIR': qemu_datadir},
|
configuration: {'DATADIR': get_option('prefix') / qemu_datadir},
|
||||||
install: get_option('install_blobs'),
|
install: get_option('install_blobs'),
|
||||||
install_dir: qemu_datadir / 'firmware')
|
install_dir: qemu_datadir / 'firmware')
|
||||||
endforeach
|
endforeach
|
||||||
|
@ -12,6 +12,7 @@ if install_edk2_blobs
|
|||||||
|
|
||||||
foreach f : fds
|
foreach f : fds
|
||||||
custom_target(f,
|
custom_target(f,
|
||||||
|
build_by_default: have_system,
|
||||||
output: f,
|
output: f,
|
||||||
input: '@0@.bz2'.format(f),
|
input: '@0@.bz2'.format(f),
|
||||||
capture: true,
|
capture: true,
|
||||||
|
@ -4,18 +4,20 @@ util_ss.add(files(
|
|||||||
'qapi-dealloc-visitor.c',
|
'qapi-dealloc-visitor.c',
|
||||||
'qapi-util.c',
|
'qapi-util.c',
|
||||||
'qapi-visit-core.c',
|
'qapi-visit-core.c',
|
||||||
'qmp-dispatch.c',
|
|
||||||
'qmp-event.c',
|
|
||||||
'qmp-registry.c',
|
|
||||||
'qobject-input-visitor.c',
|
'qobject-input-visitor.c',
|
||||||
'qobject-output-visitor.c',
|
'qobject-output-visitor.c',
|
||||||
'string-input-visitor.c',
|
'string-input-visitor.c',
|
||||||
'string-output-visitor.c',
|
'string-output-visitor.c',
|
||||||
))
|
))
|
||||||
|
if have_system or have_tools
|
||||||
|
util_ss.add(files(
|
||||||
|
'qmp-dispatch.c',
|
||||||
|
'qmp-event.c',
|
||||||
|
'qmp-registry.c',
|
||||||
|
))
|
||||||
|
endif
|
||||||
|
|
||||||
qapi_all_modules = [
|
qapi_all_modules = [
|
||||||
'acpi',
|
|
||||||
'audio',
|
|
||||||
'authz',
|
'authz',
|
||||||
'block',
|
'block',
|
||||||
'block-core',
|
'block-core',
|
||||||
@ -35,20 +37,30 @@ qapi_all_modules = [
|
|||||||
'misc-target',
|
'misc-target',
|
||||||
'net',
|
'net',
|
||||||
'pragma',
|
'pragma',
|
||||||
'qdev',
|
|
||||||
'pci',
|
|
||||||
'qom',
|
'qom',
|
||||||
'rdma',
|
|
||||||
'replay',
|
'replay',
|
||||||
'rocker',
|
|
||||||
'run-state',
|
'run-state',
|
||||||
'sockets',
|
'sockets',
|
||||||
'tpm',
|
|
||||||
'trace',
|
'trace',
|
||||||
'transaction',
|
'transaction',
|
||||||
'ui',
|
|
||||||
'yank',
|
'yank',
|
||||||
]
|
]
|
||||||
|
if have_system
|
||||||
|
qapi_all_modules += [
|
||||||
|
'acpi',
|
||||||
|
'audio',
|
||||||
|
'qdev',
|
||||||
|
'pci',
|
||||||
|
'rdma',
|
||||||
|
'rocker',
|
||||||
|
'tpm',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
if have_system or have_tools
|
||||||
|
qapi_all_modules += [
|
||||||
|
'ui',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
qapi_storage_daemon_modules = [
|
qapi_storage_daemon_modules = [
|
||||||
'block-core',
|
'block-core',
|
||||||
|
@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
|||||||
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
|
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
|
||||||
" nvdimm=on|off controls NVDIMM support (default=off)\n"
|
" nvdimm=on|off controls NVDIMM support (default=off)\n"
|
||||||
" memory-encryption=@var{} memory encryption object to use (default=none)\n"
|
" memory-encryption=@var{} memory encryption object to use (default=none)\n"
|
||||||
" hmat=on|off controls ACPI HMAT support (default=off)\n",
|
" hmat=on|off controls ACPI HMAT support (default=off)\n"
|
||||||
|
" memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\n",
|
||||||
QEMU_ARCH_ALL)
|
QEMU_ARCH_ALL)
|
||||||
SRST
|
SRST
|
||||||
``-machine [type=]name[,prop=value[,...]]``
|
``-machine [type=]name[,prop=value[,...]]``
|
||||||
@ -96,6 +97,29 @@ SRST
|
|||||||
``hmat=on|off``
|
``hmat=on|off``
|
||||||
Enables or disables ACPI Heterogeneous Memory Attribute Table
|
Enables or disables ACPI Heterogeneous Memory Attribute Table
|
||||||
(HMAT) support. The default is off.
|
(HMAT) support. The default is off.
|
||||||
|
|
||||||
|
``memory-backend='id'``
|
||||||
|
An alternative to legacy ``-mem-path`` and ``mem-prealloc`` options.
|
||||||
|
Allows to use a memory backend as main RAM.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
::
|
||||||
|
-object memory-backend-file,id=pc.ram,size=512M,mem-path=/hugetlbfs,prealloc=on,share=on
|
||||||
|
-machine memory-backend=pc.ram
|
||||||
|
-m 512M
|
||||||
|
|
||||||
|
Migration compatibility note:
|
||||||
|
a) as backend id one shall use value of 'default-ram-id', advertised by
|
||||||
|
machine type (available via ``query-machines`` QMP command), if migration
|
||||||
|
to/from old QEMU (<5.0) is expected.
|
||||||
|
b) for machine types 4.0 and older, user shall
|
||||||
|
use ``x-use-canonical-path-for-ramblock-id=off`` backend option
|
||||||
|
if migration to/from old QEMU (<5.0) is expected.
|
||||||
|
For example:
|
||||||
|
::
|
||||||
|
-object memory-backend-ram,id=pc.ram,size=512M,x-use-canonical-path-for-ramblock-id=off
|
||||||
|
-machine memory-backend=pc.ram
|
||||||
|
-m 512M
|
||||||
ERST
|
ERST
|
||||||
|
|
||||||
HXCOMM Deprecated by -machine
|
HXCOMM Deprecated by -machine
|
||||||
|
@ -261,7 +261,7 @@ def clear_bits(newtrace, outpath):
|
|||||||
data_try = hex(int("".join(data_bin_list), 2))
|
data_try = hex(int("".join(data_bin_list), 2))
|
||||||
# It seems qtest only accepts padded hex-values.
|
# It seems qtest only accepts padded hex-values.
|
||||||
if len(data_try) % 2 == 1:
|
if len(data_try) % 2 == 1:
|
||||||
data_try = data_try[:2] + "0" + data_try[2:-1]
|
data_try = data_try[:2] + "0" + data_try[2:]
|
||||||
|
|
||||||
newtrace[i] = "{prefix} {data_try}\n".format(
|
newtrace[i] = "{prefix} {data_try}\n".format(
|
||||||
prefix=prefix,
|
prefix=prefix,
|
||||||
|
@ -90,14 +90,21 @@ static void cpu_throttle_timer_tick(void *opaque)
|
|||||||
|
|
||||||
void cpu_throttle_set(int new_throttle_pct)
|
void cpu_throttle_set(int new_throttle_pct)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* boolean to store whether throttle is already active or not,
|
||||||
|
* before modifying throttle_percentage
|
||||||
|
*/
|
||||||
|
bool throttle_active = cpu_throttle_active();
|
||||||
|
|
||||||
/* Ensure throttle percentage is within valid range */
|
/* Ensure throttle percentage is within valid range */
|
||||||
new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
|
new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
|
||||||
new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
|
new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
|
||||||
|
|
||||||
qatomic_set(&throttle_percentage, new_throttle_pct);
|
qatomic_set(&throttle_percentage, new_throttle_pct);
|
||||||
|
|
||||||
timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
|
if (!throttle_active) {
|
||||||
CPU_THROTTLE_TIMESLICE_NS);
|
cpu_throttle_timer_tick(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_throttle_stop(void)
|
void cpu_throttle_stop(void)
|
||||||
|
@ -1440,7 +1440,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
|
|||||||
unsigned size = memop_size(op);
|
unsigned size = memop_size(op);
|
||||||
MemTxResult r;
|
MemTxResult r;
|
||||||
|
|
||||||
fuzz_dma_read_cb(addr, size, mr, false);
|
fuzz_dma_read_cb(addr, size, mr);
|
||||||
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
|
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
|
||||||
*pval = unassigned_mem_read(mr, addr, size);
|
*pval = unassigned_mem_read(mr, addr, size);
|
||||||
return MEMTX_DECODE_ERROR;
|
return MEMTX_DECODE_ERROR;
|
||||||
@ -3285,8 +3285,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
|
|||||||
#ifdef CONFIG_FUZZ
|
#ifdef CONFIG_FUZZ
|
||||||
void __attribute__((weak)) fuzz_dma_read_cb(size_t addr,
|
void __attribute__((weak)) fuzz_dma_read_cb(size_t addr,
|
||||||
size_t len,
|
size_t len,
|
||||||
MemoryRegion *mr,
|
MemoryRegion *mr)
|
||||||
bool is_write)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2839,7 +2839,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
|||||||
stn_he_p(buf, l, val);
|
stn_he_p(buf, l, val);
|
||||||
} else {
|
} else {
|
||||||
/* RAM case */
|
/* RAM case */
|
||||||
fuzz_dma_read_cb(addr, len, mr, false);
|
fuzz_dma_read_cb(addr, len, mr);
|
||||||
ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
|
ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
|
||||||
memcpy(buf, ram_ptr, l);
|
memcpy(buf, ram_ptr, l);
|
||||||
}
|
}
|
||||||
@ -3200,7 +3200,7 @@ void *address_space_map(AddressSpace *as,
|
|||||||
memory_region_ref(mr);
|
memory_region_ref(mr);
|
||||||
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
|
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
|
||||||
l, is_write, attrs);
|
l, is_write, attrs);
|
||||||
fuzz_dma_read_cb(addr, *plen, mr, is_write);
|
fuzz_dma_read_cb(addr, *plen, mr);
|
||||||
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
|
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -53,4 +53,6 @@ endif
|
|||||||
if have_system
|
if have_system
|
||||||
stub_ss.add(files('semihost.c'))
|
stub_ss.add(files('semihost.c'))
|
||||||
stub_ss.add(files('xen-hw-stub.c'))
|
stub_ss.add(files('xen-hw-stub.c'))
|
||||||
|
else
|
||||||
|
stub_ss.add(files('qdev.c'))
|
||||||
endif
|
endif
|
||||||
|
23
stubs/qdev.c
Normal file
23
stubs/qdev.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* QOM stubs
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*
|
||||||
|
* 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 "qapi/qapi-events-qdev.h"
|
||||||
|
|
||||||
|
void qapi_event_send_device_deleted(bool has_device,
|
||||||
|
const char *device,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
/* Nothing to do. */
|
||||||
|
}
|
@ -667,7 +667,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
|
|||||||
CPUID_7_0_EBX_RDSEED */
|
CPUID_7_0_EBX_RDSEED */
|
||||||
#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
|
#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
|
||||||
/* CPUID_7_0_ECX_OSPKE is dynamic */ \
|
/* CPUID_7_0_ECX_OSPKE is dynamic */ \
|
||||||
CPUID_7_0_ECX_LA57)
|
CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS)
|
||||||
#define TCG_7_0_EDX_FEATURES 0
|
#define TCG_7_0_EDX_FEATURES 0
|
||||||
#define TCG_7_1_EAX_FEATURES 0
|
#define TCG_7_1_EAX_FEATURES 0
|
||||||
#define TCG_APM_FEATURES 0
|
#define TCG_APM_FEATURES 0
|
||||||
@ -926,11 +926,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
|||||||
"npt", "lbrv", "svm-lock", "nrip-save",
|
"npt", "lbrv", "svm-lock", "nrip-save",
|
||||||
"tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
|
"tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
|
||||||
NULL, NULL, "pause-filter", NULL,
|
NULL, NULL, "pause-filter", NULL,
|
||||||
"pfthreshold", NULL, NULL, NULL,
|
"pfthreshold", "avic", NULL, "v-vmsave-vmload",
|
||||||
NULL, NULL, NULL, NULL,
|
"vgif", NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
|
"svme-addr-chk", NULL, NULL, NULL,
|
||||||
},
|
},
|
||||||
.cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
|
.cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
|
||||||
.tcg_features = TCG_SVM_FEATURES,
|
.tcg_features = TCG_SVM_FEATURES,
|
||||||
@ -964,7 +964,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
|||||||
"la57", NULL, NULL, NULL,
|
"la57", NULL, NULL, NULL,
|
||||||
NULL, NULL, "rdpid", NULL,
|
NULL, NULL, "rdpid", NULL,
|
||||||
NULL, "cldemote", NULL, "movdiri",
|
NULL, "cldemote", NULL, "movdiri",
|
||||||
"movdir64b", NULL, NULL, NULL,
|
"movdir64b", NULL, NULL, "pks",
|
||||||
},
|
},
|
||||||
.cpuid = {
|
.cpuid = {
|
||||||
.eax = 7,
|
.eax = 7,
|
||||||
@ -1215,7 +1215,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
|||||||
"vmx-exit-save-efer", "vmx-exit-load-efer",
|
"vmx-exit-save-efer", "vmx-exit-load-efer",
|
||||||
"vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
|
"vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
|
||||||
NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
|
NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, "vmx-exit-load-pkrs", NULL, NULL,
|
||||||
},
|
},
|
||||||
.msr = {
|
.msr = {
|
||||||
.index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
|
.index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
|
||||||
@ -1230,7 +1230,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
|||||||
NULL, "vmx-entry-ia32e-mode", NULL, NULL,
|
NULL, "vmx-entry-ia32e-mode", NULL, NULL,
|
||||||
NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
|
NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
|
||||||
"vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
|
"vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, "vmx-entry-load-pkrs", NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
},
|
},
|
||||||
@ -5073,6 +5073,11 @@ static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
|
|||||||
} else {
|
} else {
|
||||||
return ~0;
|
return ~0;
|
||||||
}
|
}
|
||||||
|
#ifndef TARGET_X86_64
|
||||||
|
if (w == FEAT_8000_0001_EDX) {
|
||||||
|
r &= ~CPUID_EXT2_LM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (migratable_only) {
|
if (migratable_only) {
|
||||||
r &= x86_cpu_get_migratable_flags(w);
|
r &= x86_cpu_get_migratable_flags(w);
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,7 @@ typedef enum X86Seg {
|
|||||||
#define CR4_SMEP_MASK (1U << 20)
|
#define CR4_SMEP_MASK (1U << 20)
|
||||||
#define CR4_SMAP_MASK (1U << 21)
|
#define CR4_SMAP_MASK (1U << 21)
|
||||||
#define CR4_PKE_MASK (1U << 22)
|
#define CR4_PKE_MASK (1U << 22)
|
||||||
|
#define CR4_PKS_MASK (1U << 24)
|
||||||
|
|
||||||
#define DR6_BD (1 << 13)
|
#define DR6_BD (1 << 13)
|
||||||
#define DR6_BS (1 << 14)
|
#define DR6_BS (1 << 14)
|
||||||
@ -357,6 +358,7 @@ typedef enum X86Seg {
|
|||||||
|
|
||||||
#define MSR_IA32_TSX_CTRL 0x122
|
#define MSR_IA32_TSX_CTRL 0x122
|
||||||
#define MSR_IA32_TSCDEADLINE 0x6e0
|
#define MSR_IA32_TSCDEADLINE 0x6e0
|
||||||
|
#define MSR_IA32_PKRS 0x6e1
|
||||||
|
|
||||||
#define FEATURE_CONTROL_LOCKED (1<<0)
|
#define FEATURE_CONTROL_LOCKED (1<<0)
|
||||||
#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
|
#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
|
||||||
@ -680,6 +682,10 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
|||||||
#define CPUID_SVM_DECODEASSIST (1U << 7)
|
#define CPUID_SVM_DECODEASSIST (1U << 7)
|
||||||
#define CPUID_SVM_PAUSEFILTER (1U << 10)
|
#define CPUID_SVM_PAUSEFILTER (1U << 10)
|
||||||
#define CPUID_SVM_PFTHRESHOLD (1U << 12)
|
#define CPUID_SVM_PFTHRESHOLD (1U << 12)
|
||||||
|
#define CPUID_SVM_AVIC (1U << 13)
|
||||||
|
#define CPUID_SVM_V_VMSAVE_VMLOAD (1U << 15)
|
||||||
|
#define CPUID_SVM_VGIF (1U << 16)
|
||||||
|
#define CPUID_SVM_SVME_ADDR_CHK (1U << 28)
|
||||||
|
|
||||||
/* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
|
/* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
|
||||||
#define CPUID_7_0_EBX_FSGSBASE (1U << 0)
|
#define CPUID_7_0_EBX_FSGSBASE (1U << 0)
|
||||||
@ -768,6 +774,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
|||||||
#define CPUID_7_0_ECX_MOVDIRI (1U << 27)
|
#define CPUID_7_0_ECX_MOVDIRI (1U << 27)
|
||||||
/* Move 64 Bytes as Direct Store Instruction */
|
/* Move 64 Bytes as Direct Store Instruction */
|
||||||
#define CPUID_7_0_ECX_MOVDIR64B (1U << 28)
|
#define CPUID_7_0_ECX_MOVDIR64B (1U << 28)
|
||||||
|
/* Protection Keys for Supervisor-mode Pages */
|
||||||
|
#define CPUID_7_0_ECX_PKS (1U << 31)
|
||||||
|
|
||||||
/* AVX512 Neural Network Instructions */
|
/* AVX512 Neural Network Instructions */
|
||||||
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2)
|
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2)
|
||||||
@ -965,6 +973,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
|||||||
#define VMX_VM_EXIT_CLEAR_BNDCFGS 0x00800000
|
#define VMX_VM_EXIT_CLEAR_BNDCFGS 0x00800000
|
||||||
#define VMX_VM_EXIT_PT_CONCEAL_PIP 0x01000000
|
#define VMX_VM_EXIT_PT_CONCEAL_PIP 0x01000000
|
||||||
#define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000
|
#define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000
|
||||||
|
#define VMX_VM_EXIT_LOAD_IA32_PKRS 0x20000000
|
||||||
|
|
||||||
#define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004
|
#define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004
|
||||||
#define VMX_VM_ENTRY_IA32E_MODE 0x00000200
|
#define VMX_VM_ENTRY_IA32E_MODE 0x00000200
|
||||||
@ -976,6 +985,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
|||||||
#define VMX_VM_ENTRY_LOAD_BNDCFGS 0x00010000
|
#define VMX_VM_ENTRY_LOAD_BNDCFGS 0x00010000
|
||||||
#define VMX_VM_ENTRY_PT_CONCEAL_PIP 0x00020000
|
#define VMX_VM_ENTRY_PT_CONCEAL_PIP 0x00020000
|
||||||
#define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000
|
#define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000
|
||||||
|
#define VMX_VM_ENTRY_LOAD_IA32_PKRS 0x00400000
|
||||||
|
|
||||||
/* Supported Hyper-V Enlightenments */
|
/* Supported Hyper-V Enlightenments */
|
||||||
#define HYPERV_FEAT_RELAXED 0
|
#define HYPERV_FEAT_RELAXED 0
|
||||||
@ -1483,6 +1493,7 @@ typedef struct CPUX86State {
|
|||||||
uint64_t msr_smi_count;
|
uint64_t msr_smi_count;
|
||||||
|
|
||||||
uint32_t pkru;
|
uint32_t pkru;
|
||||||
|
uint32_t pkrs;
|
||||||
uint32_t tsx_ctrl;
|
uint32_t tsx_ctrl;
|
||||||
|
|
||||||
uint64_t spec_ctrl;
|
uint64_t spec_ctrl;
|
||||||
|
@ -194,6 +194,9 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
|
|||||||
if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
|
if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
|
||||||
new_cr4 &= ~CR4_PKE_MASK;
|
new_cr4 &= ~CR4_PKE_MASK;
|
||||||
}
|
}
|
||||||
|
if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
|
||||||
|
new_cr4 &= ~CR4_PKS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
env->cr[4] = new_cr4;
|
env->cr[4] = new_cr4;
|
||||||
env->hflags = hflags;
|
env->hflags = hflags;
|
||||||
|
@ -113,6 +113,7 @@ static bool has_msr_vmx_vmfunc;
|
|||||||
static bool has_msr_ucode_rev;
|
static bool has_msr_ucode_rev;
|
||||||
static bool has_msr_vmx_procbased_ctls2;
|
static bool has_msr_vmx_procbased_ctls2;
|
||||||
static bool has_msr_perf_capabs;
|
static bool has_msr_perf_capabs;
|
||||||
|
static bool has_msr_pkrs;
|
||||||
|
|
||||||
static uint32_t has_architectural_pmu_version;
|
static uint32_t has_architectural_pmu_version;
|
||||||
static uint32_t num_architectural_pmu_gp_counters;
|
static uint32_t num_architectural_pmu_gp_counters;
|
||||||
@ -2087,6 +2088,9 @@ static int kvm_get_supported_msrs(KVMState *s)
|
|||||||
case MSR_IA32_VMX_PROCBASED_CTLS2:
|
case MSR_IA32_VMX_PROCBASED_CTLS2:
|
||||||
has_msr_vmx_procbased_ctls2 = true;
|
has_msr_vmx_procbased_ctls2 = true;
|
||||||
break;
|
break;
|
||||||
|
case MSR_IA32_PKRS:
|
||||||
|
has_msr_pkrs = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2814,6 +2818,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
|||||||
if (has_msr_smi_count) {
|
if (has_msr_smi_count) {
|
||||||
kvm_msr_entry_add(cpu, MSR_SMI_COUNT, env->msr_smi_count);
|
kvm_msr_entry_add(cpu, MSR_SMI_COUNT, env->msr_smi_count);
|
||||||
}
|
}
|
||||||
|
if (has_msr_pkrs) {
|
||||||
|
kvm_msr_entry_add(cpu, MSR_IA32_PKRS, env->pkrs);
|
||||||
|
}
|
||||||
if (has_msr_bndcfgs) {
|
if (has_msr_bndcfgs) {
|
||||||
kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs);
|
kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs);
|
||||||
}
|
}
|
||||||
@ -3205,6 +3212,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
|||||||
if (has_msr_feature_control) {
|
if (has_msr_feature_control) {
|
||||||
kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0);
|
kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0);
|
||||||
}
|
}
|
||||||
|
if (has_msr_pkrs) {
|
||||||
|
kvm_msr_entry_add(cpu, MSR_IA32_PKRS, 0);
|
||||||
|
}
|
||||||
if (has_msr_bndcfgs) {
|
if (has_msr_bndcfgs) {
|
||||||
kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0);
|
kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0);
|
||||||
}
|
}
|
||||||
@ -3475,6 +3485,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
|||||||
case MSR_IA32_UMWAIT_CONTROL:
|
case MSR_IA32_UMWAIT_CONTROL:
|
||||||
env->umwait = msrs[i].data;
|
env->umwait = msrs[i].data;
|
||||||
break;
|
break;
|
||||||
|
case MSR_IA32_PKRS:
|
||||||
|
env->pkrs = msrs[i].data;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (msrs[i].index >= MSR_MC0_CTL &&
|
if (msrs[i].index >= MSR_MC0_CTL &&
|
||||||
msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
|
msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
|
||||||
|
@ -980,7 +980,6 @@ static const VMStateDescription vmstate_umwait = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TARGET_X86_64
|
|
||||||
static bool pkru_needed(void *opaque)
|
static bool pkru_needed(void *opaque)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = opaque;
|
X86CPU *cpu = opaque;
|
||||||
@ -999,7 +998,25 @@ static const VMStateDescription vmstate_pkru = {
|
|||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
static bool pkrs_needed(void *opaque)
|
||||||
|
{
|
||||||
|
X86CPU *cpu = opaque;
|
||||||
|
CPUX86State *env = &cpu->env;
|
||||||
|
|
||||||
|
return env->pkrs != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_pkrs = {
|
||||||
|
.name = "cpu/pkrs",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.needed = pkrs_needed,
|
||||||
|
.fields = (VMStateField[]){
|
||||||
|
VMSTATE_UINT32(env.pkrs, X86CPU),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static bool tsc_khz_needed(void *opaque)
|
static bool tsc_khz_needed(void *opaque)
|
||||||
{
|
{
|
||||||
@ -1480,9 +1497,8 @@ VMStateDescription vmstate_x86_cpu = {
|
|||||||
&vmstate_umwait,
|
&vmstate_umwait,
|
||||||
&vmstate_tsc_khz,
|
&vmstate_tsc_khz,
|
||||||
&vmstate_msr_smi_count,
|
&vmstate_msr_smi_count,
|
||||||
#ifdef TARGET_X86_64
|
|
||||||
&vmstate_pkru,
|
&vmstate_pkru,
|
||||||
#endif
|
&vmstate_pkrs,
|
||||||
&vmstate_spec_ctrl,
|
&vmstate_spec_ctrl,
|
||||||
&vmstate_mcg_ext_ctl,
|
&vmstate_mcg_ext_ctl,
|
||||||
&vmstate_msr_intel_pt,
|
&vmstate_msr_intel_pt,
|
||||||
|
@ -361,6 +361,7 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
|
|||||||
uint64_t rsvd_mask = PG_HI_RSVD_MASK;
|
uint64_t rsvd_mask = PG_HI_RSVD_MASK;
|
||||||
uint32_t page_offset;
|
uint32_t page_offset;
|
||||||
target_ulong vaddr;
|
target_ulong vaddr;
|
||||||
|
uint32_t pkr;
|
||||||
|
|
||||||
is_user = mmu_idx == MMU_USER_IDX;
|
is_user = mmu_idx == MMU_USER_IDX;
|
||||||
#if defined(DEBUG_MMU)
|
#if defined(DEBUG_MMU)
|
||||||
@ -588,21 +589,28 @@ do_check_protect_pse36:
|
|||||||
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
|
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
|
||||||
prot |= PAGE_EXEC;
|
prot |= PAGE_EXEC;
|
||||||
}
|
}
|
||||||
if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) &&
|
|
||||||
(ptep & PG_USER_MASK) && env->pkru) {
|
|
||||||
uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
|
|
||||||
uint32_t pkru_ad = (env->pkru >> pk * 2) & 1;
|
|
||||||
uint32_t pkru_wd = (env->pkru >> pk * 2) & 2;
|
|
||||||
uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
|
||||||
|
|
||||||
if (pkru_ad) {
|
if (!(env->hflags & HF_LMA_MASK)) {
|
||||||
pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
|
pkr = 0;
|
||||||
} else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
|
} else if (ptep & PG_USER_MASK) {
|
||||||
pkru_prot &= ~PAGE_WRITE;
|
pkr = env->cr[4] & CR4_PKE_MASK ? env->pkru : 0;
|
||||||
|
} else {
|
||||||
|
pkr = env->cr[4] & CR4_PKS_MASK ? env->pkrs : 0;
|
||||||
|
}
|
||||||
|
if (pkr) {
|
||||||
|
uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
|
||||||
|
uint32_t pkr_ad = (pkr >> pk * 2) & 1;
|
||||||
|
uint32_t pkr_wd = (pkr >> pk * 2) & 2;
|
||||||
|
uint32_t pkr_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
|
|
||||||
|
if (pkr_ad) {
|
||||||
|
pkr_prot &= ~(PAGE_READ | PAGE_WRITE);
|
||||||
|
} else if (pkr_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
|
||||||
|
pkr_prot &= ~PAGE_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
prot &= pkru_prot;
|
prot &= pkr_prot;
|
||||||
if ((pkru_prot & (1 << is_write1)) == 0) {
|
if ((pkr_prot & (1 << is_write1)) == 0) {
|
||||||
assert(is_write1 != 2);
|
assert(is_write1 != 2);
|
||||||
error_code |= PG_ERROR_PK_MASK;
|
error_code |= PG_ERROR_PK_MASK;
|
||||||
goto do_fault_protect;
|
goto do_fault_protect;
|
||||||
|
@ -244,6 +244,7 @@ void helper_rdmsr(CPUX86State *env)
|
|||||||
void helper_wrmsr(CPUX86State *env)
|
void helper_wrmsr(CPUX86State *env)
|
||||||
{
|
{
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
|
cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
|
||||||
|
|
||||||
@ -296,6 +297,13 @@ void helper_wrmsr(CPUX86State *env)
|
|||||||
case MSR_PAT:
|
case MSR_PAT:
|
||||||
env->pat = val;
|
env->pat = val;
|
||||||
break;
|
break;
|
||||||
|
case MSR_IA32_PKRS:
|
||||||
|
if (val & 0xFFFFFFFF00000000ull) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
env->pkrs = val;
|
||||||
|
tlb_flush(cs);
|
||||||
|
break;
|
||||||
case MSR_VM_HSAVE_PA:
|
case MSR_VM_HSAVE_PA:
|
||||||
env->vm_hsave = val;
|
env->vm_hsave = val;
|
||||||
break;
|
break;
|
||||||
@ -399,6 +407,9 @@ void helper_wrmsr(CPUX86State *env)
|
|||||||
/* XXX: exception? */
|
/* XXX: exception? */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_rdmsr(CPUX86State *env)
|
void helper_rdmsr(CPUX86State *env)
|
||||||
@ -430,6 +441,9 @@ void helper_rdmsr(CPUX86State *env)
|
|||||||
case MSR_PAT:
|
case MSR_PAT:
|
||||||
val = env->pat;
|
val = env->pat;
|
||||||
break;
|
break;
|
||||||
|
case MSR_IA32_PKRS:
|
||||||
|
val = env->pkrs;
|
||||||
|
break;
|
||||||
case MSR_VM_HSAVE_PA:
|
case MSR_VM_HSAVE_PA:
|
||||||
val = env->vm_hsave;
|
val = env->vm_hsave;
|
||||||
break;
|
break;
|
||||||
|
@ -3075,7 +3075,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
|||||||
}
|
}
|
||||||
if (is_xmm
|
if (is_xmm
|
||||||
&& !(s->flags & HF_OSFXSR_MASK)
|
&& !(s->flags & HF_OSFXSR_MASK)
|
||||||
&& ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
|
&& (b != 0x38 && b != 0x3a)) {
|
||||||
goto unknown_op;
|
goto unknown_op;
|
||||||
}
|
}
|
||||||
if (b == 0x0e) {
|
if (b == 0x0e) {
|
||||||
|
@ -86,7 +86,6 @@ tests = {
|
|||||||
'test-qobject-input-visitor': [testqapi],
|
'test-qobject-input-visitor': [testqapi],
|
||||||
'test-string-input-visitor': [testqapi],
|
'test-string-input-visitor': [testqapi],
|
||||||
'test-string-output-visitor': [testqapi],
|
'test-string-output-visitor': [testqapi],
|
||||||
'test-qmp-event': [testqapi],
|
|
||||||
'test-opts-visitor': [testqapi],
|
'test-opts-visitor': [testqapi],
|
||||||
'test-visitor-serialization': [testqapi],
|
'test-visitor-serialization': [testqapi],
|
||||||
'test-bitmap': [],
|
'test-bitmap': [],
|
||||||
@ -117,6 +116,12 @@ tests = {
|
|||||||
'test-qapi-util': [],
|
'test-qapi-util': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if have_system or have_tools
|
||||||
|
tests += {
|
||||||
|
'test-qmp-event': [testqapi],
|
||||||
|
}
|
||||||
|
endif
|
||||||
|
|
||||||
test_deps = {
|
test_deps = {
|
||||||
'test-qht-par': qht_bench,
|
'test-qht-par': qht_bench,
|
||||||
}
|
}
|
||||||
@ -276,7 +281,9 @@ test('decodetree', sh,
|
|||||||
workdir: meson.current_source_dir() / 'decode',
|
workdir: meson.current_source_dir() / 'decode',
|
||||||
suite: 'decodetree')
|
suite: 'decodetree')
|
||||||
|
|
||||||
|
if 'CONFIG_TCG' in config_all
|
||||||
subdir('fp')
|
subdir('fp')
|
||||||
|
endif
|
||||||
|
|
||||||
if not get_option('tcg').disabled()
|
if not get_option('tcg').disabled()
|
||||||
if 'CONFIG_PLUGIN' in config_host
|
if 'CONFIG_PLUGIN' in config_host
|
||||||
|
@ -159,6 +159,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
|
|||||||
char *target_name;
|
char *target_name;
|
||||||
const char *bindir;
|
const char *bindir;
|
||||||
char *datadir;
|
char *datadir;
|
||||||
|
GString *cmd_line;
|
||||||
|
gchar *pretty_cmd_line;
|
||||||
bool serialize = false;
|
bool serialize = false;
|
||||||
|
|
||||||
/* Initialize qgraph and modules */
|
/* Initialize qgraph and modules */
|
||||||
@ -217,7 +219,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Run QEMU's softmmu main with the fuzz-target dependent arguments */
|
/* Run QEMU's softmmu main with the fuzz-target dependent arguments */
|
||||||
GString *cmd_line = fuzz_target->get_init_cmdline(fuzz_target);
|
cmd_line = fuzz_target->get_init_cmdline(fuzz_target);
|
||||||
g_string_append_printf(cmd_line, " %s -qtest /dev/null ",
|
g_string_append_printf(cmd_line, " %s -qtest /dev/null ",
|
||||||
getenv("QTEST_LOG") ? "" : "-qtest-log none");
|
getenv("QTEST_LOG") ? "" : "-qtest-log none");
|
||||||
|
|
||||||
@ -226,6 +228,13 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
|
|||||||
wordexp(cmd_line->str, &result, 0);
|
wordexp(cmd_line->str, &result, 0);
|
||||||
g_string_free(cmd_line, true);
|
g_string_free(cmd_line, true);
|
||||||
|
|
||||||
|
if (getenv("QTEST_LOG")) {
|
||||||
|
pretty_cmd_line = g_strjoinv(" ", result.we_wordv + 1);
|
||||||
|
printf("Starting %s with Arguments: %s\n",
|
||||||
|
result.we_wordv[0], pretty_cmd_line);
|
||||||
|
g_free(pretty_cmd_line);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_init(result.we_wordc, result.we_wordv, NULL);
|
qemu_init(result.we_wordc, result.we_wordv, NULL);
|
||||||
|
|
||||||
/* re-enable the rcu atfork, which was previously disabled in qemu_init */
|
/* re-enable the rcu atfork, which was previously disabled in qemu_init */
|
||||||
|
@ -175,7 +175,7 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
|
|||||||
* generic_fuzz(), avoiding potential race-conditions, which we don't have
|
* generic_fuzz(), avoiding potential race-conditions, which we don't have
|
||||||
* a good way for reproducing right now.
|
* a good way for reproducing right now.
|
||||||
*/
|
*/
|
||||||
void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
|
void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
/* Are we in the generic-fuzzer or are we using another fuzz-target? */
|
/* Are we in the generic-fuzzer or are we using another fuzz-target? */
|
||||||
if (!qts_global) {
|
if (!qts_global) {
|
||||||
@ -187,14 +187,11 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
|
|||||||
* - We have no DMA patterns defined
|
* - We have no DMA patterns defined
|
||||||
* - The length of the DMA read request is zero
|
* - The length of the DMA read request is zero
|
||||||
* - The DMA read is hitting an MR other than the machine's main RAM
|
* - The DMA read is hitting an MR other than the machine's main RAM
|
||||||
* - The DMA request is not a read (what happens for a address_space_map
|
|
||||||
* with is_write=True? Can the device use the same pointer to do reads?)
|
|
||||||
* - The DMA request hits past the bounds of our RAM
|
* - The DMA request hits past the bounds of our RAM
|
||||||
*/
|
*/
|
||||||
if (dma_patterns->len == 0
|
if (dma_patterns->len == 0
|
||||||
|| len == 0
|
|| len == 0
|
||||||
|| mr != current_machine->ram
|
|| mr != current_machine->ram
|
||||||
|| is_write
|
|
||||||
|| addr > current_machine->ram_size) {
|
|| addr > current_machine->ram_size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -213,12 +210,12 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
|
|||||||
double_fetch = true;
|
double_fetch = true;
|
||||||
if (addr < region.addr
|
if (addr < region.addr
|
||||||
&& avoid_double_fetches) {
|
&& avoid_double_fetches) {
|
||||||
fuzz_dma_read_cb(addr, region.addr - addr, mr, is_write);
|
fuzz_dma_read_cb(addr, region.addr - addr, mr);
|
||||||
}
|
}
|
||||||
if (addr + len > region.addr + region.size
|
if (addr + len > region.addr + region.size
|
||||||
&& avoid_double_fetches) {
|
&& avoid_double_fetches) {
|
||||||
fuzz_dma_read_cb(region.addr + region.size,
|
fuzz_dma_read_cb(region.addr + region.size,
|
||||||
addr + len - (region.addr + region.size), mr, is_write);
|
addr + len - (region.addr + region.size), mr);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -936,12 +933,20 @@ static GString *generic_fuzz_cmdline(FuzzTarget *t)
|
|||||||
|
|
||||||
static GString *generic_fuzz_predefined_config_cmdline(FuzzTarget *t)
|
static GString *generic_fuzz_predefined_config_cmdline(FuzzTarget *t)
|
||||||
{
|
{
|
||||||
|
gchar *args;
|
||||||
const generic_fuzz_config *config;
|
const generic_fuzz_config *config;
|
||||||
g_assert(t->opaque);
|
g_assert(t->opaque);
|
||||||
|
|
||||||
config = t->opaque;
|
config = t->opaque;
|
||||||
setenv("QEMU_AVOID_DOUBLE_FETCH", "1", 1);
|
setenv("QEMU_AVOID_DOUBLE_FETCH", "1", 1);
|
||||||
|
if (config->argfunc) {
|
||||||
|
args = config->argfunc();
|
||||||
|
setenv("QEMU_FUZZ_ARGS", args, 1);
|
||||||
|
g_free(args);
|
||||||
|
} else {
|
||||||
|
g_assert_nonnull(config->args);
|
||||||
setenv("QEMU_FUZZ_ARGS", config->args, 1);
|
setenv("QEMU_FUZZ_ARGS", config->args, 1);
|
||||||
|
}
|
||||||
setenv("QEMU_FUZZ_OBJECTS", config->objects, 1);
|
setenv("QEMU_FUZZ_OBJECTS", config->objects, 1);
|
||||||
return generic_fuzz_cmdline(t);
|
return generic_fuzz_cmdline(t);
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,19 @@
|
|||||||
|
|
||||||
typedef struct generic_fuzz_config {
|
typedef struct generic_fuzz_config {
|
||||||
const char *name, *args, *objects;
|
const char *name, *args, *objects;
|
||||||
|
gchar* (*argfunc)(void); /* Result must be freeable by g_free() */
|
||||||
} generic_fuzz_config;
|
} generic_fuzz_config;
|
||||||
|
|
||||||
|
static inline gchar *generic_fuzzer_virtio_9p_args(void){
|
||||||
|
char tmpdir[] = "/tmp/qemu-fuzz.XXXXXX";
|
||||||
|
g_assert_nonnull(mkdtemp(tmpdir));
|
||||||
|
|
||||||
|
return g_strdup_printf("-machine q35 -nodefaults "
|
||||||
|
"-device virtio-9p,fsdev=hshare,mount_tag=hshare "
|
||||||
|
"-fsdev local,id=hshare,path=%s,security_model=mapped-xattr,"
|
||||||
|
"writeout=immediate,fmode=0600,dmode=0700", tmpdir);
|
||||||
|
}
|
||||||
|
|
||||||
const generic_fuzz_config predefined_configs[] = {
|
const generic_fuzz_config predefined_configs[] = {
|
||||||
{
|
{
|
||||||
.name = "virtio-net-pci-slirp",
|
.name = "virtio-net-pci-slirp",
|
||||||
@ -59,6 +70,16 @@ const generic_fuzz_config predefined_configs[] = {
|
|||||||
.name = "virtio-mouse",
|
.name = "virtio-mouse",
|
||||||
.args = "-machine q35 -nodefaults -device virtio-mouse",
|
.args = "-machine q35 -nodefaults -device virtio-mouse",
|
||||||
.objects = "virtio*",
|
.objects = "virtio*",
|
||||||
|
},{
|
||||||
|
.name = "virtio-9p",
|
||||||
|
.argfunc = generic_fuzzer_virtio_9p_args,
|
||||||
|
.objects = "virtio*",
|
||||||
|
},{
|
||||||
|
.name = "virtio-9p-synth",
|
||||||
|
.args = "-machine q35 -nodefaults "
|
||||||
|
"-device virtio-9p,fsdev=hshare,mount_tag=hshare "
|
||||||
|
"-fsdev synth,id=hshare",
|
||||||
|
.objects = "virtio*",
|
||||||
},{
|
},{
|
||||||
.name = "e1000",
|
.name = "e1000",
|
||||||
.args = "-M q35 -nodefaults "
|
.args = "-M q35 -nodefaults "
|
||||||
@ -85,10 +106,28 @@ const generic_fuzz_config predefined_configs[] = {
|
|||||||
.objects = "intel-hda",
|
.objects = "intel-hda",
|
||||||
},{
|
},{
|
||||||
.name = "ide-hd",
|
.name = "ide-hd",
|
||||||
|
.args = "-machine pc -nodefaults "
|
||||||
|
"-drive file=null-co://,if=none,format=raw,id=disk0 "
|
||||||
|
"-device ide-hd,drive=disk0",
|
||||||
|
.objects = "*ide*",
|
||||||
|
},{
|
||||||
|
.name = "ide-atapi",
|
||||||
|
.args = "-machine pc -nodefaults "
|
||||||
|
"-drive file=null-co://,if=none,format=raw,id=disk0 "
|
||||||
|
"-device ide-cd,drive=disk0",
|
||||||
|
.objects = "*ide*",
|
||||||
|
},{
|
||||||
|
.name = "ahci-hd",
|
||||||
.args = "-machine q35 -nodefaults "
|
.args = "-machine q35 -nodefaults "
|
||||||
"-drive file=null-co://,if=none,format=raw,id=disk0 "
|
"-drive file=null-co://,if=none,format=raw,id=disk0 "
|
||||||
"-device ide-hd,drive=disk0",
|
"-device ide-hd,drive=disk0",
|
||||||
.objects = "ahci*",
|
.objects = "*ahci*",
|
||||||
|
},{
|
||||||
|
.name = "ahci-atapi",
|
||||||
|
.args = "-machine q35 -nodefaults "
|
||||||
|
"-drive file=null-co://,if=none,format=raw,id=disk0 "
|
||||||
|
"-device ide-cd,drive=disk0",
|
||||||
|
.objects = "*ahci*",
|
||||||
},{
|
},{
|
||||||
.name = "floppy",
|
.name = "floppy",
|
||||||
.args = "-machine pc -nodefaults -device floppy,id=floppy0 "
|
.args = "-machine pc -nodefaults -device floppy,id=floppy0 "
|
||||||
|
@ -29,6 +29,7 @@ void event_notifier_init_fd(EventNotifier *e, int fd)
|
|||||||
{
|
{
|
||||||
e->rfd = fd;
|
e->rfd = fd;
|
||||||
e->wfd = fd;
|
e->wfd = fd;
|
||||||
|
e->initialized = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ int event_notifier_init(EventNotifier *e, int active)
|
|||||||
if (active) {
|
if (active) {
|
||||||
event_notifier_set(e);
|
event_notifier_set(e);
|
||||||
}
|
}
|
||||||
|
e->initialized = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -78,12 +80,18 @@ fail:
|
|||||||
|
|
||||||
void event_notifier_cleanup(EventNotifier *e)
|
void event_notifier_cleanup(EventNotifier *e)
|
||||||
{
|
{
|
||||||
|
if (!e->initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e->rfd != e->wfd) {
|
if (e->rfd != e->wfd) {
|
||||||
close(e->rfd);
|
close(e->rfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->rfd = -1;
|
e->rfd = -1;
|
||||||
close(e->wfd);
|
close(e->wfd);
|
||||||
e->wfd = -1;
|
e->wfd = -1;
|
||||||
|
e->initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int event_notifier_get_fd(const EventNotifier *e)
|
int event_notifier_get_fd(const EventNotifier *e)
|
||||||
@ -96,6 +104,10 @@ int event_notifier_set(EventNotifier *e)
|
|||||||
static const uint64_t value = 1;
|
static const uint64_t value = 1;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
if (!e->initialized) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = write(e->wfd, &value, sizeof(value));
|
ret = write(e->wfd, &value, sizeof(value));
|
||||||
} while (ret < 0 && errno == EINTR);
|
} while (ret < 0 && errno == EINTR);
|
||||||
@ -113,6 +125,10 @@ int event_notifier_test_and_clear(EventNotifier *e)
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
|
||||||
|
if (!e->initialized) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
|
/* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
|
||||||
value = 0;
|
value = 0;
|
||||||
do {
|
do {
|
||||||
|
Loading…
Reference in New Issue
Block a user