From 988a27754bbbc45698f7acb54352e5a1ae699514 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:31 +0800 Subject: [PATCH 01/31] vhost: allow backends to filter memory sections This patch introduces a vhost op for vhost backends to allow them to filter the memory sections that they can handle. Signed-off-by: Tiwei Bie Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-user.c | 11 +++++++++++ hw/virtio/vhost.c | 9 +++++++-- include/hw/virtio/vhost-backend.h | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index ca554d4ff1..da0756effe 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -1620,6 +1620,16 @@ 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; +} + const VhostOps user_ops = { .backend_type = VHOST_BACKEND_TYPE_USER, .vhost_backend_init = vhost_user_init, @@ -1650,4 +1660,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 b08290036d..624ade9682 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/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; From 5f57fbeaaf7c4cd33152d7f2e449caab4d4209d9 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:32 +0800 Subject: [PATCH 02/31] vhost-user: allow slave to send fds via slave channel Introduce VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature to allow slave to send at most 8 descriptors in each message to master via ancillary data using the slave channel. Suggested-by: Michael S. Tsirkin Signed-off-by: Tiwei Bie Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/interop/vhost-user.txt | 5 +++++ hw/virtio/vhost-user.c | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index 534caab18a..682a683eb4 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -367,6 +367,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 +384,7 @@ 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 Master message types -------------------- diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index da0756effe..75a3faef2a 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -30,6 +30,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 +48,7 @@ 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_MAX }; @@ -854,10 +856,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 +867,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 +889,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; } } @@ -913,14 +917,15 @@ static void slave_read(void *opaque) 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 +959,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; } From 4d0cf552d3a9585f380e8abdc313e4d416a56aa0 Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:33 +0800 Subject: [PATCH 03/31] vhost-user: introduce shared vhost-user state When multi queue is enabled e.g. for a virtio-net device, each queue pair will have a vhost_dev, and the only thing shared between vhost devs currently is the chardev. This patch introduces a vhost-user state structure which will be shared by all vhost devs of the same virtio device. Signed-off-by: Tiwei Bie Signed-off-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- backends/cryptodev-vhost-user.c | 20 ++++++++++++- hw/block/vhost-user-blk.c | 22 ++++++++++++++- hw/scsi/vhost-user-scsi.c | 20 ++++++++++++- hw/virtio/Makefile.objs | 2 +- hw/virtio/vhost-stub.c | 10 +++++++ hw/virtio/vhost-user.c | 31 ++++++++++++++------ include/hw/virtio/vhost-user-blk.h | 2 ++ include/hw/virtio/vhost-user-scsi.h | 2 ++ include/hw/virtio/vhost-user.h | 20 +++++++++++++ net/vhost-user.c | 44 +++++++++++++++++++++++------ 10 files changed, 152 insertions(+), 21 deletions(-) create mode 100644 include/hw/virtio/vhost-user.h 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/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 975eae6211..7c3fa8bb1c 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -226,6 +226,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 +244,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 +268,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 +293,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 +308,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) 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/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 765d363c1f..030969e28c 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -11,5 +11,5 @@ obj-y += virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) += virtio-crypto-pci.o endif -common-obj-$(call lnot,$(CONFIG_LINUX)) += vhost-stub.o +common-obj-$(call lnot,$(call land,$(CONFIG_VIRTIO),$(CONFIG_LINUX))) += vhost-stub.o common-obj-$(CONFIG_ALL) += vhost-stub.o 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 75a3faef2a..70b9610c87 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -11,6 +11,7 @@ #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-net.h" #include "chardev/char-fe.h" @@ -175,7 +176,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; @@ -201,7 +203,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; @@ -287,7 +289,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; /* @@ -1090,7 +1092,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, @@ -1228,7 +1230,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; @@ -1237,7 +1239,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; @@ -1313,7 +1315,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; @@ -1637,10 +1639,21 @@ static bool vhost_user_mem_section_filter(struct vhost_dev *dev, return result; } +VhostUserState *vhost_user_init(void) +{ + VhostUserState *user = g_new0(struct VhostUserState, 1); + + return user; +} + +void vhost_user_cleanup(VhostUserState *user) +{ +} + 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, diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h index 5804cc904a..f1258ae545 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) \ @@ -36,6 +37,7 @@ typedef struct VHostUserBlk { 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..eb8bc0d90d --- /dev/null +++ b/include/hw/virtio/vhost-user.h @@ -0,0 +1,20 @@ +/* + * 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" + +typedef struct VhostUserState { + CharBackend *chr; +} VhostUserState; + +VhostUserState *vhost_user_init(void); +void vhost_user_cleanup(VhostUserState *user); + +#endif 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( From 44866521bd6ea8e5152a87664dea1eee90c9438b Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:34 +0800 Subject: [PATCH 04/31] vhost-user: support registering external host notifiers This patch introduces VHOST_USER_PROTOCOL_F_HOST_NOTIFIER. With this feature negotiated, vhost-user backend can register memory region based host notifiers. And it will allow the guest driver in the VM to notify the hardware accelerator at the vhost-user backend directly. Signed-off-by: Tiwei Bie Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/interop/vhost-user.txt | 33 ++++++++++ hw/virtio/vhost-user.c | 113 +++++++++++++++++++++++++++++++++ include/hw/virtio/vhost-user.h | 8 +++ 3 files changed, 154 insertions(+) diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index 682a683eb4..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; @@ -385,6 +396,7 @@ Protocol features #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 -------------------- @@ -782,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/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 70b9610c87..b041343632 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -13,6 +13,7 @@ #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" @@ -50,6 +51,7 @@ enum VhostUserProtocolFeature { 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 }; @@ -94,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; @@ -138,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; @@ -159,6 +168,7 @@ typedef union { struct vhost_iotlb_msg iotlb; VhostUserConfig config; VhostUserCryptoSession session; + VhostUserVringArea area; } VhostUserPayload; typedef struct VhostUserMsg { @@ -640,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); } @@ -676,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; } @@ -849,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; @@ -917,6 +1017,10 @@ 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."); ret = -EINVAL; @@ -1648,6 +1752,15 @@ VhostUserState *vhost_user_init(void) 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 = { diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index eb8bc0d90d..fd660393a0 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -9,9 +9,17 @@ #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); From d84599f56c820d8c1ac9928a76500dcdfbbf194d Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:35 +0800 Subject: [PATCH 05/31] libvhost-user: support host notifier This patch introduces the host notifier support in libvhost-user. A new API is added to support setting host notifier for each queue. Signed-off-by: Tiwei Bie Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- contrib/libvhost-user/libvhost-user.c | 81 ++++++++++++++++++++++++--- contrib/libvhost-user/libvhost-user.h | 32 +++++++++++ 2 files changed, 105 insertions(+), 8 deletions(-) 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: From e3af2928f8270498097af163bb023b633c0d8d1c Mon Sep 17 00:00:00 2001 From: Tiwei Bie Date: Thu, 24 May 2018 18:33:36 +0800 Subject: [PATCH 06/31] vhost-user-bridge: support host notifier This patch introduces the host notifier support in vhost-user-bridge. A new option (-H) is added to use the host notifier. This is mainly used to test the host notifier implementation in vhost user. Signed-off-by: Tiwei Bie Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/vhost-user-bridge.c | 98 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) 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; } From 28012e190e6897cfc2a98364240909d08e90ffc0 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 May 2018 21:09:52 +0300 Subject: [PATCH 07/31] osdep: add wait.h compat macros Man page for WCOREDUMP says: WCOREDUMP(wstatus) returns true if the child produced a core dump. This macro should be employed only if WIFSIGNALED returned true. 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. Let's do exactly this. Signed-off-by: Michael S. Tsirkin --- include/qemu/osdep.h | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 @@ -107,6 +107,16 @@ extern int daemon(int, int); #include "glib-compat.h" #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 From fa0d421f39b353ed2de901bb798f81ce9824c2f3 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 24 May 2018 17:24:35 +0300 Subject: [PATCH 08/31] libqtest: fail if child coredumps Right now tests report OK status if QEMU crashes during cleanup. Let's catch that case and fail the test. Signed-off-by: Michael S. Tsirkin Acked-by: Thomas Huth --- tests/libqtest.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/libqtest.c b/tests/libqtest.c index 43fb97e035..f869854849 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)); + } } } From 0d8c41dae5b0566d0022be2af84d50ff456b3537 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:20 +0300 Subject: [PATCH 09/31] block: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- block/crypto.c | 2 +- block/nbd.c | 2 +- block/qcow.c | 2 +- block/qcow2-bitmap.c | 2 +- block/qcow2-cluster.c | 2 +- block/qcow2-refcount.c | 2 +- block/qcow2-snapshot.c | 2 +- block/qcow2.c | 4 ++-- block/vhdx-endian.c | 2 +- block/vhdx-log.c | 2 +- block/vhdx.c | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) 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 6d532470a8..db13109744 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -27,7 +27,7 @@ #include "sysemu/block-backend.h" #include "qemu/module.h" #include -#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 0b1e21c750..79c68a2061 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" From 986bc8ded9a5459e72951cc91b53cf2b52eb735f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:23 +0300 Subject: [PATCH 10/31] crypto: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Acked-by: Daniel P. Berrangé --- crypto/block-luks.c | 2 +- crypto/block-luks.h | 2 +- crypto/block-qcow.c | 2 +- crypto/block-qcow.h | 2 +- crypto/block.c | 6 +++--- crypto/cipher.c | 6 +++--- crypto/ivgen-essiv.c | 2 +- crypto/ivgen-essiv.h | 2 +- crypto/ivgen-plain.c | 2 +- crypto/ivgen-plain.h | 2 +- crypto/ivgen-plain64.c | 2 +- crypto/ivgen-plain64.h | 2 +- crypto/ivgen.c | 8 ++++---- crypto/tlscreds.c | 2 +- crypto/tlscredsanon.c | 2 +- crypto/tlscredsx509.c | 2 +- 16 files changed, 23 insertions(+), 23 deletions(-) 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" From 070e9a1e837e1a2ba5c6450eb8ce2e18b29c4af8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:25 +0300 Subject: [PATCH 11/31] hppa: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/hppa/hppa_sys.h | 2 +- hw/hppa/machine.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h index a182d1f34e..f98cc8daad 100644 --- a/hw/hppa/hppa_sys.h +++ b/hw/hppa/hppa_sys.h @@ -10,7 +10,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" From 83ee768d6247bf121b5b8f4b7580fbbc1281d473 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:27 +0300 Subject: [PATCH 12/31] migration: drop an unused include In the vmstate.h file, we just need a struct name. Use a forward declaration instead of an include, then adjust the one affected .c file to include the file that is no longer implicit from the header. Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake --- include/migration/vmstate.h | 2 +- migration/savevm.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index df463fd33d..5877caed90 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/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 From a322714248b9e8dffe6a2bb379ffd5d59b394bb7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:28 +0300 Subject: [PATCH 13/31] trace: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Stefan Hajnoczi Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- trace/control.h | 2 +- trace/qmp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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) From e921d6eff9b7fc0260a69bd286b2b134890ef03a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:31 +0300 Subject: [PATCH 14/31] display: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/display/bcm2835_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" From 9314b859bb1065ef9ee1ad2a863aa30f2aa93178 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:31 +0300 Subject: [PATCH 15/31] ide: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/ide/ahci-allwinner.c | 2 +- hw/ide/ahci.c | 2 +- hw/ide/ich.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 From 455e17a1b85fbc3d8c7208b5bc9a742d8508b324 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:32 +0300 Subject: [PATCH 16/31] ioapic: fix up includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include files shouldn't have the "include/" part, that is implied. Also, drop an unused include. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/intc/ioapic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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" From e703a5a1e043ad78f9370b1f91825625da4383ed Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:33 +0300 Subject: [PATCH 17/31] e1000e: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/net/e1000e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" From 4147a0358e214551a71c108b4474a5c58835abbb Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:34 +0300 Subject: [PATCH 18/31] rocker: drop an unused include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't use net/clients.h, drop that include. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/net/rocker/rocker_fp.c | 1 - 1 file changed, 1 deletion(-) 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" From 72a56a1f797c67015bff20d4b77fbf4f6d5b9440 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:35 +0300 Subject: [PATCH 19/31] ppc: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Acked-by: David Gibson Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/ppc/ppc440_uc.c | 2 +- hw/ppc/sam460ex.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 a48e6e6fce..cb2ab1d1e4 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -27,8 +27,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" From dbff516dc96c9e4c3ca1ac1826377af88c7b7f1d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:37 +0300 Subject: [PATCH 20/31] vhost-scsi: drop an unused include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No reason for vhost-scsi to pull in migration headers directly. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/scsi/vhost-scsi-common.c | 1 - 1 file changed, 1 deletion(-) 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" From 222ee196abe316ad21be8629b8be8e60bc3e8c4b Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:46 +0300 Subject: [PATCH 21/31] sd: fix up include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include files shouldn't have the "include/" part, that is implied. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/sd/milkymist-memcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" From 463581a827ea8fd540ddf1d4260a7610d17f1b2e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:48 +0300 Subject: [PATCH 22/31] usb: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/usb/desc-msos.c | 2 +- hw/usb/desc.c | 2 +- hw/usb/dev-audio.c | 2 +- hw/usb/dev-bluetooth.c | 2 +- hw/usb/dev-hid.c | 2 +- hw/usb/dev-hub.c | 2 +- hw/usb/dev-mtp.c | 2 +- hw/usb/dev-network.c | 2 +- hw/usb/dev-serial.c | 2 +- hw/usb/dev-smartcard-reader.c | 2 +- hw/usb/dev-storage.c | 2 +- hw/usb/dev-uas.c | 2 +- hw/usb/dev-wacom.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) 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 b56c75a73a..f2f632aeb0 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 From 53d37d36caa046d7d93f365e56dcf664f47ccf31 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:51 +0300 Subject: [PATCH 23/31] migration: use local path for local headers When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Juan Quintela --- migration/block-dirty-bitmap.c | 2 +- migration/page_cache.c | 2 +- migration/ram.c | 4 ++-- migration/vmstate.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) 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 5bcbf7a9f9..e7d6cf6492 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/vmstate.c b/migration/vmstate.c index 0b3282c9df..0a096360e2 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" From f27f01db0391990098620cd39473edf03e170183 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:56 +0300 Subject: [PATCH 24/31] colo: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Reviewed-by: Zhang Chen Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- net/colo-compare.c | 2 +- net/colo.c | 2 +- net/filter-rewriter.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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" From dc03272da6d234a02b8caf938242d26584489e27 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:50:57 +0300 Subject: [PATCH 25/31] qga: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé --- qga/channel-posix.c | 2 +- qga/channel-win32.c | 4 ++-- qga/commands-posix.c | 2 +- qga/commands-win32.c | 4 ++-- qga/commands.c | 2 +- qga/guest-agent-command-state.c | 2 +- qga/main.c | 4 ++-- qga/vss-win32.c | 6 +++--- 8 files changed, 13 insertions(+), 13 deletions(-) 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 #include "qapi/error.h" #include "qemu/sockets.h" -#include "qga/channel.h" +#include "channel.h" #ifdef CONFIG_SOLARIS #include 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 #include -#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 #include #include -#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 #include -#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 #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" From 0041e9a0ac7f140256351a50b218f479981f06b2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:51:00 +0300 Subject: [PATCH 26/31] ui: use local path for local headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pulling in headers that are in the same directory as the C file (as opposed to one in include/), we should use its relative path, without a directory. Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé --- ui/gtk.c | 2 +- ui/input-keymap.c | 2 +- ui/input-legacy.c | 2 +- ui/spice-input.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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 */ From d35ea39e8db126b5f41b3f5c8aa6edf8bc3ded7d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 3 May 2018 22:51:03 +0300 Subject: [PATCH 27/31] arch_init: sort architectures Sort alphabetically. Will help us see if anything is missing (e.g. tile is not there now). Signed-off-by: Michael S. Tsirkin Reviewed-by: Laszlo Ersek --- arch_init.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 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; From 2e0c56cdde0b4bbd6ed4070626ed72d1977da07f Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Mon, 21 May 2018 10:32:01 -0600 Subject: [PATCH 28/31] tests/.gitignore: add entry for generated file After a "make check" we end up with the following: $ git status On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add ..." to include in what will be committed) tests/test-block-backend nothing added to commit but untracked files present (use "git add" to track) Signed-off-by: Ross Zwisler Fixes: commit ad0df3e0fdac ("block: test blk_aio_flush() with blk->root == NULL") Cc: Kevin Wolf Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake --- tests/.gitignore | 1 + 1 file changed, 1 insertion(+) 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 From 9ab3aad2813ce5d9e79c86cb65a013016b61a08f Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Mon, 21 May 2018 10:32:02 -0600 Subject: [PATCH 29/31] nvdimm, acpi: support NFIT platform capabilities Add a machine command line option to allow the user to control the Platform Capabilities Structure in the virtualized NFIT. This Platform Capabilities Structure was added in ACPI 6.2 Errata A. Signed-off-by: Ross Zwisler Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/nvdimm.txt | 27 +++++++++++++++++++++++++ hw/acpi/nvdimm.c | 45 +++++++++++++++++++++++++++++++++++++---- hw/i386/pc.c | 31 ++++++++++++++++++++++++++++ include/hw/i386/pc.h | 1 + include/hw/mem/nvdimm.h | 5 +++++ 5 files changed, 105 insertions(+), 4 deletions(-) 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 @@ -169,6 +169,21 @@ struct NvdimmNfitControlRegion { } QEMU_PACKED; 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 @@ -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/i386/pc.c b/hw/i386/pc.c index d768930d02..1b2684c549 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2182,6 +2182,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); @@ -2395,6 +2422,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/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; From cab27afa10c241cb99df41f770b29cebd6a91e73 Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Mon, 21 May 2018 10:32:03 -0600 Subject: [PATCH 30/31] ACPI testing: test NFIT platform capabilities Add testing for the newly added NFIT Platform Capabilities Structure. Signed-off-by: Ross Zwisler Suggested-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/NFIT.dimmpxm | Bin 224 -> 240 bytes tests/acpi-test-data/q35/NFIT.dimmpxm | Bin 224 -> 240 bytes tests/bios-tables-test.c | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acpi-test-data/pc/NFIT.dimmpxm b/tests/acpi-test-data/pc/NFIT.dimmpxm index 2bfc6c51f31c25a052803c494c933d4948fc0106..598d331b751cd3cb2137d431c1f34bb8957a0d31 100644 GIT binary patch delta 35 lcmaFB_<@nj&&@OB0|NsCqsm0CYXa;H0t}2m9y1Vw005dH1-}3Q delta 18 Zcmeys_<)hi&&@OB0RsaAqyI#%YXCU~1+M@A diff --git a/tests/acpi-test-data/q35/NFIT.dimmpxm b/tests/acpi-test-data/q35/NFIT.dimmpxm index 2bfc6c51f31c25a052803c494c933d4948fc0106..598d331b751cd3cb2137d431c1f34bb8957a0d31 100644 GIT binary patch delta 35 lcmaFB_<@nj&&@OB0|NsCqsm0CYXa;H0t}2m9y1Vw005dH1-}3Q delta 18 Zcmeys_<)hi&&@OB0RsaAqyI#%YXCU~1+M@A 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" From 25b1d45a1975fd8624c37b5bf42e8502ccf53460 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 29 May 2018 09:24:35 +0800 Subject: [PATCH 31/31] vhost-blk: turn on pre-defined RO feature bit Read only feature shouldn't be negotiable, because if the backend device reported Read only feature supported, QEMU host driver shouldn't change backend's RO attribute. While here, also enable the vhost-user-blk test utility to test RO feature. Signed-off-by: Changpeng Liu Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- contrib/vhost-user-blk/vhost-user-blk.c | 48 ++++++++++++++++++------- hw/block/vhost-user-blk.c | 5 +-- include/hw/virtio/vhost-user-blk.h | 1 - 3 files changed, 36 insertions(+), 18 deletions(-) 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/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 7c3fa8bb1c..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); } @@ -339,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/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h index f1258ae545..d52944aeeb 100644 --- a/include/hw/virtio/vhost-user-blk.h +++ b/include/hw/virtio/vhost-user-blk.h @@ -35,7 +35,6 @@ 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;