* 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:
Peter Maydell 2021-02-09 10:04:51 +00:00
commit 41d306ec7d
47 changed files with 573 additions and 191 deletions

View File

@ -2541,6 +2541,7 @@ F: qapi/qom.json
F: qapi/qdev.json
F: scripts/coccinelle/qom-parent-type.cocci
F: softmmu/qdev-monitor.c
F: stubs/qdev.c
F: qom/
F: tests/check-qom-interface.c
F: tests/check-qom-proplist.c

View File

@ -644,16 +644,19 @@ static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
d.dirty_bitmap = mem->dirty_bmap;
d.slot = mem->slot | (kml->as_id << 16);
if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
DPRINTF("ioctl failed %d\n", errno);
ret = -1;
ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
if (ret == -ENOENT) {
/* 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;
} else {
subsection.offset_within_region += slot_offset;
subsection.size = int128_make64(slot_size);
kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
}
subsection.offset_within_region += slot_offset;
subsection.size = int128_make64(slot_size);
kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
slot_offset += slot_size;
start_addr += slot_size;
size -= 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.slot = mem->slot | (as_id << 16);
if (kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d) == -1) {
ret = -errno;
ret = kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d);
if (ret < 0 && ret != -ENOENT) {
error_report("%s: KVM_CLEAR_DIRTY_LOG failed, slot=%d, "
"start=0x%"PRIx64", size=0x%"PRIx32", errno=%d",
__func__, d.slot, (uint64_t)d.first_page,

View File

@ -81,7 +81,13 @@ void icount_handle_deadline(void)
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
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();
}
}

View File

@ -494,6 +494,16 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
host_memory_backend_get_share, host_memory_backend_set_share);
object_class_property_set_description(oc, "share",
"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",
host_memory_backend_get_use_canonical_path,
host_memory_backend_set_use_canonical_path);

View File

@ -10,6 +10,7 @@
#include "qemu/main-loop.h"
#include "qemu/guest-random.h"
#include "qom/object.h"
#include "sysemu/replay.h"
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);
qemu_bh_schedule(s->bh);
replay_bh_schedule_event(s->bh);
}
static void rng_builtin_init(Object *obj)

2
configure vendored
View File

@ -1764,7 +1764,7 @@ Advanced options (experts only):
--with-trace-file=NAME Full PATH,NAME of file to store traces
Default:trace-<pid>
--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
--oss-lib path to OSS library
--cpu=CPU Build for host CPU [$cpu]

View File

@ -100,7 +100,7 @@ In meson.build::
# Detect dependency
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
method: 'pkg-config',
static: enable_static)
kwargs: static_kwargs)
# Create config-host.h (if applicable)
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())

View File

@ -119,7 +119,7 @@ Adding a new fuzzer
Coverage over virtual devices can be improved by adding additional fuzzers.
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.
@ -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
for reference.
3. Register the fuzzer in ``tests/fuzz/Makefile.include`` by appending the
corresponding object to fuzz-obj-y
3. Add the fuzzer to ``tests/qtest/fuzz/meson.build``.
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
@ -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.
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
-----------------------------------------

View File

@ -46,9 +46,11 @@ if build_docs
meson.source_root() / 'docs/sphinx/qmp_lexer.py',
qapi_gen_depends ]
have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT')
man_pages = {
'qemu-ga.8': (have_tools ? 'man8' : ''),
'qemu-ga-ref.7': 'man7',
'qemu-ga.8': (have_ga ? 'man8' : ''),
'qemu-ga-ref.7': (have_ga ? 'man7' : ''),
'qemu-qmp-ref.7': 'man7',
'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''),
'qemu-img.1': (have_tools ? 'man1' : ''),

View File

@ -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 = {
.read = imx7_set_clr_tog_read,
.write = imx7_digprog_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 4,

View File

@ -196,7 +196,21 @@ static bool tz_ppc_dummy_accepts(void *opaque, hwaddr addr,
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 = {
/* 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,
};

View File

@ -273,6 +273,15 @@ static const MemoryRegionOps io_ops = {
.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,
unsigned int size)
@ -300,6 +309,7 @@ static void flash_write(void *opaque, hwaddr offset, uint64_t value,
static const MemoryRegionOps flash_ops = {
.read = flash_read,
.write = flash_write,
.valid.min_access_size = 4,
.valid.max_access_size = 4,

View File

@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/log.h"
#include "hw/pci/msi.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_host.h"
@ -63,6 +64,23 @@ designware_pcie_root_to_host(DesignwarePCIERoot *root)
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,
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 = {
.read = designware_pcie_root_msi_read,
.write = designware_pcie_root_msi_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {

View File

@ -27,6 +27,7 @@
#include "qemu-common.h"
#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "hw/pci/pci.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);
}
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 = {
.read = raven_intack_read,
.write = raven_intack_write,
.valid = {
.max_access_size = 1,
},

View File

@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
@ -235,8 +236,15 @@ static uint64_t ppc_parity_error_readl(void *opaque, hwaddr addr,
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 = {
.read = ppc_parity_error_readl,
.write = ppc_parity_error_writel,
.valid = {
.min_access_size = 4,
.max_access_size = 4,

View File

@ -53,6 +53,7 @@
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
#include "hw/ppc/spapr_numa.h"
#include "qemu/log.h"
/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
#define RTAS_QUERY_FN 0
@ -739,6 +740,12 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
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.
* 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 = {
/* 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,
.endianness = DEVICE_LITTLE_ENDIAN
};

View File

@ -126,6 +126,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
{
int i;
int rc;
int vq_init_count = 0;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
@ -153,17 +154,22 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
if (rc) {
goto fail_vrings;
}
vq_init_count++;
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
virtio_scsi_data_plane_handle_event);
if (rc) {
goto fail_vrings;
}
vq_init_count++;
for (i = 0; i < vs->conf.num_queues; i++) {
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
virtio_scsi_data_plane_handle_cmd);
if (rc) {
goto fail_vrings;
}
vq_init_count++;
}
s->dataplane_starting = false;
@ -174,7 +180,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
fail_vrings:
aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s);
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_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}

View File

@ -14,6 +14,7 @@
#include CONFIG_DEVICES
#include "exec/memop.h"
#include "qemu/units.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
@ -264,8 +265,15 @@ static uint64_t vfio_ati_3c3_quirk_read(void *opaque,
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 = {
.read = vfio_ati_3c3_quirk_read,
.write = vfio_ati_3c3_quirk_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};

View File

@ -45,13 +45,11 @@ DECLARE_OBJ_CHECKERS(IOMMUMemoryRegion, IOMMUMemoryRegionClass,
#ifdef CONFIG_FUZZ
void fuzz_dma_read_cb(size_t addr,
size_t len,
MemoryRegion *mr,
bool is_write);
MemoryRegion *mr);
#else
static inline void fuzz_dma_read_cb(size_t addr,
size_t len,
MemoryRegion *mr,
bool is_write)
MemoryRegion *mr)
{
/* Do Nothing */
}
@ -2514,7 +2512,7 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
void *buf, hwaddr len)
{
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)) {
memcpy(buf, cache->ptr + addr, len);
return MEMTX_OK;

View File

@ -28,7 +28,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
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)) {
return LD_P(l)(cache->ptr + addr);
} else {
@ -40,7 +40,7 @@ static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
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)) {
return LD_P(q)(cache->ptr + addr);
} else {
@ -52,7 +52,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
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)) {
return LD_P(uw)(cache->ptr + addr);
} else {

View File

@ -24,6 +24,7 @@ struct EventNotifier {
#else
int rfd;
int wfd;
bool initialized;
#endif
};

View File

@ -42,7 +42,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
MO_32 | devend_memop(endian), attrs);
} else {
/* 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);
switch (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);
} else {
/* 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);
switch (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);
} else {
/* 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);
val = ldub_p(ptr);
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);
} else {
/* 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);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:

View File

@ -18,6 +18,9 @@ config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
enable_modules = 'CONFIG_MODULES' 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
# configure runs. Since it is in the build directory
# 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 cpu not in supported_cpus
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
error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
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
if get_option('tcg_interpreter')
tcg_arch = 'tci'
@ -311,14 +321,14 @@ endif
pixman = not_found
if have_system or have_tools
pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
pam = not_found
if 'CONFIG_AUTH_PAM' in config_host
pam = cc.find_library('pam')
endif
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
if 'CONFIG_LINUX_IO_URING' in config_host
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
libnfs = dependency('libnfs', version: '>=1.9.3',
required: get_option('libnfs'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
libattr_test = '''
@ -354,7 +364,7 @@ if not get_option('attr').disabled()
else
libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
required: get_option('attr'),
static: enable_static)
kwargs: static_kwargs)
if libattr.found() and not \
cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
libattr = not_found
@ -381,14 +391,14 @@ seccomp = not_found
if not get_option('seccomp').auto() or have_system or have_tools
seccomp = dependency('libseccomp', version: '>=2.3.0',
required: get_option('seccomp'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
libcap_ng = not_found
if not get_option('cap_ng').auto() or have_system or have_tools
libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
required: get_option('cap_ng'),
static: enable_static)
kwargs: static_kwargs)
endif
if libcap_ng.found() and not cc.links('''
#include <cap-ng.h>
@ -409,7 +419,7 @@ if get_option('xkbcommon').auto() and not have_system and not have_tools
xkbcommon = not_found
else
xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
vde = not_found
if config_host.has_key('CONFIG_VDE')
@ -445,13 +455,13 @@ libiscsi = not_found
if not get_option('libiscsi').auto() or have_block
libiscsi = dependency('libiscsi', version: '>=1.9.0',
required: get_option('libiscsi'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
zstd = not_found
if not get_option('zstd').auto() or have_block
zstd = dependency('libzstd', version: '>=1.4.0',
required: get_option('zstd'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
endif
gbm = not_found
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',
method: 'pkg-config',
required: get_option('curl'),
static: enable_static)
kwargs: static_kwargs)
endif
libudev = not_found
if targetos == 'linux' and (have_system or have_tools)
libudev = dependency('libudev',
method: 'pkg-config',
required: get_option('libudev'),
static: enable_static)
kwargs: static_kwargs)
endif
mpathlibs = [libudev]
@ -511,17 +521,17 @@ if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
}'''
libmpathpersist = cc.find_library('mpathpersist',
required: get_option('mpath'),
static: enable_static)
kwargs: static_kwargs)
if libmpathpersist.found()
mpathlibs += libmpathpersist
if enable_static
mpathlibs += cc.find_library('devmapper',
required: get_option('mpath'),
static: enable_static)
kwargs: static_kwargs)
endif
mpathlibs += cc.find_library('multipath',
required: get_option('mpath'),
static: enable_static)
kwargs: static_kwargs)
foreach lib: mpathlibs
if not lib.found()
mpathlibs = []
@ -571,7 +581,7 @@ if have_system and not get_option('curses').disabled()
curses = dependency(curses_dep,
required: false,
method: 'pkg-config',
static: enable_static)
kwargs: static_kwargs)
endif
endforeach
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
libcurses = cc.find_library(curses_libname,
required: false,
static: enable_static)
kwargs: static_kwargs)
if libcurses.found()
if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
curses = declare_dependency(compile_args: curses_compile_args,
@ -647,7 +657,7 @@ brlapi = not_found
if not get_option('brlapi').auto() or have_system
brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
required: get_option('brlapi'),
static: enable_static)
kwargs: static_kwargs)
if brlapi.found() and not cc.links('''
#include <brlapi.h>
#include <stddef.h>
@ -663,7 +673,7 @@ endif
sdl = not_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
endif
if sdl.found()
@ -671,7 +681,7 @@ if sdl.found()
sdl = declare_dependency(compile_args: '-Wno-undef',
dependencies: sdl)
sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
else
if get_option('sdl_image').enabled()
error('sdl-image required, but SDL was @0@'.format(
@ -683,19 +693,25 @@ endif
rbd = not_found
if not get_option('rbd').auto() or have_block
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'],
required: get_option('rbd'),
static: enable_static)
if librados.found() and librbd.found() and cc.links('''
#include <stdio.h>
#include <rbd/librbd.h>
int main(void) {
rados_t cluster;
rados_create(&cluster, NULL);
return 0;
}''', dependencies: [librbd, librados])
rbd = declare_dependency(dependencies: [librbd, librados])
kwargs: static_kwargs)
if librados.found() and librbd.found()
if cc.links('''
#include <stdio.h>
#include <rbd/librbd.h>
int main(void) {
rados_t cluster;
rados_create(&cluster, NULL);
return 0;
}''', dependencies: [librbd, librados])
rbd = declare_dependency(dependencies: [librbd, librados])
elif get_option('rbd').enabled()
error('could not link librados')
else
warning('could not link librados, disabling')
endif
endif
endif
@ -705,7 +721,7 @@ glusterfs_iocb_has_stat = false
if not get_option('glusterfs').auto() or have_block
glusterfs = dependency('glusterfs-api', version: '>=3',
required: get_option('glusterfs'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
if glusterfs.found()
glusterfs_ftruncate_has_stat = cc.links('''
#include <glusterfs/api/glfs.h>
@ -744,7 +760,7 @@ libbzip2 = not_found
if not get_option('bzip2').auto() or have_block
libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
required: get_option('bzip2'),
static: enable_static)
kwargs: static_kwargs)
if libbzip2.found() and not cc.links('''
#include <bzlib.h>
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
liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
required: get_option('lzfse'),
static: enable_static)
kwargs: static_kwargs)
endif
if liblzfse.found() and not cc.links('''
#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',
method: 'pkg-config',
required: get_option('gtk'),
static: enable_static)
kwargs: static_kwargs)
if gtk.found()
gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
method: 'pkg-config',
required: false,
static: enable_static)
kwargs: static_kwargs)
gtk = declare_dependency(dependencies: [gtk, gtkx11])
endif
endif
@ -816,7 +832,7 @@ endif
x11 = not_found
if gtkx11.found() or 'lm32-softmmu' in target_dirs
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
static: enable_static)
kwargs: static_kwargs)
endif
vnc = not_found
png = not_found
@ -825,12 +841,12 @@ sasl = not_found
if get_option('vnc').enabled()
vnc = declare_dependency() # dummy dependency
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'),
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
required: get_option('vnc_sasl'),
static: enable_static)
kwargs: static_kwargs)
if sasl.found()
sasl = declare_dependency(dependencies: sasl,
compile_args: '-DSTRUCT_IOVEC_DEFINED')
@ -841,7 +857,7 @@ snappy = not_found
if not get_option('snappy').auto() or have_system
snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
required: get_option('snappy'),
static: enable_static)
kwargs: static_kwargs)
endif
if snappy.found() and not cc.links('''
#include <snappy-c.h>
@ -858,7 +874,7 @@ lzo = not_found
if not get_option('lzo').auto() or have_system
lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
required: get_option('lzo'),
static: enable_static)
kwargs: static_kwargs)
endif
if lzo.found() and not cc.links('''
#include <lzo/lzo1x.h>
@ -893,7 +909,7 @@ u2f = not_found
if have_system
u2f = dependency('u2f-emu', required: get_option('u2f'),
method: 'pkg-config',
static: enable_static)
kwargs: static_kwargs)
endif
usbredir = not_found
if 'CONFIG_USB_REDIR' in config_host
@ -920,7 +936,7 @@ if 'CONFIG_TASN1' in config_host
link_args: config_host['TASN1_LIBS'].split())
endif
keyutils = dependency('libkeyutils', required: false,
method: 'pkg-config', static: enable_static)
method: 'pkg-config', kwargs: static_kwargs)
has_gettid = cc.has_function('gettid')
@ -979,7 +995,7 @@ endif
fuse = dependency('fuse3', required: get_option('fuse'),
version: '>=3.1', method: 'pkg-config',
static: enable_static)
kwargs: static_kwargs)
fuse_lseek = not_found
if not get_option('fuse_lseek').disabled()
@ -1367,7 +1383,7 @@ capstone_opt = get_option('capstone')
if capstone_opt in ['enabled', 'auto', 'system']
have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
capstone = dependency('capstone', version: '>=4.0',
static: enable_static, method: 'pkg-config',
kwargs: static_kwargs, method: 'pkg-config',
required: capstone_opt == 'system' or
capstone_opt == 'enabled' and not have_internal)
if capstone.found()
@ -1477,7 +1493,7 @@ if have_system
slirp_opt = get_option('slirp')
if slirp_opt in ['enabled', 'auto', 'system']
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',
required: slirp_opt == 'system' or
slirp_opt == 'enabled' and not have_internal)
@ -1556,7 +1572,7 @@ fdt_opt = get_option('fdt')
if have_system
if fdt_opt in ['enabled', 'auto', 'system']
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
fdt_opt == 'enabled' and not have_internal)
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
# we have those
trace_events_subdirs = [
'accel/kvm',
'accel/tcg',
'crypto',
'qapi',
'qom',
'monitor',
'util',
]
if have_user
trace_events_subdirs += [ 'linux-user' ]
@ -1744,6 +1761,7 @@ if have_block
endif
if have_system
trace_events_subdirs += [
'accel/kvm',
'audio',
'backends',
'backends/tpm',
@ -1801,21 +1819,21 @@ if have_system
'ui',
]
endif
trace_events_subdirs += [
'hw/core',
'qapi',
'qom',
'target/arm',
'target/hppa',
'target/i386',
'target/i386/kvm',
'target/mips',
'target/ppc',
'target/riscv',
'target/s390x',
'target/sparc',
'util',
]
if have_system or have_user
trace_events_subdirs += [
'accel/tcg',
'hw/core',
'target/arm',
'target/hppa',
'target/i386',
'target/i386/kvm',
'target/mips',
'target/ppc',
'target/riscv',
'target/s390x',
'target/sparc',
]
endif
vhost_user = not_found
if 'CONFIG_VHOST_USER' in config_host
@ -1849,41 +1867,45 @@ libqemuutil = static_library('qemuutil',
qemuutil = declare_dependency(link_with: libqemuutil,
sources: genh + version_res)
decodetree = generator(find_program('scripts/decodetree.py'),
output: 'decode-@BASENAME@.c.inc',
arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
if have_system or have_user
decodetree = generator(find_program('scripts/decodetree.py'),
output: 'decode-@BASENAME@.c.inc',
arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
subdir('libdecnumber')
subdir('target')
endif
subdir('audio')
subdir('io')
subdir('chardev')
subdir('fsdev')
subdir('libdecnumber')
subdir('target')
subdir('dump')
block_ss.add(files(
'block.c',
'blockjob.c',
'job.c',
'qemu-io-cmds.c',
))
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
if have_block
block_ss.add(files(
'block.c',
'blockjob.c',
'job.c',
'qemu-io-cmds.c',
))
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
subdir('nbd')
subdir('scsi')
subdir('block')
subdir('nbd')
subdir('scsi')
subdir('block')
blockdev_ss.add(files(
'blockdev.c',
'blockdev-nbd.c',
'iothread.c',
'job-qmp.c',
), gnutls)
blockdev_ss.add(files(
'blockdev.c',
'blockdev-nbd.c',
'iothread.c',
'job-qmp.c',
), gnutls)
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
# os-win32.c does not
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
# os-win32.c does not
blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
endif
common_ss.add(files('cpus-common.c'))
@ -2500,8 +2522,12 @@ if have_system
endif
summary_info += {'TCG support': 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 interpreter': tcg_arch == 'tci'}
endif
summary_info += {'target list': ' '.join(target_dirs)}
if have_system

View File

@ -40,7 +40,7 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto',
option('tcg', type: 'feature', value: 'auto',
description: 'TCG support')
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',
description: 'Control-Flow Integrity (CFI)')
option('cfi_debug', type: 'boolean', value: 'false',

View File

@ -9,7 +9,7 @@ if install_edk2_blobs
]
configure_file(input: files(f),
output: f,
configuration: {'DATADIR': qemu_datadir},
configuration: {'DATADIR': get_option('prefix') / qemu_datadir},
install: get_option('install_blobs'),
install_dir: qemu_datadir / 'firmware')
endforeach

View File

@ -12,6 +12,7 @@ if install_edk2_blobs
foreach f : fds
custom_target(f,
build_by_default: have_system,
output: f,
input: '@0@.bz2'.format(f),
capture: true,

View File

@ -4,18 +4,20 @@ util_ss.add(files(
'qapi-dealloc-visitor.c',
'qapi-util.c',
'qapi-visit-core.c',
'qmp-dispatch.c',
'qmp-event.c',
'qmp-registry.c',
'qobject-input-visitor.c',
'qobject-output-visitor.c',
'string-input-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 = [
'acpi',
'audio',
'authz',
'block',
'block-core',
@ -35,20 +37,30 @@ qapi_all_modules = [
'misc-target',
'net',
'pragma',
'qdev',
'pci',
'qom',
'rdma',
'replay',
'rocker',
'run-state',
'sockets',
'tpm',
'trace',
'transaction',
'ui',
'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 = [
'block-core',

View File

@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\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)
SRST
``-machine [type=]name[,prop=value[,...]]``
@ -96,6 +97,29 @@ SRST
``hmat=on|off``
Enables or disables ACPI Heterogeneous Memory Attribute Table
(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
HXCOMM Deprecated by -machine

View File

@ -261,7 +261,7 @@ def clear_bits(newtrace, outpath):
data_try = hex(int("".join(data_bin_list), 2))
# It seems qtest only accepts padded hex-values.
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(
prefix=prefix,

View File

@ -90,14 +90,21 @@ static void cpu_throttle_timer_tick(void *opaque)
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 */
new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX);
new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN);
qatomic_set(&throttle_percentage, new_throttle_pct);
timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) +
CPU_THROTTLE_TIMESLICE_NS);
if (!throttle_active) {
cpu_throttle_timer_tick(NULL);
}
}
void cpu_throttle_stop(void)

