aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-06-04 10:15:16 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-04 10:15:16 +0100
commitf67c9b693ae3d03305162623a043ba4067a3c00c (patch)
treef7b339649902accf7aeb09a8cd48dba45e962b3c
parentafd76ffba966a072a7bbd0048bdf3b2ab69d3d4a (diff)
parent25b1d45a1975fd8624c37b5bf42e8502ccf53460 (diff)
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
acpi, vhost, misc: fixes, features vDPA support, fix to vhost blk RO bit handling, some include path cleanups, NFIT ACPI table. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 01 Jun 2018 17:25:19 BST # gpg: using RSA key 281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (31 commits) vhost-blk: turn on pre-defined RO feature bit ACPI testing: test NFIT platform capabilities nvdimm, acpi: support NFIT platform capabilities tests/.gitignore: add entry for generated file arch_init: sort architectures ui: use local path for local headers qga: use local path for local headers colo: use local path for local headers migration: use local path for local headers usb: use local path for local headers sd: fix up include vhost-scsi: drop an unused include ppc: use local path for local headers rocker: drop an unused include e1000e: use local path for local headers ioapic: fix up includes ide: use local path for local headers display: use local path for local headers trace: use local path for local headers migration: drop an unused include ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--arch_init.c16
-rw-r--r--backends/cryptodev-vhost-user.c20
-rw-r--r--block/crypto.c2
-rw-r--r--block/nbd.c2
-rw-r--r--block/qcow.c2
-rw-r--r--block/qcow2-bitmap.c2
-rw-r--r--block/qcow2-cluster.c2
-rw-r--r--block/qcow2-refcount.c2
-rw-r--r--block/qcow2-snapshot.c2
-rw-r--r--block/qcow2.c4
-rw-r--r--block/vhdx-endian.c2
-rw-r--r--block/vhdx-log.c2
-rw-r--r--block/vhdx.c2
-rw-r--r--contrib/libvhost-user/libvhost-user.c81
-rw-r--r--contrib/libvhost-user/libvhost-user.h32
-rw-r--r--contrib/vhost-user-blk/vhost-user-blk.c48
-rw-r--r--crypto/block-luks.c2
-rw-r--r--crypto/block-luks.h2
-rw-r--r--crypto/block-qcow.c2
-rw-r--r--crypto/block-qcow.h2
-rw-r--r--crypto/block.c6
-rw-r--r--crypto/cipher.c6
-rw-r--r--crypto/ivgen-essiv.c2
-rw-r--r--crypto/ivgen-essiv.h2
-rw-r--r--crypto/ivgen-plain.c2
-rw-r--r--crypto/ivgen-plain.h2
-rw-r--r--crypto/ivgen-plain64.c2
-rw-r--r--crypto/ivgen-plain64.h2
-rw-r--r--crypto/ivgen.c8
-rw-r--r--crypto/tlscreds.c2
-rw-r--r--crypto/tlscredsanon.c2
-rw-r--r--crypto/tlscredsx509.c2
-rw-r--r--docs/interop/vhost-user.txt38
-rw-r--r--docs/nvdimm.txt27
-rw-r--r--hw/acpi/nvdimm.c45
-rw-r--r--hw/block/vhost-user-blk.c27
-rw-r--r--hw/display/bcm2835_fb.c2
-rw-r--r--hw/hppa/hppa_sys.h2
-rw-r--r--hw/hppa/machine.c2
-rw-r--r--hw/i386/pc.c31
-rw-r--r--hw/ide/ahci-allwinner.c2
-rw-r--r--hw/ide/ahci.c2
-rw-r--r--hw/ide/ich.c2
-rw-r--r--hw/intc/ioapic.c3
-rw-r--r--hw/net/e1000e.c2
-rw-r--r--hw/net/rocker/rocker_fp.c1
-rw-r--r--hw/ppc/ppc440_uc.c2
-rw-r--r--hw/ppc/sam460ex.c4
-rw-r--r--hw/scsi/vhost-scsi-common.c1
-rw-r--r--hw/scsi/vhost-user-scsi.c20
-rw-r--r--hw/sd/milkymist-memcard.c2
-rw-r--r--hw/usb/desc-msos.c2
-rw-r--r--hw/usb/desc.c2
-rw-r--r--hw/usb/dev-audio.c2
-rw-r--r--hw/usb/dev-bluetooth.c2
-rw-r--r--hw/usb/dev-hid.c2
-rw-r--r--hw/usb/dev-hub.c2
-rw-r--r--hw/usb/dev-mtp.c2
-rw-r--r--hw/usb/dev-network.c2
-rw-r--r--hw/usb/dev-serial.c2
-rw-r--r--hw/usb/dev-smartcard-reader.c2
-rw-r--r--hw/usb/dev-storage.c2
-rw-r--r--hw/usb/dev-uas.c2
-rw-r--r--hw/usb/dev-wacom.c2
-rw-r--r--hw/virtio/vhost-stub.c10
-rw-r--r--hw/virtio/vhost-user.c182
-rw-r--r--hw/virtio/vhost.c9
-rw-r--r--include/hw/i386/pc.h1
-rw-r--r--include/hw/mem/nvdimm.h5
-rw-r--r--include/hw/virtio/vhost-backend.h4
-rw-r--r--include/hw/virtio/vhost-user-blk.h3
-rw-r--r--include/hw/virtio/vhost-user-scsi.h2
-rw-r--r--include/hw/virtio/vhost-user.h28
-rw-r--r--include/migration/vmstate.h2
-rw-r--r--include/qemu/osdep.h10
-rw-r--r--migration/block-dirty-bitmap.c2
-rw-r--r--migration/page_cache.c2
-rw-r--r--migration/ram.c4
-rw-r--r--migration/savevm.c1
-rw-r--r--migration/vmstate.c2
-rw-r--r--net/colo-compare.c2
-rw-r--r--net/colo.c2
-rw-r--r--net/filter-rewriter.c2
-rw-r--r--net/vhost-user.c44
-rw-r--r--qga/channel-posix.c2
-rw-r--r--qga/channel-win32.c4
-rw-r--r--qga/commands-posix.c2
-rw-r--r--qga/commands-win32.c4
-rw-r--r--qga/commands.c2
-rw-r--r--qga/guest-agent-command-state.c2
-rw-r--r--qga/main.c4
-rw-r--r--qga/vss-win32.c6
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/acpi-test-data/pc/NFIT.dimmpxmbin224 -> 240 bytes
-rw-r--r--tests/acpi-test-data/q35/NFIT.dimmpxmbin224 -> 240 bytes
-rw-r--r--tests/bios-tables-test.c2
-rw-r--r--tests/libqtest.c9
-rw-r--r--tests/vhost-user-bridge.c98
-rw-r--r--trace/control.h2
-rw-r--r--trace/qmp.c2
-rw-r--r--ui/gtk.c2
-rw-r--r--ui/input-keymap.c2
-rw-r--r--ui/input-legacy.c2
-rw-r--r--ui/spice-input.c2
104 files changed, 807 insertions, 166 deletions
diff --git a/arch_init.c b/arch_init.c
index 9597218ced..f4f3f610c8 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -52,14 +52,14 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_ARM
#elif defined(TARGET_CRIS)
#define QEMU_ARCH QEMU_ARCH_CRIS
-#elif defined(TARGET_I386)
-#define QEMU_ARCH QEMU_ARCH_I386
#elif defined(TARGET_HPPA)
#define QEMU_ARCH QEMU_ARCH_HPPA
-#elif defined(TARGET_M68K)
-#define QEMU_ARCH QEMU_ARCH_M68K
+#elif defined(TARGET_I386)
+#define QEMU_ARCH QEMU_ARCH_I386
#elif defined(TARGET_LM32)
#define QEMU_ARCH QEMU_ARCH_LM32
+#elif defined(TARGET_M68K)
+#define QEMU_ARCH QEMU_ARCH_M68K
#elif defined(TARGET_MICROBLAZE)
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
#elif defined(TARGET_MIPS)
@@ -80,12 +80,12 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_SH4
#elif defined(TARGET_SPARC)
#define QEMU_ARCH QEMU_ARCH_SPARC
-#elif defined(TARGET_XTENSA)
-#define QEMU_ARCH QEMU_ARCH_XTENSA
-#elif defined(TARGET_UNICORE32)
-#define QEMU_ARCH QEMU_ARCH_UNICORE32
#elif defined(TARGET_TRICORE)
#define QEMU_ARCH QEMU_ARCH_TRICORE
+#elif defined(TARGET_UNICORE32)
+#define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_XTENSA)
+#define QEMU_ARCH QEMU_ARCH_XTENSA
#endif
const uint32_t arch_type = QEMU_ARCH;
diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index 862d4f2580..d52daccfcd 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -26,6 +26,7 @@
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
+#include "hw/virtio/vhost-user.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "sysemu/cryptodev-vhost.h"
#include "chardev/char-fe.h"
@@ -46,6 +47,7 @@
typedef struct CryptoDevBackendVhostUser {
CryptoDevBackend parent_obj;
+ VhostUserState *vhost_user;
CharBackend chr;
char *chr_name;
bool opened;
@@ -102,7 +104,7 @@ cryptodev_vhost_user_start(int queues,
continue;
}
- options.opaque = &s->chr;
+ options.opaque = s->vhost_user;
options.backend_type = VHOST_BACKEND_TYPE_USER;
options.cc = b->conf.peers.ccs[i];
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
@@ -185,6 +187,7 @@ static void cryptodev_vhost_user_init(
size_t i;
Error *local_err = NULL;
Chardev *chr;
+ VhostUserState *user;
CryptoDevBackendClient *cc;
CryptoDevBackendVhostUser *s =
CRYPTODEV_BACKEND_VHOST_USER(backend);
@@ -215,6 +218,15 @@ static void cryptodev_vhost_user_init(
}
}
+ user = vhost_user_init();
+ if (!user) {
+ error_setg(errp, "Failed to init vhost_user");
+ return;
+ }
+
+ user->chr = &s->chr;
+ s->vhost_user = user;
+
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
cryptodev_vhost_user_event, NULL, s, NULL, true);
@@ -299,6 +311,12 @@ static void cryptodev_vhost_user_cleanup(
backend->conf.peers.ccs[i] = NULL;
}
}
+
+ if (s->vhost_user) {
+ vhost_user_cleanup(s->vhost_user);
+ g_free(s->vhost_user);
+ s->vhost_user = NULL;
+ }
}
static void cryptodev_vhost_user_set_chardev(Object *obj,
diff --git a/block/crypto.c b/block/crypto.c
index 7e7ad2d2a6..bc322b50f5 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -29,7 +29,7 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qemu/option.h"
-#include "block/crypto.h"
+#include "crypto.h"
typedef struct BlockCrypto BlockCrypto;
diff --git a/block/nbd.c b/block/nbd.c
index 3e1693cc55..ff8333e3c1 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -27,7 +27,7 @@
*/
#include "qemu/osdep.h"
-#include "block/nbd-client.h"
+#include "nbd-client.h"
#include "qapi/error.h"
#include "qemu/uri.h"
#include "block/block_int.h"
diff --git a/block/qcow.c b/block/qcow.c
index 3ba2ca25ea..1f866af0d3 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -37,7 +37,7 @@
#include "qapi/qapi-visit-block-core.h"
#include "crypto/block.h"
#include "migration/blocker.h"
-#include "block/crypto.h"
+#include "crypto.h"
/**************************************************************/
/* QEMU COW block driver with compression and encryption support */
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 6e93ec43e1..60d5290f10 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -30,7 +30,7 @@
#include "qemu/cutils.h"
#include "block/block_int.h"
-#include "block/qcow2.h"
+#include "qcow2.h"
/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
* _internal_ constants. Please do not use this _internal_ abbreviation for
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 1aee726c6a..0d74584c9b 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -28,7 +28,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
-#include "block/qcow2.h"
+#include "qcow2.h"
#include "qemu/bswap.h"
#include "trace.h"
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2dc23005b7..403236256b 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -26,7 +26,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
-#include "block/qcow2.h"
+#include "qcow2.h"
#include "qemu/range.h"
#include "qemu/bswap.h"
#include "qemu/cutils.h"
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 74293be470..bb6a5b7516 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -25,7 +25,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
-#include "block/qcow2.h"
+#include "qcow2.h"
#include "qemu/bswap.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
diff --git a/block/qcow2.c b/block/qcow2.c
index a007dc4246..c87c593e83 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -27,7 +27,7 @@
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include <zlib.h>
-#include "block/qcow2.h"
+#include "qcow2.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block-core.h"
@@ -39,7 +39,7 @@
#include "qemu/bswap.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-block-core.h"
-#include "block/crypto.h"
+#include "crypto.h"
/*
Differences with QCOW:
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
index 429d7556bd..41fbdd2b8f 100644
--- a/block/vhdx-endian.c
+++ b/block/vhdx-endian.c
@@ -19,7 +19,7 @@
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/bswap.h"
-#include "block/vhdx.h"
+#include "vhdx.h"
/*
* All the VHDX formats on disk are little endian - the following
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
index 0ac4863b25..d2f1b98199 100644
--- a/block/vhdx-log.c
+++ b/block/vhdx-log.c
@@ -24,7 +24,7 @@
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/bswap.h"
-#include "block/vhdx.h"
+#include "vhdx.h"
typedef struct VHDXLogSequence {
diff --git a/block/vhdx.c b/block/vhdx.c
index b1ba121bb6..0831c5c5f4 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -23,7 +23,7 @@
#include "qemu/option.h"
#include "qemu/crc32c.h"
#include "qemu/bswap.h"
-#include "block/vhdx.h"
+#include "vhdx.h"
#include "migration/blocker.h"
#include "qemu/uuid.h"
#include "qapi/qmp/qdict.h"
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 54e643d871..a6b46cdc03 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -314,11 +314,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
msg.msg_controllen = 0;
}
- /* Set the version in the flags when sending the reply */
- vmsg->flags &= ~VHOST_USER_VERSION_MASK;
- vmsg->flags |= VHOST_USER_VERSION;
- vmsg->flags |= VHOST_USER_REPLY_MASK;
-
do {
rc = sendmsg(conn_fd, &msg, 0);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
@@ -341,6 +336,39 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
return true;
}
+static bool
+vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
+{
+ /* Set the version in the flags when sending the reply */
+ vmsg->flags &= ~VHOST_USER_VERSION_MASK;
+ vmsg->flags |= VHOST_USER_VERSION;
+ vmsg->flags |= VHOST_USER_REPLY_MASK;
+
+ return vu_message_write(dev, conn_fd, vmsg);
+}
+
+static bool
+vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg)
+{
+ VhostUserMsg msg_reply;
+
+ if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
+ return true;
+ }
+
+ if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) {
+ return false;
+ }
+
+ if (msg_reply.request != vmsg->request) {
+ DPRINT("Received unexpected msg type. Expected %d received %d",
+ vmsg->request, msg_reply.request);
+ return false;
+ }
+
+ return msg_reply.payload.u64 == 0;
+}
+
/* Kick the log_call_fd if required. */
static void
vu_log_kick(VuDev *dev)
@@ -536,7 +564,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
/* Send the message back to qemu with the addresses filled in */
vmsg->fd_num = 0;
- if (!vu_message_write(dev, dev->sock, vmsg)) {
+ if (!vu_send_reply(dev, dev->sock, vmsg)) {
vu_panic(dev, "failed to respond to set-mem-table for postcopy");
return false;
}
@@ -916,6 +944,41 @@ void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
}
}
+bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
+ int size, int offset)
+{
+ int qidx = vq - dev->vq;
+ int fd_num = 0;
+ VhostUserMsg vmsg = {
+ .request = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
+ .flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
+ .size = sizeof(vmsg.payload.area),
+ .payload.area = {
+ .u64 = qidx & VHOST_USER_VRING_IDX_MASK,
+ .size = size,
+ .offset = offset,
+ },
+ };
+
+ if (fd == -1) {
+ vmsg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;
+ } else {
+ vmsg.fds[fd_num++] = fd;
+ }
+
+ vmsg.fd_num = fd_num;
+
+ if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
+ return false;
+ }
+
+ if (!vu_message_write(dev, dev->slave_fd, &vmsg)) {
+ return false;
+ }
+
+ return vu_process_message_reply(dev, &vmsg);
+}
+
static bool
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
{
@@ -968,7 +1031,9 @@ static bool
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
{
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
- 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ;
+ 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ |
+ 1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER |
+ 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD;
if (have_userfault()) {
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
@@ -1252,7 +1317,7 @@ vu_dispatch(VuDev *dev)
goto end;
}
- if (!vu_message_write(dev, dev->sock, &vmsg)) {
+ if (!vu_send_reply(dev, dev->sock, &vmsg)) {
goto end;
}
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index b27075ea3b..4aa55b4d2d 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -51,6 +51,8 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
VHOST_USER_PROTOCOL_F_CONFIG = 9,
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
+ VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -92,6 +94,14 @@ typedef enum VhostUserRequest {
VHOST_USER_MAX
} VhostUserRequest;
+typedef enum VhostUserSlaveRequest {
+ VHOST_USER_SLAVE_NONE = 0,
+ VHOST_USER_SLAVE_IOTLB_MSG = 1,
+ VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
+ VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
+ VHOST_USER_SLAVE_MAX
+} VhostUserSlaveRequest;
+
typedef struct VhostUserMemoryRegion {
uint64_t guest_phys_addr;
uint64_t memory_size;
@@ -122,6 +132,12 @@ static VhostUserConfig c __attribute__ ((unused));
+ sizeof(c.size) \
+ sizeof(c.flags))
+typedef struct VhostUserVringArea {
+ uint64_t u64;
+ uint64_t size;
+ uint64_t offset;
+} VhostUserVringArea;
+
#if defined(_WIN32)
# define VU_PACKED __attribute__((gcc_struct, packed))
#else
@@ -133,6 +149,7 @@ typedef struct VhostUserMsg {
#define VHOST_USER_VERSION_MASK (0x3)
#define VHOST_USER_REPLY_MASK (0x1 << 2)
+#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
uint32_t flags;
uint32_t size; /* the following payload size */
@@ -145,6 +162,7 @@ typedef struct VhostUserMsg {
VhostUserMemory memory;
VhostUserLog log;
VhostUserConfig config;
+ VhostUserVringArea area;
} payload;
int fds[VHOST_MEMORY_MAX_NREGIONS];
@@ -368,6 +386,20 @@ VuVirtq *vu_get_queue(VuDev *dev, int qidx);
void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
vu_queue_handler_cb handler);
+/**
+ * vu_set_queue_host_notifier:
+ * @dev: a VuDev context
+ * @vq: a VuVirtq queue
+ * @fd: a file descriptor
+ * @size: host page size
+ * @offset: notifier offset in @fd file
+ *
+ * Set queue's host notifier. This function may be called several
+ * times for the same queue. If called with -1 @fd, the notifier
+ * is removed.
+ */
+bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
+ int size, int offset);
/**
* vu_queue_set_notification:
diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-blk/vhost-user-blk.c
index a6a132a492..571f114a56 100644
--- a/contrib/vhost-user-blk/vhost-user-blk.c
+++ b/contrib/vhost-user-blk/vhost-user-blk.c
@@ -31,6 +31,7 @@ typedef struct VubDev {
VugDev parent;
int blk_fd;
struct virtio_blk_config blkcfg;
+ bool enable_ro;
char *blk_name;
GMainLoop *loop;
} VubDev;
@@ -301,14 +302,27 @@ static void vub_queue_set_started(VuDev *vu_dev, int idx, bool started)
static uint64_t
vub_get_features(VuDev *dev)
{
- return 1ull << VIRTIO_BLK_F_SIZE_MAX |
- 1ull << VIRTIO_BLK_F_SEG_MAX |
- 1ull << VIRTIO_BLK_F_TOPOLOGY |
- 1ull << VIRTIO_BLK_F_BLK_SIZE |
- 1ull << VIRTIO_BLK_F_FLUSH |
- 1ull << VIRTIO_BLK_F_CONFIG_WCE |
- 1ull << VIRTIO_F_VERSION_1 |
- 1ull << VHOST_USER_F_PROTOCOL_FEATURES;
+ uint64_t features;
+ VugDev *gdev;
+ VubDev *vdev_blk;
+
+ gdev = container_of(dev, VugDev, parent);
+ vdev_blk = container_of(gdev, VubDev, parent);
+
+ features = 1ull << VIRTIO_BLK_F_SIZE_MAX |
+ 1ull << VIRTIO_BLK_F_SEG_MAX |
+ 1ull << VIRTIO_BLK_F_TOPOLOGY |
+ 1ull << VIRTIO_BLK_F_BLK_SIZE |
+ 1ull << VIRTIO_BLK_F_FLUSH |
+ 1ull << VIRTIO_BLK_F_CONFIG_WCE |
+ 1ull << VIRTIO_F_VERSION_1 |
+ 1ull << VHOST_USER_F_PROTOCOL_FEATURES;
+
+ if (vdev_blk->enable_ro) {
+ features |= 1ull << VIRTIO_BLK_F_RO;
+ }
+
+ return features;
}
static uint64_t
@@ -476,6 +490,7 @@ vub_new(char *blk_file)
vub_free(vdev_blk);
return NULL;
}
+ vdev_blk->enable_ro = false;
vdev_blk->blkcfg.wce = 0;
vdev_blk->blk_name = blk_file;
@@ -490,10 +505,11 @@ int main(int argc, char **argv)
int opt;
char *unix_socket = NULL;
char *blk_file = NULL;
+ bool enable_ro = false;
int lsock = -1, csock = -1;
VubDev *vdev_blk = NULL;
- while ((opt = getopt(argc, argv, "b:s:h")) != -1) {
+ while ((opt = getopt(argc, argv, "b:rs:h")) != -1) {
switch (opt) {
case 'b':
blk_file = g_strdup(optarg);
@@ -501,17 +517,20 @@ int main(int argc, char **argv)
case 's':
unix_socket = g_strdup(optarg);
break;
+ case 'r':
+ enable_ro = true;
+ break;
case 'h':
default:
- printf("Usage: %s [-b block device or file, -s UNIX domain socket]"
- " | [ -h ]\n", argv[0]);
+ printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
+ " | -r Enable read-only ] | [ -h ]\n", argv[0]);
return 0;
}
}
if (!unix_socket || !blk_file) {
- printf("Usage: %s [-b block device or file, -s UNIX domain socket] |"
- " [ -h ]\n", argv[0]);
+ printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
+ " | -r Enable read-only ] | [ -h ]\n", argv[0]);
return -1;
}
@@ -530,6 +549,9 @@ int main(int argc, char **argv)
if (!vdev_blk) {
goto err;
}
+ if (enable_ro) {
+ vdev_blk->enable_ro = true;
+ }
vug_init(&vdev_blk->parent, csock, vub_panic_cb, &vub_iface);
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index d418ac30b8..5738124773 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -22,7 +22,7 @@
#include "qapi/error.h"
#include "qemu/bswap.h"
-#include "crypto/block-luks.h"
+#include "block-luks.h"
#include "crypto/hash.h"
#include "crypto/afsplit.h"
diff --git a/crypto/block-luks.h b/crypto/block-luks.h
index b2d8a35c1b..befd8b2c56 100644
--- a/crypto/block-luks.h
+++ b/crypto/block-luks.h
@@ -21,7 +21,7 @@
#ifndef QCRYPTO_BLOCK_LUKS_H
#define QCRYPTO_BLOCK_LUKS_H
-#include "crypto/blockpriv.h"
+#include "blockpriv.h"
extern const QCryptoBlockDriver qcrypto_block_driver_luks;
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
index 8817d6aaa7..4284e05167 100644
--- a/crypto/block-qcow.c
+++ b/crypto/block-qcow.c
@@ -27,7 +27,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "crypto/block-qcow.h"
+#include "block-qcow.h"
#include "crypto/secret.h"
#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512
diff --git a/crypto/block-qcow.h b/crypto/block-qcow.h
index 3e2c0a851a..6988fb210b 100644
--- a/crypto/block-qcow.h
+++ b/crypto/block-qcow.h
@@ -21,7 +21,7 @@
#ifndef QCRYPTO_BLOCK_QCOW_H
#define QCRYPTO_BLOCK_QCOW_H
-#include "crypto/blockpriv.h"
+#include "blockpriv.h"
extern const QCryptoBlockDriver qcrypto_block_driver_qcow;
diff --git a/crypto/block.c b/crypto/block.c
index f206d5eea8..e59d1140fe 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -20,9 +20,9 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "crypto/blockpriv.h"
-#include "crypto/block-qcow.h"
-#include "crypto/block-luks.h"
+#include "blockpriv.h"
+#include "block-qcow.h"
+#include "block-luks.h"
static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
[Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
diff --git a/crypto/cipher.c b/crypto/cipher.c
index bcbfb3d5b8..b3af57961b 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -150,11 +150,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
#ifdef CONFIG_GCRYPT
-#include "crypto/cipher-gcrypt.c"
+#include "cipher-gcrypt.c"
#elif defined CONFIG_NETTLE
-#include "crypto/cipher-nettle.c"
+#include "cipher-nettle.c"
#else
-#include "crypto/cipher-builtin.c"
+#include "cipher-builtin.c"
#endif
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
diff --git a/crypto/ivgen-essiv.c b/crypto/ivgen-essiv.c
index aeaa8fcd5b..43e258c6f7 100644
--- a/crypto/ivgen-essiv.c
+++ b/crypto/ivgen-essiv.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "qemu/bswap.h"
-#include "crypto/ivgen-essiv.h"
+#include "ivgen-essiv.h"
typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV;
struct QCryptoIVGenESSIV {
diff --git a/crypto/ivgen-essiv.h b/crypto/ivgen-essiv.h
index 4a00af849a..f34dbab57b 100644
--- a/crypto/ivgen-essiv.h
+++ b/crypto/ivgen-essiv.h
@@ -18,7 +18,7 @@
*
*/
-#include "crypto/ivgenpriv.h"
+#include "ivgenpriv.h"
#ifndef QCRYPTO_IVGEN_ESSIV_H__
#define QCRYPTO_IVGEN_ESSIV_H__
diff --git a/crypto/ivgen-plain.c b/crypto/ivgen-plain.c
index bf2fb7aac4..06f4145fe5 100644
--- a/crypto/ivgen-plain.c
+++ b/crypto/ivgen-plain.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "qemu/bswap.h"
-#include "crypto/ivgen-plain.h"
+#include "ivgen-plain.h"
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
const uint8_t *key, size_t nkey,
diff --git a/crypto/ivgen-plain.h b/crypto/ivgen-plain.h
index 0fe8835c3e..16e1ae5b27 100644
--- a/crypto/ivgen-plain.h
+++ b/crypto/ivgen-plain.h
@@ -18,7 +18,7 @@
*
*/
-#include "crypto/ivgenpriv.h"
+#include "ivgenpriv.h"
#ifndef QCRYPTO_IVGEN_PLAIN_H__
#define QCRYPTO_IVGEN_PLAIN_H__
diff --git a/crypto/ivgen-plain64.c b/crypto/ivgen-plain64.c
index e4679a1e6e..fbb7724b20 100644
--- a/crypto/ivgen-plain64.c
+++ b/crypto/ivgen-plain64.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "qemu/bswap.h"
-#include "crypto/ivgen-plain.h"
+#include "ivgen-plain.h"
static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen,
const uint8_t *key, size_t nkey,
diff --git a/crypto/ivgen-plain64.h b/crypto/ivgen-plain64.h
index c4104459b5..f8611bd705 100644
--- a/crypto/ivgen-plain64.h
+++ b/crypto/ivgen-plain64.h
@@ -18,7 +18,7 @@
*
*/
-#include "crypto/ivgenpriv.h"
+#include "ivgenpriv.h"
#ifndef QCRYPTO_IVGEN_PLAIN64_H__
#define QCRYPTO_IVGEN_PLAIN64_H__
diff --git a/crypto/ivgen.c b/crypto/ivgen.c
index f66435112b..6a2b3ad01e 100644
--- a/crypto/ivgen.c
+++ b/crypto/ivgen.c
@@ -21,10 +21,10 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "crypto/ivgenpriv.h"
-#include "crypto/ivgen-plain.h"
-#include "crypto/ivgen-plain64.h"
-#include "crypto/ivgen-essiv.h"
+#include "ivgenpriv.h"
+#include "ivgen-plain.h"
+#include "ivgen-plain64.h"
+#include "ivgen-essiv.h"
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c
index 3cd41035bb..02255a6f3c 100644
--- a/crypto/tlscreds.c
+++ b/crypto/tlscreds.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "crypto/tlscredspriv.h"
+#include "tlscredspriv.h"
#include "trace.h"
#define DH_BITS 2048
diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c
index 1464220080..7ad66d1e7d 100644
--- a/crypto/tlscredsanon.c
+++ b/crypto/tlscredsanon.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "crypto/tlscredsanon.h"
-#include "crypto/tlscredspriv.h"
+#include "tlscredspriv.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "trace.h"
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index 50eb54f6bb..98ee0424e5 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "crypto/tlscredsx509.h"
-#include "crypto/tlscredspriv.h"
+#include "tlscredspriv.h"
#include "crypto/secret.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index 534caab18a..d51fd58242 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -132,6 +132,16 @@ Depending on the request type, payload can be:
Payload: Size bytes array holding the contents of the virtio
device's configuration space
+ * Vring area description
+ -----------------------
+ | u64 | size | offset |
+ -----------------------
+
+ u64: a 64-bit integer contains vring index and flags
+ Size: a 64-bit size of this area
+ Offset: a 64-bit offset of this area from the start of the
+ supplied file descriptor
+
In QEMU the vhost-user message is implemented with the following struct:
typedef struct VhostUserMsg {
@@ -146,6 +156,7 @@ typedef struct VhostUserMsg {
VhostUserLog log;
struct vhost_iotlb_msg iotlb;
VhostUserConfig config;
+ VhostUserVringArea area;
};
} QEMU_PACKED VhostUserMsg;
@@ -367,6 +378,10 @@ The fd is provided via VHOST_USER_SET_SLAVE_REQ_FD ancillary data.
A slave may then send VHOST_USER_SLAVE_* messages to the master
using this fd communication channel.
+If VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature is negotiated,
+slave can send file descriptors (at most 8 descriptors in each message)
+to master via ancillary data using this fd communication channel.
+
Protocol features
-----------------
@@ -380,6 +395,8 @@ Protocol features
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
#define VHOST_USER_PROTOCOL_F_CONFIG 9
+#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10
+#define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
Master message types
--------------------
@@ -777,6 +794,27 @@ Slave message types
the VHOST_USER_NEED_REPLY flag, master must respond with zero when
operation is successfully completed, or non-zero otherwise.
+ * VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG
+
+ Id: 3
+ Equivalent ioctl: N/A
+ Slave payload: vring area description
+ Master payload: N/A
+
+ Sets host notifier for a specified queue. The queue index is contained
+ in the u64 field of the vring area description. The host notifier is
+ described by the file descriptor (typically it's a VFIO device fd) which
+ is passed as ancillary data and the size (which is mmap size and should
+ be the same as host page size) and offset (which is mmap offset) carried
+ in the vring area description. QEMU can mmap the file descriptor based
+ on the size and offset to get a memory range. Registering a host notifier
+ means mapping this memory range to the VM as the specified queue's notify
+ MMIO region. Slave sends this request to tell QEMU to de-register the
+ existing notifier if any and register the new notifier if the request is
+ sent with a file descriptor.
+ This request should be sent only when VHOST_USER_PROTOCOL_F_HOST_NOTIFIER
+ protocol feature has been successfully negotiated.
+
VHOST_USER_PROTOCOL_F_REPLY_ACK:
-------------------------------
The original vhost-user specification only demands replies for certain
diff --git a/docs/nvdimm.txt b/docs/nvdimm.txt
index e903d8bb09..8b48fb4633 100644
--- a/docs/nvdimm.txt
+++ b/docs/nvdimm.txt
@@ -153,3 +153,30 @@ guest NVDIMM region mapping structure. This unarmed flag indicates
guest software that this vNVDIMM device contains a region that cannot
accept persistent writes. In result, for example, the guest Linux
NVDIMM driver, marks such vNVDIMM device as read-only.
+
+Platform Capabilities
+---------------------
+
+ACPI 6.2 Errata A added support for a new Platform Capabilities Structure
+which allows the platform to communicate what features it supports related to
+NVDIMM data durability. Users can provide a capabilities value to a guest via
+the optional "nvdimm-cap" machine command line option:
+
+ -machine pc,accel=kvm,nvdimm,nvdimm-cap=2
+
+This "nvdimm-cap" field is an integer, and is the combined value of the
+various capability bits defined in table 5-137 of the ACPI 6.2 Errata A spec.
+
+Here is a quick summary of the three bits that are defined as of that spec:
+
+Bit[0] - CPU Cache Flush to NVDIMM Durability on Power Loss Capable.
+Bit[1] - Memory Controller Flush to NVDIMM Durability on Power Loss Capable.
+ Note: If bit 0 is set to 1 then this bit shall be set to 1 as well.
+Bit[2] - Byte Addressable Persistent Memory Hardware Mirroring Capable.
+
+So, a "nvdimm-cap" value of 2 would mean that the platform supports Memory
+Controller Flush on Power Loss, a value of 3 would mean that the platform
+supports CPU Cache Flush and Memory Controller Flush on Power Loss, etc.
+
+For a complete list of the flags available and for more detailed descriptions,
+please consult the ACPI spec.
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 59d6e4254c..87e4280c71 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -170,6 +170,21 @@ struct NvdimmNfitControlRegion {
typedef struct NvdimmNfitControlRegion NvdimmNfitControlRegion;
/*
+ * NVDIMM Platform Capabilities Structure
+ *
+ * Defined in section 5.2.25.9 of ACPI 6.2 Errata A, September 2017
+ */
+struct NvdimmNfitPlatformCaps {
+ uint16_t type;
+ uint16_t length;
+ uint8_t highest_cap;
+ uint8_t reserved[3];
+ uint32_t capabilities;
+ uint8_t reserved2[4];
+} QEMU_PACKED;
+typedef struct NvdimmNfitPlatformCaps NvdimmNfitPlatformCaps;
+
+/*
* Module serial number is a unique number for each device. We use the
* slot id of NVDIMM device to generate this number so that each device
* associates with a different number.
@@ -351,7 +366,23 @@ static void nvdimm_build_structure_dcr(GArray *structures, DeviceState *dev)
JEDEC Annex L Release 3. */);
}
-static GArray *nvdimm_build_device_structure(void)
+/*
+ * ACPI 6.2 Errata A: 5.2.25.9 NVDIMM Platform Capabilities Structure
+ */
+static void
+nvdimm_build_structure_caps(GArray *structures, uint32_t capabilities)
+{
+ NvdimmNfitPlatformCaps *nfit_caps;
+
+ nfit_caps = acpi_data_push(structures, sizeof(*nfit_caps));
+
+ nfit_caps->type = cpu_to_le16(7 /* NVDIMM Platform Capabilities */);
+ nfit_caps->length = cpu_to_le16(sizeof(*nfit_caps));
+ nfit_caps->highest_cap = 31 - clz32(capabilities);
+ nfit_caps->capabilities = cpu_to_le32(capabilities);
+}
+
+static GArray *nvdimm_build_device_structure(AcpiNVDIMMState *state)
{
GSList *device_list = nvdimm_get_device_list();
GArray *structures = g_array_new(false, true /* clear */, 1);
@@ -373,6 +404,10 @@ static GArray *nvdimm_build_device_structure(void)
}
g_slist_free(device_list);
+ if (state->capabilities) {
+ nvdimm_build_structure_caps(structures, state->capabilities);
+ }
+
return structures;
}
@@ -381,16 +416,18 @@ static void nvdimm_init_fit_buffer(NvdimmFitBuffer *fit_buf)
fit_buf->fit = g_array_new(false, true /* clear */, 1);
}
-static void nvdimm_build_fit_buffer(NvdimmFitBuffer *fit_buf)
+static void nvdimm_build_fit_buffer(AcpiNVDIMMState *state)
{
+ NvdimmFitBuffer *fit_buf = &state->fit_buf;
+
g_array_free(fit_buf->fit, true);
- fit_buf->fit = nvdimm_build_device_structure();
+ fit_buf->fit = nvdimm_build_device_structure(state);
fit_buf->dirty = true;
}
void nvdimm_plug(AcpiNVDIMMState *state)
{
- nvdimm_build_fit_buffer(&state->fit_buf);
+ nvdimm_build_fit_buffer(state);
}
static void nvdimm_build_nfit(AcpiNVDIMMState *state, GArray *table_offsets,
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 975eae6211..d755223643 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -203,13 +203,11 @@ static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev,
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
+ virtio_add_feature(&features, VIRTIO_BLK_F_RO);
if (s->config_wce) {
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
}
- if (s->config_ro) {
- virtio_add_feature(&features, VIRTIO_BLK_F_RO);
- }
if (s->num_queues > 1) {
virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
}
@@ -226,6 +224,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ VhostUserState *user;
int i, ret;
if (!s->chardev.chr) {
@@ -243,6 +242,15 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
return;
}
+ user = vhost_user_init();
+ if (!user) {
+ error_setg(errp, "vhost-user-blk: failed to init vhost_user");
+ return;
+ }
+
+ user->chr = &s->chardev;
+ s->vhost_user = user;
+
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config));
@@ -258,7 +266,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
- ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0);
+ ret = vhost_dev_init(&s->dev, s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
strerror(-ret));
@@ -283,6 +291,10 @@ vhost_err:
virtio_err:
g_free(s->dev.vqs);
virtio_cleanup(vdev);
+
+ vhost_user_cleanup(user);
+ g_free(user);
+ s->vhost_user = NULL;
}
static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -294,6 +306,12 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
vhost_dev_cleanup(&s->dev);
g_free(s->dev.vqs);
virtio_cleanup(vdev);
+
+ if (s->vhost_user) {
+ vhost_user_cleanup(s->vhost_user);
+ g_free(s->vhost_user);
+ s->vhost_user = NULL;
+ }
}
static void vhost_user_blk_instance_init(Object *obj)
@@ -319,7 +337,6 @@ static Property vhost_user_blk_properties[] = {
DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
- DEFINE_PROP_BIT("config-ro", VHostUserBlk, config_ro, 0, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
index 7eab927652..3355f4c131 100644
--- a/hw/display/bcm2835_fb.c
+++ b/hw/display/bcm2835_fb.c
@@ -26,7 +26,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/display/bcm2835_fb.h"
-#include "hw/display/framebuffer.h"
+#include "framebuffer.h"
#include "ui/pixel_ops.h"
#include "hw/misc/bcm2835_mbox_defs.h"
#include "qemu/log.h"
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
index 3f6c145120..f5f983bf4c 100644
--- a/hw/hppa/hppa_sys.h
+++ b/hw/hppa/hppa_sys.h
@@ -9,7 +9,7 @@
#include "hw/i386/pc.h"
#include "hw/irq.h"
-#include "hw/hppa/hppa_hardware.h"
+#include "hppa_hardware.h"
PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index a1d6b0ebfb..aba269bb85 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -16,7 +16,7 @@
#include "hw/ide.h"
#include "hw/timer/i8254.h"
#include "hw/char/serial.h"
-#include "hw/hppa/hppa_sys.h"
+#include "hppa_sys.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qemu/log.h"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8b0803cb83..f3befe6721 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2181,6 +2181,33 @@ static void pc_machine_set_nvdimm(Object *obj, bool value, Error **errp)
pcms->acpi_nvdimm_state.is_enabled = value;
}
+static void pc_machine_get_nvdimm_capabilities(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ PCMachineState *pcms = PC_MACHINE(obj);
+ uint32_t value = pcms->acpi_nvdimm_state.capabilities;
+
+ visit_type_uint32(v, name, &value, errp);
+}
+
+static void pc_machine_set_nvdimm_capabilities(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ PCMachineState *pcms = PC_MACHINE(obj);
+ Error *error = NULL;
+ uint32_t value;
+
+ visit_type_uint32(v, name, &value, &error);
+ if (error) {
+ error_propagate(errp, error);
+ return;
+ }
+
+ pcms->acpi_nvdimm_state.capabilities = value;
+}
+
static bool pc_machine_get_smbus(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
@@ -2394,6 +2421,10 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, PC_MACHINE_NVDIMM,
pc_machine_get_nvdimm, pc_machine_set_nvdimm, &error_abort);
+ object_class_property_add(oc, PC_MACHINE_NVDIMM_CAP, "uint32",
+ pc_machine_get_nvdimm_capabilities,
+ pc_machine_set_nvdimm_capabilities, NULL, NULL, &error_abort);
+
object_class_property_add_bool(oc, PC_MACHINE_SMBUS,
pc_machine_get_smbus, pc_machine_set_smbus, &error_abort);
diff --git a/hw/ide/ahci-allwinner.c b/hw/ide/ahci-allwinner.c
index 2fd95078ba..f98e6cb3d4 100644
--- a/hw/ide/ahci-allwinner.c
+++ b/hw/ide/ahci-allwinner.c
@@ -20,7 +20,7 @@
#include "qemu/error-report.h"
#include "sysemu/dma.h"
#include "hw/ide/internal.h"
-#include "hw/ide/ahci_internal.h"
+#include "ahci_internal.h"
#include "trace.h"
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index e22d7be05f..24dbad5125 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -31,7 +31,7 @@
#include "sysemu/dma.h"
#include "hw/ide/internal.h"
#include "hw/ide/pci.h"
-#include "hw/ide/ahci_internal.h"
+#include "ahci_internal.h"
#include "trace.h"
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 134478ebb2..51c935a0da 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -67,7 +67,7 @@
#include "hw/isa/isa.h"
#include "sysemu/dma.h"
#include "hw/ide/pci.h"
-#include "hw/ide/ahci_internal.h"
+#include "ahci_internal.h"
#define ICH9_MSI_CAP_OFFSET 0x80
#define ICH9_SATA_CAP_OFFSET 0xA8
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 36139a4db6..c45f073271 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -28,9 +28,8 @@
#include "hw/i386/apic.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
-#include "include/hw/pci/msi.h"
+#include "hw/pci/msi.h"
#include "sysemu/kvm.h"
-#include "target/i386/cpu.h"
#include "hw/i386/apic-msidef.h"
#include "hw/i386/x86-iommu.h"
#include "trace.h"
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index 16a9417a85..cda8d48333 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -41,7 +41,7 @@
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
-#include "hw/net/e1000_regs.h"
+#include "e1000_regs.h"
#include "e1000x_common.h"
#include "e1000e_core.h"
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 27b17c890f..4aa7da79b8 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -15,7 +15,6 @@
*/
#include "qemu/osdep.h"
-#include "net/clients.h"
#include "qapi/qapi-types-rocker.h"
#include "rocker.h"
#include "rocker_hw.h"
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index e312fdba70..123f4ac09d 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -20,7 +20,7 @@
#include "hw/ppc/ppc.h"
#include "hw/pci/pci.h"
#include "sysemu/block-backend.h"
-#include "hw/ppc/ppc440.h"
+#include "ppc440.h"
/*****************************************************************************/
/* L2 Cache as SRAM */
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 3dd23de71f..bdc53d2603 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -26,8 +26,8 @@
#include "elf.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
-#include "hw/ppc/ppc440.h"
-#include "hw/ppc/ppc405.h"
+#include "ppc440.h"
+#include "ppc405.h"
#include "hw/block/flash.h"
#include "sysemu/sysemu.h"
#include "sysemu/qtest.h"
diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index 77e9897244..e2a5828af1 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -17,7 +17,6 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "migration/migration.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-scsi-common.h"
#include "hw/virtio/virtio-scsi.h"
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 9389ed48e0..9355cfdf07 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -69,6 +69,7 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+ VhostUserState *user;
Error *err = NULL;
int ret;
@@ -85,19 +86,30 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
return;
}
+ user = vhost_user_init();
+ if (!user) {
+ error_setg(errp, "vhost-user-scsi: failed to init vhost_user");
+ return;
+ }
+ user->chr = &vs->conf.chardev;
+
vsc->dev.nvqs = 2 + vs->conf.num_queues;
vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
vsc->dev.vq_index = 0;
vsc->dev.backend_features = 0;
- ret = vhost_dev_init(&vsc->dev, (void *)&vs->conf.chardev,
+ ret = vhost_dev_init(&vsc->dev, user,
VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
strerror(-ret));
+ vhost_user_cleanup(user);
+ g_free(user);
return;
}
+ s->vhost_user = user;
+
/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
vsc->channel = 0;
vsc->lun = 0;
@@ -117,6 +129,12 @@ static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
g_free(vsc->dev.vqs);
virtio_scsi_common_unrealize(dev, errp);
+
+ if (s->vhost_user) {
+ vhost_user_cleanup(s->vhost_user);
+ g_free(s->vhost_user);
+ s->vhost_user = NULL;
+ }
}
static uint64_t vhost_user_scsi_get_features(VirtIODevice *vdev,
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 5570c1e9a0..fe1cccca76 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -27,7 +27,7 @@
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
#include "trace.h"
-#include "include/qapi/error.h"
+#include "qapi/error.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/sd/sd.h"
diff --git a/hw/usb/desc-msos.c b/hw/usb/desc-msos.c
index 3652919815..3a5ad7c8d0 100644
--- a/hw/usb/desc-msos.c
+++ b/hw/usb/desc-msos.c
@@ -1,6 +1,6 @@
#include "qemu/osdep.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
/*
* Microsoft OS Descriptors
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 85c15addc5..8b6eaea407 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -1,7 +1,7 @@
#include "qemu/osdep.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "trace.h"
/* ------------------------------------------------------------------ */
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index 343345235c..ee43e4914d 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -32,7 +32,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "hw/hw.h"
#include "audio/audio.h"
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index 0bbceaea0b..eac7365b0a 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -22,7 +22,7 @@
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index c40019df96..62d18290dc 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -26,7 +26,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "hw/input/hid.h"
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 752e30c305..5d9743ef93 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -26,7 +26,7 @@
#include "qemu-common.h"
#include "trace.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "qemu/error-report.h"
#define NUM_PORTS 8
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 3d59fe4944..560c61c7c1 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -24,7 +24,7 @@
#include "qemu/iov.h"
#include "trace.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
/* ----------------------------------------------------------------------- */
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index aea7edcf31..385e090336 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -27,7 +27,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "net/net.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 2829dda391..98d1ca3c91 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -14,7 +14,7 @@
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "chardev/char-serial.h"
#include "chardev/char-fe.h"
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index f7451923f4..2131e33d27 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -39,7 +39,7 @@
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "ccid.h"
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index d02acda945..481694a473 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -14,7 +14,7 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "hw/scsi/scsi.h"
#include "ui/console.h"
#include "monitor/monitor.h"
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index c218b53f09..aaf5a88095 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -17,7 +17,7 @@
#include "qemu/error-report.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index bf70013059..ac0bc83b52 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -29,7 +29,7 @@
#include "hw/hw.h"
#include "ui/console.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "desc.h"
/* Interface requests */
#define WACOM_GET_REPORT 0x2101
diff --git a/hw/virtio/vhost-stub.c b/hw/virtio/vhost-stub.c
index 2d76cdebdc..049089b5e2 100644
--- a/hw/virtio/vhost-stub.c
+++ b/hw/virtio/vhost-stub.c
@@ -1,7 +1,17 @@
#include "qemu/osdep.h"
#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
bool vhost_has_free_slot(void)
{
return true;
}
+
+VhostUserState *vhost_user_init(void)
+{
+ return NULL;
+}
+
+void vhost_user_cleanup(VhostUserState *user)
+{
+}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ca554d4ff1..b041343632 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -11,7 +11,9 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
#include "hw/virtio/vhost-backend.h"
+#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-net.h"
#include "chardev/char-fe.h"
#include "sysemu/kvm.h"
@@ -30,6 +32,7 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
+#define VHOST_USER_SLAVE_MAX_FDS 8
/*
* Maximum size of virtio device config space
@@ -47,6 +50,8 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
VHOST_USER_PROTOCOL_F_CONFIG = 9,
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
+ VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -91,6 +96,7 @@ typedef enum VhostUserSlaveRequest {
VHOST_USER_SLAVE_NONE = 0,
VHOST_USER_SLAVE_IOTLB_MSG = 1,
VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
+ VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
VHOST_USER_SLAVE_MAX
} VhostUserSlaveRequest;
@@ -135,6 +141,12 @@ static VhostUserConfig c __attribute__ ((unused));
+ sizeof(c.size) \
+ sizeof(c.flags))
+typedef struct VhostUserVringArea {
+ uint64_t u64;
+ uint64_t size;
+ uint64_t offset;
+} VhostUserVringArea;
+
typedef struct {
VhostUserRequest request;
@@ -156,6 +168,7 @@ typedef union {
struct vhost_iotlb_msg iotlb;
VhostUserConfig config;
VhostUserCryptoSession session;
+ VhostUserVringArea area;
} VhostUserPayload;
typedef struct VhostUserMsg {
@@ -173,7 +186,8 @@ static VhostUserMsg m __attribute__ ((unused));
struct vhost_user {
struct vhost_dev *dev;
- CharBackend *chr;
+ /* Shared between vhost devs of the same virtio device */
+ VhostUserState *user;
int slave_fd;
NotifierWithReturn postcopy_notifier;
struct PostCopyFD postcopy_fd;
@@ -199,7 +213,7 @@ static bool ioeventfd_enabled(void)
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user *u = dev->opaque;
- CharBackend *chr = u->chr;
+ CharBackend *chr = u->user->chr;
uint8_t *p = (uint8_t *) msg;
int r, size = VHOST_USER_HDR_SIZE;
@@ -285,7 +299,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
int *fds, int fd_num)
{
struct vhost_user *u = dev->opaque;
- CharBackend *chr = u->chr;
+ CharBackend *chr = u->user->chr;
int ret, size = VHOST_USER_HDR_SIZE + msg->hdr.size;
/*
@@ -636,9 +650,37 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev,
return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
}
+static void vhost_user_host_notifier_restore(struct vhost_dev *dev,
+ int queue_idx)
+{
+ struct vhost_user *u = dev->opaque;
+ VhostUserHostNotifier *n = &u->user->notifier[queue_idx];
+ VirtIODevice *vdev = dev->vdev;
+
+ if (n->addr && !n->set) {
+ virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true);
+ n->set = true;
+ }
+}
+
+static void vhost_user_host_notifier_remove(struct vhost_dev *dev,
+ int queue_idx)
+{
+ struct vhost_user *u = dev->opaque;
+ VhostUserHostNotifier *n = &u->user->notifier[queue_idx];
+ VirtIODevice *vdev = dev->vdev;
+
+ if (n->addr && n->set) {
+ virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false);
+ n->set = false;
+ }
+}
+
static int vhost_user_set_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
+ vhost_user_host_notifier_restore(dev, ring->index);
+
return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
}
@@ -672,6 +714,8 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev,
.hdr.size = sizeof(msg.payload.state),
};
+ vhost_user_host_notifier_remove(dev, ring->index);
+
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
return -1;
}
@@ -845,6 +889,66 @@ static int vhost_user_slave_handle_config_change(struct vhost_dev *dev)
return ret;
}
+static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev,
+ VhostUserVringArea *area,
+ int fd)
+{
+ int queue_idx = area->u64 & VHOST_USER_VRING_IDX_MASK;
+ size_t page_size = qemu_real_host_page_size;
+ struct vhost_user *u = dev->opaque;
+ VhostUserState *user = u->user;
+ VirtIODevice *vdev = dev->vdev;
+ VhostUserHostNotifier *n;
+ void *addr;
+ char *name;
+
+ if (!virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) ||
+ vdev == NULL || queue_idx >= virtio_get_num_queues(vdev)) {
+ return -1;
+ }
+
+ n = &user->notifier[queue_idx];
+
+ if (n->addr) {
+ virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false);
+ object_unparent(OBJECT(&n->mr));
+ munmap(n->addr, page_size);
+ n->addr = NULL;
+ }
+
+ if (area->u64 & VHOST_USER_VRING_NOFD_MASK) {
+ return 0;
+ }
+
+ /* Sanity check. */
+ if (area->size != page_size) {
+ return -1;
+ }
+
+ addr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, area->offset);
+ if (addr == MAP_FAILED) {
+ return -1;
+ }
+
+ name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]",
+ user, queue_idx);
+ memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
+ page_size, addr);
+ g_free(name);
+
+ if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) {
+ munmap(addr, page_size);
+ return -1;
+ }
+
+ n->addr = addr;
+ n->set = true;
+
+ return 0;
+}
+
static void slave_read(void *opaque)
{
struct vhost_dev *dev = opaque;
@@ -854,10 +958,10 @@ static void slave_read(void *opaque)
int size, ret = 0;
struct iovec iov;
struct msghdr msgh;
- int fd = -1;
+ int fd[VHOST_USER_SLAVE_MAX_FDS];
char control[CMSG_SPACE(sizeof(fd))];
struct cmsghdr *cmsg;
- size_t fdsize;
+ int i, fdsize = 0;
memset(&msgh, 0, sizeof(msgh));
msgh.msg_iov = &iov;
@@ -865,6 +969,8 @@ static void slave_read(void *opaque)
msgh.msg_control = control;
msgh.msg_controllen = sizeof(control);
+ memset(fd, -1, sizeof(fd));
+
/* Read header */
iov.iov_base = &hdr;
iov.iov_len = VHOST_USER_HDR_SIZE;
@@ -885,7 +991,7 @@ static void slave_read(void *opaque)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
- memcpy(&fd, CMSG_DATA(cmsg), fdsize);
+ memcpy(fd, CMSG_DATA(cmsg), fdsize);
break;
}
}
@@ -911,16 +1017,21 @@ static void slave_read(void *opaque)
case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
ret = vhost_user_slave_handle_config_change(dev);
break;
+ case VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG:
+ ret = vhost_user_slave_handle_vring_host_notifier(dev, &payload.area,
+ fd[0]);
+ break;
default:
error_report("Received unexpected msg type.");
- if (fd != -1) {
- close(fd);
- }
ret = -EINVAL;
}
- /* Message handlers need to make sure that fd will be consumed. */
- fd = -1;
+ /* Close the remaining file descriptors. */
+ for (i = 0; i < fdsize; i++) {
+ if (fd[i] != -1) {
+ close(fd[i]);
+ }
+ }
/*
* REPLY_ACK feature handling. Other reply types has to be managed
@@ -954,8 +1065,10 @@ err:
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
close(u->slave_fd);
u->slave_fd = -1;
- if (fd != -1) {
- close(fd);
+ for (i = 0; i < fdsize; i++) {
+ if (fd[i] != -1) {
+ close(fd[i]);
+ }
}
return;
}
@@ -1083,7 +1196,7 @@ static int vhost_user_postcopy_waker(struct PostCopyFD *pcfd, RAMBlock *rb,
static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
{
struct vhost_user *u = dev->opaque;
- CharBackend *chr = u->chr;
+ CharBackend *chr = u->user->chr;
int ufd;
VhostUserMsg msg = {
.hdr.request = VHOST_USER_POSTCOPY_ADVISE,
@@ -1221,7 +1334,7 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
return 0;
}
-static int vhost_user_init(struct vhost_dev *dev, void *opaque)
+static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
{
uint64_t features, protocol_features;
struct vhost_user *u;
@@ -1230,7 +1343,7 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
u = g_new0(struct vhost_user, 1);
- u->chr = opaque;
+ u->user = opaque;
u->slave_fd = -1;
u->dev = dev;
dev->opaque = u;
@@ -1306,7 +1419,7 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
return 0;
}
-static int vhost_user_cleanup(struct vhost_dev *dev)
+static int vhost_user_backend_cleanup(struct vhost_dev *dev)
{
struct vhost_user *u;
@@ -1620,10 +1733,40 @@ vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id)
return 0;
}
+static bool vhost_user_mem_section_filter(struct vhost_dev *dev,
+ MemoryRegionSection *section)
+{
+ bool result;
+
+ result = memory_region_get_fd(section->mr) >= 0;
+
+ return result;
+}
+
+VhostUserState *vhost_user_init(void)
+{
+ VhostUserState *user = g_new0(struct VhostUserState, 1);
+
+ return user;
+}
+
+void vhost_user_cleanup(VhostUserState *user)
+{
+ int i;
+
+ for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
+ if (user->notifier[i].addr) {
+ object_unparent(OBJECT(&user->notifier[i].mr));
+ munmap(user->notifier[i].addr, qemu_real_host_page_size);
+ user->notifier[i].addr = NULL;
+ }
+ }
+}
+
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
- .vhost_backend_init = vhost_user_init,
- .vhost_backend_cleanup = vhost_user_cleanup,
+ .vhost_backend_init = vhost_user_backend_init,
+ .vhost_backend_cleanup = vhost_user_backend_cleanup,
.vhost_backend_memslots_limit = vhost_user_memslots_limit,
.vhost_set_log_base = vhost_user_set_log_base,
.vhost_set_mem_table = vhost_user_set_mem_table,
@@ -1650,4 +1793,5 @@ const VhostOps user_ops = {
.vhost_set_config = vhost_user_set_config,
.vhost_crypto_create_session = vhost_user_crypto_create_session,
.vhost_crypto_close_session = vhost_user_crypto_close_session,
+ .vhost_backend_mem_section_filter = vhost_user_mem_section_filter,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 4565b69f83..96175b214d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -386,7 +386,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
return r;
}
-static bool vhost_section(MemoryRegionSection *section)
+static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
{
bool result;
bool log_dirty = memory_region_get_dirty_log_mask(section->mr) &
@@ -399,6 +399,11 @@ static bool vhost_section(MemoryRegionSection *section)
*/
result &= !log_dirty;
+ if (result && dev->vhost_ops->vhost_backend_mem_section_filter) {
+ result &=
+ dev->vhost_ops->vhost_backend_mem_section_filter(dev, section);
+ }
+
trace_vhost_section(section->mr->name, result);
return result;
}
@@ -632,7 +637,7 @@ static void vhost_region_addnop(MemoryListener *listener,
struct vhost_dev *dev = container_of(listener, struct vhost_dev,
memory_listener);
- if (!vhost_section(section)) {
+ if (!vhost_section(dev, section)) {
return;
}
vhost_region_add_section(dev, section);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index a0c269fc34..04d1f8c6c3 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -76,6 +76,7 @@ struct PCMachineState {
#define PC_MACHINE_VMPORT "vmport"
#define PC_MACHINE_SMM "smm"
#define PC_MACHINE_NVDIMM "nvdimm"
+#define PC_MACHINE_NVDIMM_CAP "nvdimm-cap"
#define PC_MACHINE_SMBUS "smbus"
#define PC_MACHINE_SATA "sata"
#define PC_MACHINE_PIT "pit"
diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h
index 74c60332e1..3c82751bab 100644
--- a/include/hw/mem/nvdimm.h
+++ b/include/hw/mem/nvdimm.h
@@ -134,6 +134,11 @@ struct AcpiNVDIMMState {
/* the IO region used by OSPM to transfer control to QEMU. */
MemoryRegion io_mr;
+
+ /*
+ * Platform capabilities, section 5.2.25.9 of ACPI 6.2 Errata A
+ */
+ int32_t capabilities;
};
typedef struct AcpiNVDIMMState AcpiNVDIMMState;
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 5dac61f9ea..81283ec50f 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -101,6 +101,9 @@ typedef int (*vhost_crypto_create_session_op)(struct vhost_dev *dev,
typedef int (*vhost_crypto_close_session_op)(struct vhost_dev *dev,
uint64_t session_id);
+typedef bool (*vhost_backend_mem_section_filter_op)(struct vhost_dev *dev,
+ MemoryRegionSection *section);
+
typedef struct VhostOps {
VhostBackendType backend_type;
vhost_backend_init vhost_backend_init;
@@ -138,6 +141,7 @@ typedef struct VhostOps {
vhost_set_config_op vhost_set_config;
vhost_crypto_create_session_op vhost_crypto_create_session;
vhost_crypto_close_session_op vhost_crypto_close_session;
+ vhost_backend_mem_section_filter_op vhost_backend_mem_section_filter;
} VhostOps;
extern const VhostOps user_ops;
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index 5804cc904a..d52944aeeb 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -21,6 +21,7 @@
#include "hw/block/block.h"
#include "chardev/char-fe.h"
#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
#define TYPE_VHOST_USER_BLK "vhost-user-blk"
#define VHOST_USER_BLK(obj) \
@@ -34,8 +35,8 @@ typedef struct VHostUserBlk {
uint16_t num_queues;
uint32_t queue_size;
uint32_t config_wce;
- uint32_t config_ro;
struct vhost_dev dev;
+ VhostUserState *vhost_user;
} VHostUserBlk;
#endif
diff --git a/include/hw/virtio/vhost-user-scsi.h b/include/hw/virtio/vhost-user-scsi.h
index 01861f78d0..3ec34ae867 100644
--- a/include/hw/virtio/vhost-user-scsi.h
+++ b/include/hw/virtio/vhost-user-scsi.h
@@ -21,6 +21,7 @@
#include "hw/qdev.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
#include "hw/virtio/vhost-scsi-common.h"
#define TYPE_VHOST_USER_SCSI "vhost-user-scsi"
@@ -30,6 +31,7 @@
typedef struct VHostUserSCSI {
VHostSCSICommon parent_obj;
uint64_t host_features;
+ VhostUserState *vhost_user;
} VHostUserSCSI;
#endif /* VHOST_USER_SCSI_H */
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
new file mode 100644
index 0000000000..fd660393a0
--- /dev/null
+++ b/include/hw/virtio/vhost-user.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017-2018 Intel Corporation
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_VIRTIO_VHOST_USER_H
+#define HW_VIRTIO_VHOST_USER_H
+
+#include "chardev/char-fe.h"
+#include "hw/virtio/virtio.h"
+
+typedef struct VhostUserHostNotifier {
+ MemoryRegion mr;
+ void *addr;
+ bool set;
+} VhostUserHostNotifier;
+
+typedef struct VhostUserState {
+ CharBackend *chr;
+ VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX];
+} VhostUserState;
+
+VhostUserState *vhost_user_init(void);
+void vhost_user_cleanup(VhostUserState *user);
+
+#endif
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index f65852fc24..3747110f95 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -27,7 +27,7 @@
#ifndef QEMU_VMSTATE_H
#define QEMU_VMSTATE_H
-#include "migration/qjson.h"
+typedef struct QJSON QJSON;
typedef struct VMStateInfo VMStateInfo;
typedef struct VMStateDescription VMStateDescription;
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 41658060a7..afc28e5903 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -108,6 +108,16 @@ extern int daemon(int, int);
#include "qemu/typedefs.h"
/*
+ * According to waitpid man page:
+ * WCOREDUMP
+ * This macro is not specified in POSIX.1-2001 and is not
+ * available on some UNIX implementations (e.g., AIX, SunOS).
+ * Therefore, enclose its use inside #ifdef WCOREDUMP ... #endif.
+ */
+#ifndef WCOREDUMP
+#define WCOREDUMP(status) 0
+#endif
+/*
* We have a lot of unaudited code that may fail in strange ways, or
* even be a security risk during migration, if you disable assertions
* at compile-time. You may comment out these safety checks if you
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 8819aabe3a..eeccaff34b 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -66,7 +66,7 @@
#include "qemu/error-report.h"
#include "migration/misc.h"
#include "migration/migration.h"
-#include "migration/qemu-file.h"
+#include "qemu-file.h"
#include "migration/vmstate.h"
#include "migration/register.h"
#include "qemu/hbitmap.h"
diff --git a/migration/page_cache.c b/migration/page_cache.c
index 96268c3aea..acc252b100 100644
--- a/migration/page_cache.c
+++ b/migration/page_cache.c
@@ -18,7 +18,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/host-utils.h"
-#include "migration/page_cache.h"
+#include "page_cache.h"
#ifdef DEBUG_CACHE
#define DPRINTF(fmt, ...) \
diff --git a/migration/ram.c b/migration/ram.c
index c53e8369a3..f4e29cadc6 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -41,7 +41,7 @@
#include "migration/misc.h"
#include "qemu-file.h"
#include "postcopy-ram.h"
-#include "migration/page_cache.h"
+#include "page_cache.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/qapi-events-migration.h"
@@ -51,7 +51,7 @@
#include "exec/target_page.h"
#include "qemu/rcu_queue.h"
#include "migration/colo.h"
-#include "migration/block.h"
+#include "block.h"
#include "sysemu/sysemu.h"
#include "qemu/uuid.h"
#include "savevm.h"
diff --git a/migration/savevm.c b/migration/savevm.c
index 4251125831..da724c52f2 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -55,6 +55,7 @@
#include "io/channel-buffer.h"
#include "io/channel-file.h"
#include "sysemu/replay.h"
+#include "qjson.h"
#ifndef ETH_P_RARP
#define ETH_P_RARP 0x8035
diff --git a/migration/vmstate.c b/migration/vmstate.c
index f0b07f4ea1..6b9079bb51 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -14,7 +14,7 @@
#include "qemu-common.h"
#include "migration.h"
#include "migration/vmstate.h"
-#include "migration/savevm.h"
+#include "savevm.h"
#include "qemu-file.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
diff --git a/net/colo-compare.c b/net/colo-compare.c
index 23b2d2c4cc..c3a2be4c90 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -25,7 +25,7 @@
#include "net/queue.h"
#include "chardev/char-fe.h"
#include "qemu/sockets.h"
-#include "net/colo.h"
+#include "colo.h"
#include "sysemu/iothread.h"
#define TYPE_COLO_COMPARE "colo-compare"
diff --git a/net/colo.c b/net/colo.c
index 842626502e..6dda4ed66e 100644
--- a/net/colo.c
+++ b/net/colo.c
@@ -14,7 +14,7 @@
#include "qemu/osdep.h"
#include "trace.h"
-#include "net/colo.h"
+#include "colo.h"
uint32_t connection_key_hash(const void *opaque)
{
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index 62dad2d773..f584e4eba4 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -11,7 +11,7 @@
#include "qemu/osdep.h"
#include "trace.h"
-#include "net/colo.h"
+#include "colo.h"
#include "net/filter.h"
#include "net/net.h"
#include "qemu-common.h"
diff --git a/net/vhost-user.c b/net/vhost-user.c
index fa28aad12d..608b837175 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -12,6 +12,7 @@
#include "clients.h"
#include "net/vhost_net.h"
#include "net/vhost-user.h"
+#include "hw/virtio/vhost-user.h"
#include "chardev/char-fe.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-net.h"
@@ -23,6 +24,7 @@
typedef struct NetVhostUserState {
NetClientState nc;
CharBackend chr; /* only queue index 0 */
+ VhostUserState *vhost_user;
VHostNetState *vhost_net;
guint watch;
uint64_t acked_features;
@@ -64,7 +66,8 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
}
}
-static int vhost_user_start(int queues, NetClientState *ncs[], CharBackend *be)
+static int vhost_user_start(int queues, NetClientState *ncs[],
+ VhostUserState *be)
{
VhostNetOptions options;
struct vhost_net *net = NULL;
@@ -144,7 +147,7 @@ static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
return size;
}
-static void vhost_user_cleanup(NetClientState *nc)
+static void net_vhost_user_cleanup(NetClientState *nc)
{
NetVhostUserState *s = DO_UPCAST(NetVhostUserState, nc, nc);
@@ -159,6 +162,11 @@ static void vhost_user_cleanup(NetClientState *nc)
s->watch = 0;
}
qemu_chr_fe_deinit(&s->chr, true);
+ if (s->vhost_user) {
+ vhost_user_cleanup(s->vhost_user);
+ g_free(s->vhost_user);
+ s->vhost_user = NULL;
+ }
}
qemu_purge_queued_packets(nc);
@@ -182,7 +190,7 @@ static NetClientInfo net_vhost_user_info = {
.type = NET_CLIENT_DRIVER_VHOST_USER,
.size = sizeof(NetVhostUserState),
.receive = vhost_user_receive,
- .cleanup = vhost_user_cleanup,
+ .cleanup = net_vhost_user_cleanup,
.has_vnet_hdr = vhost_user_has_vnet_hdr,
.has_ufo = vhost_user_has_ufo,
};
@@ -244,7 +252,7 @@ static void net_vhost_user_event(void *opaque, int event)
trace_vhost_user_event(chr->label, event);
switch (event) {
case CHR_EVENT_OPENED:
- if (vhost_user_start(queues, ncs, &s->chr) < 0) {
+ if (vhost_user_start(queues, ncs, s->vhost_user) < 0) {
qemu_chr_fe_disconnect(&s->chr);
return;
}
@@ -283,12 +291,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
{
Error *err = NULL;
NetClientState *nc, *nc0 = NULL;
- NetVhostUserState *s;
+ VhostUserState *user = NULL;
+ NetVhostUserState *s = NULL;
int i;
assert(name);
assert(queues > 0);
+ user = vhost_user_init();
+ if (!user) {
+ error_report("failed to init vhost_user");
+ goto err;
+ }
+
for (i = 0; i < queues; i++) {
nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
@@ -299,17 +314,19 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
s = DO_UPCAST(NetVhostUserState, nc, nc);
if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
error_report_err(err);
- return -1;
+ goto err;
}
+ user->chr = &s->chr;
}
-
+ s = DO_UPCAST(NetVhostUserState, nc, nc);
+ s->vhost_user = user;
}
s = DO_UPCAST(NetVhostUserState, nc, nc0);
do {
if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
error_report_err(err);
- return -1;
+ goto err;
}
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
net_vhost_user_event, NULL, nc0->name, NULL,
@@ -319,6 +336,17 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
assert(s->vhost_net);
return 0;
+
+err:
+ if (user) {
+ vhost_user_cleanup(user);
+ g_free(user);
+ if (s) {
+ s->vhost_user = NULL;
+ }
+ }
+
+ return -1;
}
static Chardev *net_vhost_claim_chardev(
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index b812bf4d51..5a925a9818 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -2,7 +2,7 @@
#include <termios.h>
#include "qapi/error.h"
#include "qemu/sockets.h"
-#include "qga/channel.h"
+#include "channel.h"
#ifdef CONFIG_SOLARIS
#include <stropts.h>
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 7e6dc4d26f..b3597a8a0f 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -1,8 +1,8 @@
#include "qemu/osdep.h"
#include <windows.h>
#include <io.h>
-#include "qga/guest-agent-core.h"
-#include "qga/channel.h"
+#include "guest-agent-core.h"
+#include "channel.h"
typedef struct GAChannelReadState {
guint thread_id;
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 0dc219dbcf..eae817191b 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -16,7 +16,7 @@
#include <sys/utsname.h>
#include <sys/wait.h>
#include <dirent.h>
-#include "qga/guest-agent-core.h"
+#include "guest-agent-core.h"
#include "qga-qapi-commands.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 2d48394748..70ee5379f6 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -32,8 +32,8 @@
#include <wtsapi32.h>
#include <wininet.h>
-#include "qga/guest-agent-core.h"
-#include "qga/vss-win32.h"
+#include "guest-agent-core.h"
+#include "vss-win32.h"
#include "qga-qapi-commands.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
diff --git a/qga/commands.c b/qga/commands.c
index a64b34ccab..cce3010f0f 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -11,7 +11,7 @@
*/
#include "qemu/osdep.h"
-#include "qga/guest-agent-core.h"
+#include "guest-agent-core.h"
#include "qga-qapi-commands.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
index e609d320f0..18bcb5941d 100644
--- a/qga/guest-agent-command-state.c
+++ b/qga/guest-agent-command-state.c
@@ -10,7 +10,7 @@
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
-#include "qga/guest-agent-core.h"
+#include "guest-agent-core.h"
struct GACommandState {
GSList *groups;
diff --git a/qga/main.c b/qga/main.c
index 1e1cec708f..ea7540edcc 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -23,12 +23,12 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qstring.h"
-#include "qga/guest-agent-core.h"
+#include "guest-agent-core.h"
#include "qemu/module.h"
#include "qga-qapi-commands.h"
#include "qapi/qmp/qerror.h"
#include "qapi/error.h"
-#include "qga/channel.h"
+#include "channel.h"
#include "qemu/bswap.h"
#include "qemu/help_option.h"
#include "qemu/sockets.h"
diff --git a/qga/vss-win32.c b/qga/vss-win32.c
index 0199c2a792..a541f3ae01 100644
--- a/qga/vss-win32.c
+++ b/qga/vss-win32.c
@@ -14,9 +14,9 @@
#include <windows.h>
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "qga/guest-agent-core.h"
-#include "qga/vss-win32.h"
-#include "qga/vss-win32/requester.h"
+#include "guest-agent-core.h"
+#include "vss-win32.h"
+#include "vss-win32/requester.h"
#define QGA_VSS_DLL "qga-vss.dll"
diff --git a/tests/.gitignore b/tests/.gitignore
index fb62d2299b..2bc61a9a58 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -21,6 +21,7 @@ test-base64
test-bdrv-drain
test-bitops
test-bitcnt
+test-block-backend
test-blockjob
test-blockjob-txn
test-bufferiszero
diff --git a/tests/acpi-test-data/pc/NFIT.dimmpxm b/tests/acpi-test-data/pc/NFIT.dimmpxm
index 2bfc6c51f3..598d331b75 100644
--- a/tests/acpi-test-data/pc/NFIT.dimmpxm
+++ b/tests/acpi-test-data/pc/NFIT.dimmpxm
Binary files differ
diff --git a/tests/acpi-test-data/q35/NFIT.dimmpxm b/tests/acpi-test-data/q35/NFIT.dimmpxm
index 2bfc6c51f3..598d331b75 100644
--- a/tests/acpi-test-data/q35/NFIT.dimmpxm
+++ b/tests/acpi-test-data/q35/NFIT.dimmpxm
Binary files differ
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index bf3e193ae9..256d463cb8 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -830,7 +830,7 @@ static void test_acpi_tcg_dimm_pxm(const char *machine)
memset(&data, 0, sizeof(data));
data.machine = machine;
data.variant = ".dimmpxm";
- test_acpi_one(" -machine nvdimm=on"
+ test_acpi_one(" -machine nvdimm=on,nvdimm-cap=3"
" -smp 4,sockets=4"
" -m 128M,slots=3,maxmem=1G"
" -numa node,mem=32M,nodeid=0"
diff --git a/tests/libqtest.c b/tests/libqtest.c
index e0ca19dbfe..098af6aec4 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -103,8 +103,15 @@ static int socket_accept(int sock)
static void kill_qemu(QTestState *s)
{
if (s->qemu_pid != -1) {
+ int wstatus = 0;
+ pid_t pid;
+
kill(s->qemu_pid, SIGTERM);
- waitpid(s->qemu_pid, NULL, 0);
+ pid = waitpid(s->qemu_pid, &wstatus, 0);
+
+ if (pid == s->qemu_pid && WIFSIGNALED(wstatus)) {
+ assert(!WCOREDUMP(wstatus));
+ }
}
}
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index e0605a529e..0884294141 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -29,6 +29,7 @@
#define _FILE_OFFSET_BITS 64
+#include "qemu/atomic.h"
#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "standard-headers/linux/virtio_net.h"
@@ -65,6 +66,11 @@ typedef struct VubrDev {
int sock;
int ready;
int quit;
+ struct {
+ int fd;
+ void *addr;
+ pthread_t thread;
+ } notifier;
} VubrDev;
static void
@@ -445,14 +451,22 @@ static uint64_t
vubr_get_features(VuDev *dev)
{
return 1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE |
- 1ULL << VIRTIO_NET_F_MRG_RXBUF;
+ 1ULL << VIRTIO_NET_F_MRG_RXBUF |
+ 1ULL << VIRTIO_F_VERSION_1;
}
static void
vubr_queue_set_started(VuDev *dev, int qidx, bool started)
{
+ VubrDev *vubr = container_of(dev, VubrDev, vudev);
VuVirtq *vq = vu_get_queue(dev, qidx);
+ if (started && vubr->notifier.fd >= 0) {
+ vu_set_queue_host_notifier(dev, vq, vubr->notifier.fd,
+ getpagesize(),
+ qidx * getpagesize());
+ }
+
if (qidx % 2 == 1) {
vu_set_queue_handler(dev, vq, started ? vubr_handle_tx : NULL);
}
@@ -522,6 +536,8 @@ vubr_new(const char *path, bool client)
vubr_die("socket");
}
+ dev->notifier.fd = -1;
+
un.sun_family = AF_UNIX;
strcpy(un.sun_path, path);
len = sizeof(un.sun_family) + strlen(path);
@@ -559,6 +575,73 @@ vubr_new(const char *path, bool client)
return dev;
}
+static void *notifier_thread(void *arg)
+{
+ VuDev *dev = (VuDev *)arg;
+ VubrDev *vubr = container_of(dev, VubrDev, vudev);
+ int pagesize = getpagesize();
+ int qidx;
+
+ while (true) {
+ for (qidx = 0; qidx < VHOST_MAX_NR_VIRTQUEUE; qidx++) {
+ uint16_t *n = vubr->notifier.addr + pagesize * qidx;
+
+ if (*n == qidx) {
+ *n = 0xffff;
+ /* We won't miss notifications if we reset
+ * the memory first. */
+ smp_mb();
+
+ DPRINT("Got a notification for queue%d via host notifier.\n",
+ qidx);
+
+ if (qidx % 2 == 1) {
+ vubr_handle_tx(dev, qidx);
+ }
+ }
+ usleep(1000);
+ }
+ }
+
+ return NULL;
+}
+
+static void
+vubr_host_notifier_setup(VubrDev *dev)
+{
+ char template[] = "/tmp/vubr-XXXXXX";
+ pthread_t thread;
+ size_t length;
+ void *addr;
+ int fd;
+
+ length = getpagesize() * VHOST_MAX_NR_VIRTQUEUE;
+
+ fd = mkstemp(template);
+ if (fd < 0) {
+ vubr_die("mkstemp()");
+ }
+
+ if (posix_fallocate(fd, 0, length) != 0) {
+ vubr_die("posix_fallocate()");
+ }
+
+ addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ vubr_die("mmap()");
+ }
+
+ memset(addr, 0xff, length);
+
+ if (pthread_create(&thread, NULL, notifier_thread, &dev->vudev) != 0) {
+ vubr_die("pthread_create()");
+ }
+
+ dev->notifier.fd = fd;
+ dev->notifier.addr = addr;
+ dev->notifier.thread = thread;
+}
+
static void
vubr_set_host(struct sockaddr_in *saddr, const char *host)
{
@@ -673,8 +756,9 @@ main(int argc, char *argv[])
VubrDev *dev;
int opt;
bool client = false;
+ bool host_notifier = false;
- while ((opt = getopt(argc, argv, "l:r:u:c")) != -1) {
+ while ((opt = getopt(argc, argv, "l:r:u:cH")) != -1) {
switch (opt) {
case 'l':
@@ -693,6 +777,9 @@ main(int argc, char *argv[])
case 'c':
client = true;
break;
+ case 'H':
+ host_notifier = true;
+ break;
default:
goto out;
}
@@ -708,6 +795,10 @@ main(int argc, char *argv[])
return 1;
}
+ if (host_notifier) {
+ vubr_host_notifier_setup(dev);
+ }
+
vubr_backend_udp_setup(dev, lhost, lport, rhost, rport);
vubr_run(dev);
@@ -717,7 +808,7 @@ main(int argc, char *argv[])
out:
fprintf(stderr, "Usage: %s ", argv[0]);
- fprintf(stderr, "[-c] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
+ fprintf(stderr, "[-c] [-H] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
DEFAULT_UD_SOCKET);
fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
@@ -725,6 +816,7 @@ out:
fprintf(stderr, "\t-r remote host and port. default: %s:%s\n",
DEFAULT_RHOST, DEFAULT_RPORT);
fprintf(stderr, "\t-c client mode\n");
+ fprintf(stderr, "\t-H use host notifier\n");
return 1;
}
diff --git a/trace/control.h b/trace/control.h
index 1903e22975..eb65c8e320 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -267,6 +267,6 @@ char *trace_opt_parse(const char *optarg);
uint32_t trace_get_vcpu_event_count(void);
-#include "trace/control-internal.h"
+#include "control-internal.h"
#endif /* TRACE__CONTROL_H */
diff --git a/trace/qmp.c b/trace/qmp.c
index 756086c79f..ea99b00956 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -10,7 +10,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-trace.h"
-#include "trace/control.h"
+#include "control.h"
static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
diff --git a/ui/gtk.c b/ui/gtk.c
index dbce970dc4..903f136b8f 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -66,7 +66,7 @@
#define VC_SCALE_STEP 0.25
#ifdef GDK_WINDOWING_X11
-#include "ui/x_keymap.h"
+#include "x_keymap.h"
/* Gtk2 compat */
#ifndef GDK_IS_X11_DISPLAY
diff --git a/ui/input-keymap.c b/ui/input-keymap.c
index 3d4e66bab5..87cc301b7a 100644
--- a/ui/input-keymap.c
+++ b/ui/input-keymap.c
@@ -1,6 +1,6 @@
#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
-#include "ui/keymaps.h"
+#include "keymaps.h"
#include "ui/input.h"
#include "standard-headers/linux/input.h"
diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index e5d4db1d97..549654e26a 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -26,7 +26,7 @@
#include "qapi/qapi-commands-ui.h"
#include "sysemu/sysemu.h"
#include "ui/console.h"
-#include "ui/keymaps.h"
+#include "keymaps.h"
#include "ui/input.h"
struct QEMUPutMouseEntry {
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 3d41aa1831..a426c03b5e 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -23,7 +23,7 @@
#include "qemu-common.h"
#include "ui/qemu-spice.h"
#include "ui/console.h"
-#include "ui/keymaps.h"
+#include "keymaps.h"
#include "ui/input.h"
/* keyboard bits */