aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel/tcg/translate-all.c37
-rw-r--r--chardev/char-fe.c22
-rw-r--r--chardev/char-socket.c10
-rwxr-xr-xconfigure4
-rw-r--r--hw/audio/cs4231a.c8
-rw-r--r--hw/audio/gus.c7
-rw-r--r--hw/audio/sb16.c9
-rw-r--r--hw/block/fdc.c5
-rw-r--r--hw/net/can/can_sja1000.c4
-rw-r--r--hw/scsi/scsi-disk.c7
-rw-r--r--hw/scsi/scsi-generic.c7
-rw-r--r--iothread.c4
-rwxr-xr-xscripts/device-crash-test4
-rwxr-xr-xscripts/get_maintainer.pl4
-rw-r--r--scsi/qemu-pr-helper.c7
-rw-r--r--target/i386/whpx-all.c46
-rw-r--r--tests/vhost-user-test.c94
-rw-r--r--util/aio-win32.c4
18 files changed, 159 insertions, 124 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 5ad1b91..d419060 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1728,8 +1728,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
CPUArchState *env = cpu->env_ptr;
#endif
TranslationBlock *tb;
- uint32_t n, flags;
- target_ulong pc, cs_base;
+ uint32_t n;
tb_lock();
tb = tb_find_pc(retaddr);
@@ -1737,44 +1736,33 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
(void *)retaddr);
}
- n = cpu->icount_decr.u16.low + tb->icount;
cpu_restore_state_from_tb(cpu, tb, retaddr);
- /* Calculate how many instructions had been executed before the fault
- occurred. */
- n = n - cpu->icount_decr.u16.low;
- /* Generate a new TB ending on the I/O insn. */
- n++;
+
/* On MIPS and SH, delay slot instructions can only be restarted if
they were already the first instruction in the TB. If this is not
the first instruction in a TB then re-execute the preceding
branch. */
+ n = 1;
#if defined(TARGET_MIPS)
- if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
+ if ((env->hflags & MIPS_HFLAG_BMASK) != 0
+ && env->active_tc.PC != tb->pc) {
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
cpu->icount_decr.u16.low++;
env->hflags &= ~MIPS_HFLAG_BMASK;
+ n = 2;
}
#elif defined(TARGET_SH4)
if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
- && n > 1) {
+ && env->pc != tb->pc) {
env->pc -= 2;
cpu->icount_decr.u16.low++;
env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
+ n = 2;
}
#endif
- /* This should never happen. */
- if (n > CF_COUNT_MASK) {
- cpu_abort(cpu, "TB too big during recompile");
- }
- pc = tb->pc;
- cs_base = tb->cs_base;
- flags = tb->flags;
- tb_phys_invalidate(tb, -1);
-
- /* Execute one IO instruction without caching
- instead of creating large TB. */
- cpu->cflags_next_tb = curr_cflags() | CF_LAST_IO | CF_NOCACHE | 1;
+ /* Generate a new TB executing the I/O insn. */
+ cpu->cflags_next_tb = curr_cflags() | CF_LAST_IO | n;
if (tb->cflags & CF_NOCACHE) {
if (tb->orig_tb) {
@@ -1785,11 +1773,6 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
tb_remove(tb);
}
- /* Generate new TB instead of the current one. */
- /* FIXME: In theory this could raise an exception. In practice
- we have already translated the block once so it's probably ok. */
- tb_gen_code(cpu, pc, cs_base, flags, curr_cflags() | CF_LAST_IO | n);
-
/* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
* the first in the TB) then we end up generating a whole new TB and
* repeating the fault, which is horribly inefficient.
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index 392db78..b1f228e 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -198,19 +198,21 @@ bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
{
int tag = 0;
- if (CHARDEV_IS_MUX(s)) {
- MuxChardev *d = MUX_CHARDEV(s);
+ if (s) {
+ if (CHARDEV_IS_MUX(s)) {
+ MuxChardev *d = MUX_CHARDEV(s);
+
+ if (d->mux_cnt >= MAX_MUX) {
+ goto unavailable;
+ }
- if (d->mux_cnt >= MAX_MUX) {
+ d->backends[d->mux_cnt] = b;
+ tag = d->mux_cnt++;
+ } else if (s->be) {
goto unavailable;
+ } else {
+ s->be = b;
}
-
- d->backends[d->mux_cnt] = b;
- tag = d->mux_cnt++;
- } else if (s->be) {
- goto unavailable;
- } else {
- s->be = b;
}
b->fe_open = false;
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index d057192..159e69c 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -550,12 +550,10 @@ static void tcp_chr_connect(void *opaque)
s->is_listen, s->is_telnet);
s->connected = 1;
- if (s->ioc) {
- chr->gsource = io_add_watch_poll(chr, s->ioc,
- tcp_chr_read_poll,
- tcp_chr_read,
- chr, chr->gcontext);
- }
+ chr->gsource = io_add_watch_poll(chr, s->ioc,
+ tcp_chr_read_poll,
+ tcp_chr_read,
+ chr, chr->gcontext);
s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
diff --git a/configure b/configure
index 8376cb1..4d0e92c 100755
--- a/configure
+++ b/configure
@@ -2496,7 +2496,9 @@ if test "$whpx" != "no" ; then
#include <WinHvEmulation.h>
int main(void) {
WHV_CAPABILITY whpx_cap;
- WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap));
+ UINT32 writtenSize;
+ WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap),
+ &writtenSize);
return 0;
}
EOF
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 096e8e9..aaebec1 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -28,6 +28,7 @@
#include "hw/isa/isa.h"
#include "hw/qdev.h"
#include "qemu/timer.h"
+#include "qapi/error.h"
/*
Missing features:
@@ -663,8 +664,13 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
CSState *s = CS4231A (dev);
IsaDmaClass *k;
- isa_init_irq (d, &s->pic, s->irq);
s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->dma);
+ if (!s->isa_dma) {
+ error_setg(errp, "ISA controller does not support DMA");
+ return;
+ }
+
+ isa_init_irq(d, &s->pic, s->irq);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, cs_dma_read, s);
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 3e864cd..8e0b27e 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -241,6 +241,12 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
IsaDmaClass *k;
struct audsettings as;
+ s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
+ if (!s->isa_dma) {
+ error_setg(errp, "ISA controller does not support DMA");
+ return;
+ }
+
AUD_register_card ("gus", &s->card);
as.freq = s->freq;
@@ -272,7 +278,6 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list(d, &s->portio_list2, (s->port + 0x100) & 0xf00,
gus_portio_list2, s, "gus");
- s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->emu.gusdma, GUS_read_DMA, s);
s->emu.himemaddr = s->himem;
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 31de264..5a4d323 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1371,6 +1371,13 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
SB16State *s = SB16 (dev);
IsaDmaClass *k;
+ s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
+ s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
+ if (!s->isa_dma || !s->isa_hdma) {
+ error_setg(errp, "ISA controller does not support DMA");
+ return;
+ }
+
isa_init_irq (isadev, &s->pic, s->irq);
s->mixer_regs[0x80] = magic_of_irq (s->irq);
@@ -1389,11 +1396,9 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list(isadev, &s->portio_list, s->port,
sb16_ioport_list, s, "sb16");
- s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
k = ISADMA_GET_CLASS(s->isa_hdma);
k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
- s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 7b7dd41..cd29e27 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2695,7 +2695,10 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
fdctrl->dma_chann = isa->dma;
if (fdctrl->dma_chann != -1) {
fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma);
- assert(fdctrl->dma);
+ if (!fdctrl->dma) {
+ error_setg(errp, "ISA controller does not support DMA");
+ return;
+ }
}
qdev_set_legacy_instance_id(dev, isa->iobase, 2);
diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c
index 6293233..9a85038 100644
--- a/hw/net/can/can_sja1000.c
+++ b/hw/net/can/can_sja1000.c
@@ -866,6 +866,10 @@ int can_sja_connect_to_bus(CanSJA1000State *s, CanBusState *bus)
{
s->bus_client.info = &can_sja_bus_client_info;
+ if (!bus) {
+ return -EINVAL;
+ }
+
if (can_bus_insert_client(bus, &s->bus_client) < 0) {
return -1;
}
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 5b7a48f..f5ab767 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2607,9 +2607,10 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
/* check we are using a driver managing SG_IO (version 3 and after) */
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
if (rc < 0) {
- error_setg(errp, "cannot get SG_IO version number: %s. "
- "Is this a SCSI device?",
- strerror(-rc));
+ error_setg_errno(errp, -rc, "cannot get SG_IO version number");
+ if (rc != -EPERM) {
+ error_append_hint(errp, "Is this a SCSI device?\n");
+ }
return;
}
if (sg_version < 30000) {
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 7414fe2..4753f87 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -500,9 +500,10 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
/* check we are using a driver managing SG_IO (version 3 and after */
rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
if (rc < 0) {
- error_setg(errp, "cannot get SG_IO version number: %s. "
- "Is this a SCSI device?",
- strerror(-rc));
+ error_setg_errno(errp, -rc, "cannot get SG_IO version number");
+ if (rc != -EPERM) {
+ error_append_hint(errp, "Is this a SCSI device?\n");
+ }
return;
}
if (sg_version < 30000) {
diff --git a/iothread.c b/iothread.c
index 1b3463c..e675c38 100644
--- a/iothread.c
+++ b/iothread.c
@@ -31,11 +31,15 @@ typedef ObjectClass IOThreadClass;
#define IOTHREAD_CLASS(klass) \
OBJECT_CLASS_CHECK(IOThreadClass, klass, TYPE_IOTHREAD)
+#ifdef CONFIG_POSIX
/* Benchmark results from 2016 on NVMe SSD drives show max polling times around
* 16-32 microseconds yield IOPS improvements for both iodepth=1 and iodepth=32
* workloads.
*/
#define IOTHREAD_POLL_MAX_NS_DEFAULT 32768ULL
+#else
+#define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL
+#endif
static __thread IOThread *my_iothread;
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index f04f349..24c7bf5 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -218,11 +218,7 @@ ERROR_WHITELIST = [
{'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
{'exitcode':-6, 'device':'isa-fdc', 'loglevel':logging.ERROR, 'expected':True},
- {'exitcode':-11, 'device':'gus', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
- {'exitcode':-11, 'device':'sb16', 'loglevel':logging.ERROR, 'expected':True},
- {'exitcode':-11, 'device':'cs4231a', 'loglevel':logging.ERROR, 'expected':True},
- {'exitcode':-11, 'machine':'isapc', 'device':'.*-iommu', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'mioe3680_pci', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'kvaser_pci', 'loglevel':logging.ERROR, 'expected':True},
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 07369aa..43fb5f5 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -381,8 +381,8 @@ foreach my $file (@ARGV) {
##if $file is a directory and it lacks a trailing slash, add one
if ((-d $file)) {
$file =~ s@([^/])$@$1/@;
- } elsif (!(-f $file)) {
- die "$P: file '${file}' not found\n";
+ } elsif (!(stat $file)) {
+ die "$P: file '${file}' not found: $!\n";
}
}
if ($from_filename) {
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
index 3facbba..21e1b8e 100644
--- a/scsi/qemu-pr-helper.c
+++ b/scsi/qemu-pr-helper.c
@@ -903,12 +903,12 @@ static int drop_privileges(void)
int main(int argc, char **argv)
{
- const char *sopt = "hVk:fdT:u:g:vq";
+ const char *sopt = "hVk:f:dT:u:g:vq";
struct option lopt[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "socket", required_argument, NULL, 'k' },
- { "pidfile", no_argument, NULL, 'f' },
+ { "pidfile", required_argument, NULL, 'f' },
{ "daemon", no_argument, NULL, 'd' },
{ "trace", required_argument, NULL, 'T' },
{ "user", required_argument, NULL, 'u' },
@@ -952,7 +952,8 @@ int main(int argc, char **argv)
}
break;
case 'f':
- pidfile = optarg;
+ g_free(pidfile);
+ pidfile = g_strdup(optarg);
break;
#ifdef CONFIG_LIBCAP
case 'u': {
diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c
index 940bbe5..bf33d32 100644
--- a/target/i386/whpx-all.c
+++ b/target/i386/whpx-all.c
@@ -153,7 +153,7 @@ struct whpx_vcpu {
bool interruptable;
uint64_t tpr;
uint64_t apic_base;
- WHV_X64_PENDING_INTERRUPTION_REGISTER interrupt_in_flight;
+ bool interruption_pending;
/* Must be the last field as it may have a tail */
WHV_RUN_VP_EXIT_CONTEXT exit_ctx;
@@ -695,7 +695,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
qemu_mutex_lock_iothread();
/* Inject NMI */
- if (!vcpu->interrupt_in_flight.InterruptionPending &&
+ if (!vcpu->interruption_pending &&
cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
@@ -724,7 +724,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
}
/* Get pending hard interruption or replay one that was overwritten */
- if (!vcpu->interrupt_in_flight.InterruptionPending &&
+ if (!vcpu->interruption_pending &&
vcpu->interruptable && (env->eflags & IF_MASK)) {
assert(!new_int.InterruptionPending);
if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
@@ -781,44 +781,25 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
static void whpx_vcpu_post_run(CPUState *cpu)
{
- HRESULT hr;
- struct whpx_state *whpx = &whpx_global;
struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr);
X86CPU *x86_cpu = X86_CPU(cpu);
- WHV_REGISTER_VALUE reg_values[4];
- const WHV_REGISTER_NAME reg_names[4] = {
- WHvX64RegisterRflags,
- WHvX64RegisterCr8,
- WHvRegisterPendingInterruption,
- WHvRegisterInterruptState,
- };
- hr = WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
- reg_names, 4, reg_values);
- if (FAILED(hr)) {
- error_report("WHPX: Failed to get interrupt state regusters,"
- " hr=%08lx", hr);
- vcpu->interruptable = false;
- return;
- }
+ env->eflags = vcpu->exit_ctx.VpContext.Rflags;
- assert(reg_names[0] == WHvX64RegisterRflags);
- env->eflags = reg_values[0].Reg64;
-
- assert(reg_names[1] == WHvX64RegisterCr8);
- if (vcpu->tpr != reg_values[1].Reg64) {
- vcpu->tpr = reg_values[1].Reg64;
+ uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
+ if (vcpu->tpr != tpr) {
+ vcpu->tpr = tpr;
qemu_mutex_lock_iothread();
cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
qemu_mutex_unlock_iothread();
}
- assert(reg_names[2] == WHvRegisterPendingInterruption);
- vcpu->interrupt_in_flight = reg_values[2].PendingInterruption;
+ vcpu->interruption_pending =
+ vcpu->exit_ctx.VpContext.ExecutionState.InterruptionPending;
- assert(reg_names[3] == WHvRegisterInterruptState);
- vcpu->interruptable = !reg_values[3].InterruptState.InterruptShadow;
+ vcpu->interruptable =
+ !vcpu->exit_ctx.VpContext.ExecutionState.InterruptShadow;
return;
}
@@ -1254,6 +1235,7 @@ static int whpx_accel_init(MachineState *ms)
int ret;
HRESULT hr;
WHV_CAPABILITY whpx_cap;
+ UINT32 whpx_cap_size;
WHV_PARTITION_PROPERTY prop;
whpx = &whpx_global;
@@ -1262,7 +1244,7 @@ static int whpx_accel_init(MachineState *ms)
whpx->mem_quota = ms->ram_size;
hr = WHvGetCapability(WHvCapabilityCodeHypervisorPresent, &whpx_cap,
- sizeof(whpx_cap));
+ sizeof(whpx_cap), &whpx_cap_size);
if (FAILED(hr) || !whpx_cap.HypervisorPresent) {
error_report("WHPX: No accelerator found, hr=%08lx", hr);
ret = -ENOSPC;
@@ -1277,9 +1259,9 @@ static int whpx_accel_init(MachineState *ms)
}
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
- prop.PropertyCode = WHvPartitionPropertyCodeProcessorCount;
prop.ProcessorCount = smp_cpus;
hr = WHvSetPartitionProperty(whpx->partition,
+ WHvPartitionPropertyCodeProcessorCount,
&prop,
sizeof(WHV_PARTITION_PROPERTY));
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 22e9202..61d9972 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -18,6 +18,7 @@
#include "qemu/range.h"
#include "qemu/sockets.h"
#include "chardev/char-fe.h"
+#include "qemu/memfd.h"
#include "sysemu/sysemu.h"
#include "libqos/libqos.h"
#include "libqos/pci-pc.h"
@@ -40,23 +41,14 @@
#define HAVE_MONOTONIC_TIME
#endif
-#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM,"\
+#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM," \
"mem-path=%s,share=on -numa node,memdev=mem"
+#define QEMU_CMD_MEMFD " -m %d -object memory-backend-memfd,id=mem,size=%dM," \
+ " -numa node,memdev=mem"
#define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s%s"
#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0"
-#define QEMU_CMD QEMU_CMD_MEM QEMU_CMD_CHR \
- QEMU_CMD_NETDEV QEMU_CMD_NET
-
-#define GET_QEMU_CMD(s) \
- g_strdup_printf(QEMU_CMD, 512, 512, (root), (s)->chr_name, \
- (s)->socket_path, "", (s)->chr_name)
-
-#define GET_QEMU_CMDE(s, mem, chr_opts, extra, ...) \
- g_strdup_printf(QEMU_CMD extra, (mem), (mem), (root), (s)->chr_name, \
- (s)->socket_path, (chr_opts), (s)->chr_name, ##__VA_ARGS__)
-
#define HUGETLBFS_MAGIC 0x958458f6
/*********** FROM hw/virtio/vhost-user.c *************************************/
@@ -175,6 +167,33 @@ static void test_server_listen(TestServer *server);
static const char *tmpfs;
static const char *root;
+enum test_memfd {
+ TEST_MEMFD_AUTO,
+ TEST_MEMFD_YES,
+ TEST_MEMFD_NO,
+};
+
+static char *get_qemu_cmd(TestServer *s,
+ int mem, enum test_memfd memfd, const char *mem_path,
+ const char *chr_opts, const char *extra)
+{
+ if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check()) {
+ memfd = TEST_MEMFD_YES;
+ }
+
+ if (memfd == TEST_MEMFD_YES) {
+ return g_strdup_printf(QEMU_CMD_MEMFD QEMU_CMD_CHR
+ QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
+ s->chr_name, s->socket_path,
+ chr_opts, s->chr_name, extra);
+ } else {
+ return g_strdup_printf(QEMU_CMD_MEM QEMU_CMD_CHR
+ QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
+ mem_path, s->chr_name, s->socket_path,
+ chr_opts, s->chr_name, extra);
+ }
+}
+
static void init_virtio_dev(TestServer *s, uint32_t features_mask)
{
uint32_t features;
@@ -494,6 +513,7 @@ static void test_server_create_chr(TestServer *server, const gchar *opt)
chr = qemu_chr_new(server->chr_name, chr_path);
g_free(chr_path);
+ g_assert_nonnull(chr);
qemu_chr_fe_init(&server->chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
chr_event, NULL, server, NULL, true);
@@ -640,16 +660,18 @@ GSourceFuncs test_migrate_source_funcs = {
.check = test_migrate_source_check,
};
-static void test_read_guest_mem(void)
+static void test_read_guest_mem(const void *arg)
{
+ enum test_memfd memfd = GPOINTER_TO_INT(arg);
TestServer *server = NULL;
char *qemu_cmd = NULL;
QTestState *s = NULL;
- server = test_server_new("test");
+ server = test_server_new(memfd == TEST_MEMFD_YES ?
+ "read-guest-memfd" : "read-guest-mem");
test_server_listen(server);
- qemu_cmd = GET_QEMU_CMD(server);
+ qemu_cmd = get_qemu_cmd(server, 512, memfd, root, "", "");
s = qtest_start(qemu_cmd);
g_free(qemu_cmd);
@@ -671,7 +693,7 @@ static void test_migrate(void)
char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path);
QTestState *global = global_qtest, *from, *to;
GSource *source;
- gchar *cmd;
+ gchar *cmd, *tmp;
QDict *rsp;
guint8 *log;
guint64 size;
@@ -679,7 +701,7 @@ static void test_migrate(void)
test_server_listen(s);
test_server_listen(dest);
- cmd = GET_QEMU_CMDE(s, 2, "", "");
+ cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, "", "");
from = qtest_start(cmd);
g_free(cmd);
@@ -688,7 +710,9 @@ static void test_migrate(void)
size = get_log_size(s);
g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
- cmd = GET_QEMU_CMDE(dest, 2, "", " -incoming %s", uri);
+ tmp = g_strdup_printf(" -incoming %s", uri);
+ cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, root, "", tmp);
+ g_free(tmp);
to = qtest_init(cmd);
g_free(cmd);
@@ -801,7 +825,7 @@ static void test_reconnect_subprocess(void)
char *cmd;
g_thread_new("connect", connect_thread, s);
- cmd = GET_QEMU_CMDE(s, 2, ",server", "");
+ cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
qtest_start(cmd);
g_free(cmd);
@@ -839,7 +863,7 @@ static void test_connect_fail_subprocess(void)
s->test_fail = true;
g_thread_new("connect", connect_thread, s);
- cmd = GET_QEMU_CMDE(s, 2, ",server", "");
+ cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
qtest_start(cmd);
g_free(cmd);
@@ -869,7 +893,7 @@ static void test_flags_mismatch_subprocess(void)
s->test_flags = TEST_FLAGS_DISCONNECT;
g_thread_new("connect", connect_thread, s);
- cmd = GET_QEMU_CMDE(s, 2, ",server", "");
+ cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
qtest_start(cmd);
g_free(cmd);
@@ -904,11 +928,21 @@ static void test_multiqueue(void)
s->queues = 2;
test_server_listen(s);
- cmd = g_strdup_printf(QEMU_CMD_MEM QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
- "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
- 512, 512, root, s->chr_name,
- s->socket_path, "", s->chr_name,
- s->queues, s->queues * 2 + 2);
+ if (qemu_memfd_check()) {
+ cmd = g_strdup_printf(
+ QEMU_CMD_MEMFD QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
+ "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
+ 512, 512, s->chr_name,
+ s->socket_path, "", s->chr_name,
+ s->queues, s->queues * 2 + 2);
+ } else {
+ cmd = g_strdup_printf(
+ QEMU_CMD_MEM QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
+ "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
+ 512, 512, root, s->chr_name,
+ s->socket_path, "", s->chr_name,
+ s->queues, s->queues * 2 + 2);
+ }
qtest_start(cmd);
g_free(cmd);
@@ -954,7 +988,13 @@ int main(int argc, char **argv)
/* run the main loop thread so the chardev may operate */
thread = g_thread_new(NULL, thread_function, loop);
- qtest_add_func("/vhost-user/read-guest-mem", test_read_guest_mem);
+ if (qemu_memfd_check()) {
+ qtest_add_data_func("/vhost-user/read-guest-mem/memfd",
+ GINT_TO_POINTER(TEST_MEMFD_YES),
+ test_read_guest_mem);
+ }
+ qtest_add_data_func("/vhost-user/read-guest-mem/memfile",
+ GINT_TO_POINTER(TEST_MEMFD_NO), test_read_guest_mem);
qtest_add_func("/vhost-user/migrate", test_migrate);
qtest_add_func("/vhost-user/multiqueue", test_multiqueue);
diff --git a/util/aio-win32.c b/util/aio-win32.c
index d6d5e02..a67b00c 100644
--- a/util/aio-win32.c
+++ b/util/aio-win32.c
@@ -410,5 +410,7 @@ void aio_context_setup(AioContext *ctx)
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
int64_t grow, int64_t shrink, Error **errp)
{
- error_setg(errp, "AioContext polling is not implemented on Windows");
+ if (max_ns) {
+ error_setg(errp, "AioContext polling is not implemented on Windows");
+ }
}