View File

@ -1440,7 +1440,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
unsigned size = memop_size(op);
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)) {
*pval = unassigned_mem_read(mr, addr, size);
return MEMTX_DECODE_ERROR;
@ -3285,8 +3285,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
#ifdef CONFIG_FUZZ
void __attribute__((weak)) fuzz_dma_read_cb(size_t addr,
size_t len,
MemoryRegion *mr,
bool is_write)
MemoryRegion *mr)
{
}
#endif

View File

@ -2839,7 +2839,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
stn_he_p(buf, l, val);
} else {
/* 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);
memcpy(buf, ram_ptr, l);
}
@ -3200,7 +3200,7 @@ void *address_space_map(AddressSpace *as,
memory_region_ref(mr);
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
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);
return ptr;

View File

@ -53,4 +53,6 @@ endif
if have_system
stub_ss.add(files('semihost.c'))
stub_ss.add(files('xen-hw-stub.c'))
else
stub_ss.add(files('qdev.c'))
endif

23
stubs/qdev.c Normal file
View 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. */
}

View File

@ -667,7 +667,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_7_0_EBX_RDSEED */
#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
/* 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_1_EAX_FEATURES 0
#define TCG_APM_FEATURES 0
@ -926,11 +926,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"npt", "lbrv", "svm-lock", "nrip-save",
"tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
NULL, NULL, "pause-filter", NULL,
"pfthreshold", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"pfthreshold", "avic", NULL, "v-vmsave-vmload",
"vgif", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"svme-addr-chk", NULL, NULL, NULL,
},
.cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
.tcg_features = TCG_SVM_FEATURES,
@ -964,7 +964,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"la57", NULL, NULL, NULL,
NULL, NULL, "rdpid", NULL,
NULL, "cldemote", NULL, "movdiri",
"movdir64b", NULL, NULL, NULL,
"movdir64b", NULL, NULL, "pks",
},
.cpuid = {
.eax = 7,
@ -1215,7 +1215,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"vmx-exit-save-efer", "vmx-exit-load-efer",
"vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, "vmx-exit-load-pkrs", NULL, NULL,
},
.msr = {
.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-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
"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,
},
@ -5073,6 +5073,11 @@ static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
} else {
return ~0;
}
#ifndef TARGET_X86_64
if (w == FEAT_8000_0001_EDX) {
r &= ~CPUID_EXT2_LM;
}
#endif
if (migratable_only) {
r &= x86_cpu_get_migratable_flags(w);
}

View File

@ -247,6 +247,7 @@ typedef enum X86Seg {
#define CR4_SMEP_MASK (1U << 20)
#define CR4_SMAP_MASK (1U << 21)
#define CR4_PKE_MASK (1U << 22)
#define CR4_PKS_MASK (1U << 24)
#define DR6_BD (1 << 13)
#define DR6_BS (1 << 14)
@ -357,6 +358,7 @@ typedef enum X86Seg {
#define MSR_IA32_TSX_CTRL 0x122
#define MSR_IA32_TSCDEADLINE 0x6e0
#define MSR_IA32_PKRS 0x6e1
#define FEATURE_CONTROL_LOCKED (1<<0)
#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
@ -670,16 +672,20 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_EXT3_PERFCORE (1U << 23)
#define CPUID_EXT3_PERFNB (1U << 24)
#define CPUID_SVM_NPT (1U << 0)
#define CPUID_SVM_LBRV (1U << 1)
#define CPUID_SVM_SVMLOCK (1U << 2)
#define CPUID_SVM_NRIPSAVE (1U << 3)
#define CPUID_SVM_TSCSCALE (1U << 4)
#define CPUID_SVM_VMCBCLEAN (1U << 5)
#define CPUID_SVM_FLUSHASID (1U << 6)
#define CPUID_SVM_DECODEASSIST (1U << 7)
#define CPUID_SVM_PAUSEFILTER (1U << 10)
#define CPUID_SVM_PFTHRESHOLD (1U << 12)
#define CPUID_SVM_NPT (1U << 0)
#define CPUID_SVM_LBRV (1U << 1)
#define CPUID_SVM_SVMLOCK (1U << 2)
#define CPUID_SVM_NRIPSAVE (1U << 3)
#define CPUID_SVM_TSCSCALE (1U << 4)
#define CPUID_SVM_VMCBCLEAN (1U << 5)
#define CPUID_SVM_FLUSHASID (1U << 6)
#define CPUID_SVM_DECODEASSIST (1U << 7)
#define CPUID_SVM_PAUSEFILTER (1U << 10)
#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 */
#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)
/* Move 64 Bytes as Direct Store Instruction */
#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 */
#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_PT_CONCEAL_PIP 0x01000000
#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_IA32E_MODE 0x00000200
@ -976,6 +985,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define VMX_VM_ENTRY_LOAD_BNDCFGS 0x00010000
#define VMX_VM_ENTRY_PT_CONCEAL_PIP 0x00020000
#define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000
#define VMX_VM_ENTRY_LOAD_IA32_PKRS 0x00400000
/* Supported Hyper-V Enlightenments */
#define HYPERV_FEAT_RELAXED 0
@ -1483,6 +1493,7 @@ typedef struct CPUX86State {
uint64_t msr_smi_count;
uint32_t pkru;
uint32_t pkrs;
uint32_t tsx_ctrl;
uint64_t spec_ctrl;

View File

@ -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)) {
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->hflags = hflags;

View File

@ -113,6 +113,7 @@ static bool has_msr_vmx_vmfunc;
static bool has_msr_ucode_rev;
static bool has_msr_vmx_procbased_ctls2;
static bool has_msr_perf_capabs;
static bool has_msr_pkrs;
static uint32_t has_architectural_pmu_version;
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:
has_msr_vmx_procbased_ctls2 = true;
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) {
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) {
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) {
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) {
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:
env->umwait = msrs[i].data;
break;
case MSR_IA32_PKRS:
env->pkrs = msrs[i].data;
break;
default:
if (msrs[i].index >= MSR_MC0_CTL &&
msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {

View File

@ -980,7 +980,6 @@ static const VMStateDescription vmstate_umwait = {
}
};
#ifdef TARGET_X86_64
static bool pkru_needed(void *opaque)
{
X86CPU *cpu = opaque;
@ -999,7 +998,25 @@ static const VMStateDescription vmstate_pkru = {
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)
{
@ -1480,9 +1497,8 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_umwait,
&vmstate_tsc_khz,
&vmstate_msr_smi_count,
#ifdef TARGET_X86_64
&vmstate_pkru,
#endif
&vmstate_pkrs,
&vmstate_spec_ctrl,
&vmstate_mcg_ext_ctl,
&vmstate_msr_intel_pt,

View File

@ -361,6 +361,7 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
uint64_t rsvd_mask = PG_HI_RSVD_MASK;
uint32_t page_offset;
target_ulong vaddr;
uint32_t pkr;
is_user = mmu_idx == MMU_USER_IDX;
#if defined(DEBUG_MMU)
@ -588,21 +589,28 @@ do_check_protect_pse36:
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
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) {
pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
} else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
pkru_prot &= ~PAGE_WRITE;
if (!(env->hflags & HF_LMA_MASK)) {
pkr = 0;
} else if (ptep & PG_USER_MASK) {
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;
if ((pkru_prot & (1 << is_write1)) == 0) {
prot &= pkr_prot;
if ((pkr_prot & (1 << is_write1)) == 0) {
assert(is_write1 != 2);
error_code |= PG_ERROR_PK_MASK;
goto do_fault_protect;

View File

@ -244,6 +244,7 @@ void helper_rdmsr(CPUX86State *env)
void helper_wrmsr(CPUX86State *env)
{
uint64_t val;
CPUState *cs = env_cpu(env);
cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
@ -296,6 +297,13 @@ void helper_wrmsr(CPUX86State *env)
case MSR_PAT:
env->pat = val;
break;
case MSR_IA32_PKRS:
if (val & 0xFFFFFFFF00000000ull) {
goto error;
}
env->pkrs = val;
tlb_flush(cs);
break;
case MSR_VM_HSAVE_PA:
env->vm_hsave = val;
break;
@ -399,6 +407,9 @@ void helper_wrmsr(CPUX86State *env)
/* XXX: exception? */
break;
}
return;
error:
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
}
void helper_rdmsr(CPUX86State *env)
@ -430,6 +441,9 @@ void helper_rdmsr(CPUX86State *env)
case MSR_PAT:
val = env->pat;
break;
case MSR_IA32_PKRS:
val = env->pkrs;
break;
case MSR_VM_HSAVE_PA:
val = env->vm_hsave;
break;

View File

@ -3075,7 +3075,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
if (is_xmm
&& !(s->flags & HF_OSFXSR_MASK)
&& ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
&& (b != 0x38 && b != 0x3a)) {
goto unknown_op;
}
if (b == 0x0e) {

View File

@ -86,7 +86,6 @@ tests = {
'test-qobject-input-visitor': [testqapi],
'test-string-input-visitor': [testqapi],
'test-string-output-visitor': [testqapi],
'test-qmp-event': [testqapi],
'test-opts-visitor': [testqapi],
'test-visitor-serialization': [testqapi],
'test-bitmap': [],
@ -117,6 +116,12 @@ tests = {
'test-qapi-util': [],
}
if have_system or have_tools
tests += {
'test-qmp-event': [testqapi],
}
endif
test_deps = {
'test-qht-par': qht_bench,
}
@ -276,7 +281,9 @@ test('decodetree', sh,
workdir: meson.current_source_dir() / 'decode',
suite: 'decodetree')
subdir('fp')
if 'CONFIG_TCG' in config_all
subdir('fp')
endif
if not get_option('tcg').disabled()
if 'CONFIG_PLUGIN' in config_host

View File

@ -159,6 +159,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
char *target_name;
const char *bindir;
char *datadir;
GString *cmd_line;
gchar *pretty_cmd_line;
bool serialize = false;
/* 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 */
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 ",
getenv("QTEST_LOG") ? "" : "-qtest-log none");
@ -226,6 +228,13 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
wordexp(cmd_line->str, &result, 0);
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);
/* re-enable the rcu atfork, which was previously disabled in qemu_init */

View File

@ -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
* 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? */
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
* - 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 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
*/
if (dma_patterns->len == 0
|| len == 0
|| mr != current_machine->ram
|| is_write
|| addr > current_machine->ram_size) {
return;
}
@ -213,12 +210,12 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
double_fetch = true;
if (addr < region.addr
&& 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
&& avoid_double_fetches) {
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;
}
@ -936,12 +933,20 @@ static GString *generic_fuzz_cmdline(FuzzTarget *t)
static GString *generic_fuzz_predefined_config_cmdline(FuzzTarget *t)
{
gchar *args;
const generic_fuzz_config *config;
g_assert(t->opaque);
config = t->opaque;
setenv("QEMU_AVOID_DOUBLE_FETCH", "1", 1);
setenv("QEMU_FUZZ_ARGS", config->args, 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_OBJECTS", config->objects, 1);
return generic_fuzz_cmdline(t);
}

View File

@ -16,8 +16,19 @@
typedef struct generic_fuzz_config {
const char *name, *args, *objects;
gchar* (*argfunc)(void); /* Result must be freeable by g_free() */
} 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[] = {
{
.name = "virtio-net-pci-slirp",
@ -59,6 +70,16 @@ const generic_fuzz_config predefined_configs[] = {
.name = "virtio-mouse",
.args = "-machine q35 -nodefaults -device virtio-mouse",
.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",
.args = "-M q35 -nodefaults "
@ -85,10 +106,28 @@ const generic_fuzz_config predefined_configs[] = {
.objects = "intel-hda",
},{
.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 "
"-drive file=null-co://,if=none,format=raw,id=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",
.args = "-machine pc -nodefaults -device floppy,id=floppy0 "

View File

@ -29,6 +29,7 @@ void event_notifier_init_fd(EventNotifier *e, int fd)
{
e->rfd = fd;
e->wfd = fd;
e->initialized = true;
}
#endif
@ -68,6 +69,7 @@ int event_notifier_init(EventNotifier *e, int active)
if (active) {
event_notifier_set(e);
}
e->initialized = true;
return 0;
fail:
@ -78,12 +80,18 @@ fail:
void event_notifier_cleanup(EventNotifier *e)
{
if (!e->initialized) {
return;
}
if (e->rfd != e->wfd) {
close(e->rfd);
}
e->rfd = -1;
close(e->wfd);
e->wfd = -1;
e->initialized = false;
}
int event_notifier_get_fd(const EventNotifier *e)
@ -96,6 +104,10 @@ int event_notifier_set(EventNotifier *e)
static const uint64_t value = 1;
ssize_t ret;
if (!e->initialized) {
return -1;
}
do {
ret = write(e->wfd, &value, sizeof(value));
} while (ret < 0 && errno == EINTR);
@ -113,6 +125,10 @@ int event_notifier_test_and_clear(EventNotifier *e)
ssize_t len;
char buffer[512];
if (!e->initialized) {
return 0;
}
/* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
value = 0;
do {