From 910b25766b336a94d69f5f6e1b55c10b3aeb4326 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 26 Jun 2020 09:22:37 +0200 Subject: virtio-mem: Paravirtualized memory hot(un)plug This is the very basic/initial version of virtio-mem. An introduction to virtio-mem can be found in the Linux kernel driver [1]. While it can be used in the current state for hotplug of a smaller amount of memory, it will heavily benefit from resizeable memory regions in the future. Each virtio-mem device manages a memory region (provided via a memory backend). After requested by the hypervisor ("requested-size"), the guest can try to plug/unplug blocks of memory within that region, in order to reach the requested size. Initially, and after a reboot, all memory is unplugged (except in special cases - reboot during postcopy). The guest may only try to plug/unplug blocks of memory within the usable region size. The usable region size is a little bigger than the requested size, to give the device driver some flexibility. The usable region size will only grow, except on reboots or when all memory is requested to get unplugged. The guest can never plug more memory than requested. Unplugged memory will get zapped/discarded, similar to in a balloon device. The block size is variable, however, it is always chosen in a way such that THP splits are avoided (e.g., 2MB). The state of each block (plugged/unplugged) is tracked in a bitmap. As virtio-mem devices (e.g., virtio-mem-pci) will be memory devices, we now expose "VirtioMEMDeviceInfo" via "query-memory-devices". -------------------------------------------------------------------------- There are two important follow-up items that are in the works: 1. Resizeable memory regions: Use resizeable allocations/RAM blocks to grow/shrink along with the usable region size. This avoids creating initially very big VMAs, RAM blocks, and KVM slots. 2. Protection of unplugged memory: Make sure the gust cannot actually make use of unplugged memory. Other follow-up items that are in the works: 1. Exclude unplugged memory during migration (via precopy notifier). 2. Handle remapping of memory. 3. Support for other architectures. -------------------------------------------------------------------------- Example usage (virtio-mem-pci is introduced in follow-up patches): Start QEMU with two virtio-mem devices (one per NUMA node): $ qemu-system-x86_64 -m 4G,maxmem=20G \ -smp sockets=2,cores=2 \ -numa node,nodeid=0,cpus=0-1 -numa node,nodeid=1,cpus=2-3 \ [...] -object memory-backend-ram,id=mem0,size=8G \ -device virtio-mem-pci,id=vm0,memdev=mem0,node=0,requested-size=0M \ -object memory-backend-ram,id=mem1,size=8G \ -device virtio-mem-pci,id=vm1,memdev=mem1,node=1,requested-size=1G Query the configuration: (qemu) info memory-devices Memory device [virtio-mem]: "vm0" memaddr: 0x140000000 node: 0 requested-size: 0 size: 0 max-size: 8589934592 block-size: 2097152 memdev: /objects/mem0 Memory device [virtio-mem]: "vm1" memaddr: 0x340000000 node: 1 requested-size: 1073741824 size: 1073741824 max-size: 8589934592 block-size: 2097152 memdev: /objects/mem1 Add some memory to node 0: (qemu) qom-set vm0 requested-size 500M Remove some memory from node 1: (qemu) qom-set vm1 requested-size 200M Query the configuration again: (qemu) info memory-devices Memory device [virtio-mem]: "vm0" memaddr: 0x140000000 node: 0 requested-size: 524288000 size: 524288000 max-size: 8589934592 block-size: 2097152 memdev: /objects/mem0 Memory device [virtio-mem]: "vm1" memaddr: 0x340000000 node: 1 requested-size: 209715200 size: 209715200 max-size: 8589934592 block-size: 2097152 memdev: /objects/mem1 [1] https://lkml.kernel.org/r/20200311171422.10484-1-david@redhat.com Cc: "Michael S. Tsirkin" Cc: Eric Blake Cc: Markus Armbruster Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand Message-Id: <20200626072248.78761-11-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- qapi/misc.json | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'qapi') diff --git a/qapi/misc.json b/qapi/misc.json index a5a0beb902..65ca3edf32 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1356,19 +1356,56 @@ } } +## +# @VirtioMEMDeviceInfo: +# +# VirtioMEMDevice state information +# +# @id: device's ID +# +# @memaddr: physical address in memory, where device is mapped +# +# @requested-size: the user requested size of the device +# +# @size: the (current) size of memory that the device provides +# +# @max-size: the maximum size of memory that the device can provide +# +# @block-size: the block size of memory that the device provides +# +# @node: NUMA node number where device is assigned to +# +# @memdev: memory backend linked with the region +# +# Since: 5.1 +## +{ 'struct': 'VirtioMEMDeviceInfo', + 'data': { '*id': 'str', + 'memaddr': 'size', + 'requested-size': 'size', + 'size': 'size', + 'max-size': 'size', + 'block-size': 'size', + 'node': 'int', + 'memdev': 'str' + } +} + ## # @MemoryDeviceInfo: # # Union containing information about a memory device # # nvdimm is included since 2.12. virtio-pmem is included since 4.1. +# virtio-mem is included since 5.1. # # Since: 2.1 ## { 'union': 'MemoryDeviceInfo', 'data': { 'dimm': 'PCDIMMDeviceInfo', 'nvdimm': 'PCDIMMDeviceInfo', - 'virtio-pmem': 'VirtioPMEMDeviceInfo' + 'virtio-pmem': 'VirtioPMEMDeviceInfo', + 'virtio-mem': 'VirtioMEMDeviceInfo' } } -- cgit v1.2.3-55-g7522 From 722a3c783ef4159b297d86e3c1f345360fb2a362 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 26 Jun 2020 09:22:44 +0200 Subject: virtio-pci: Send qapi events when the virtio-mem size changes Let's register the notifier and trigger the qapi event with the right device id. MEMORY_DEVICE_SIZE_CHANGE is similar to BALLOON_CHANGE, however on a memory device level. Don't unregister the notifier (we neither have finalize() nor unrealize() for VirtIOPCIProxy, so it's not that simple to do it) - both devices are expected to vanish at the same time. Cc: "Michael S. Tsirkin" Cc: Markus Armbruster Cc: "Dr. David Alan Gilbert" Cc: Eric Blake Cc: Igor Mammedov Signed-off-by: David Hildenbrand Message-Id: <20200626072248.78761-18-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-mem-pci.c | 28 ++++++++++++++++++++++++++++ hw/virtio/virtio-mem-pci.h | 1 + monitor/monitor.c | 1 + qapi/misc.json | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+) (limited to 'qapi') diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c index b325303b32..1a8e854123 100644 --- a/hw/virtio/virtio-mem-pci.c +++ b/hw/virtio/virtio-mem-pci.c @@ -14,6 +14,7 @@ #include "virtio-mem-pci.h" #include "hw/mem/memory-device.h" #include "qapi/error.h" +#include "qapi/qapi-events-misc.h" static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { @@ -74,6 +75,21 @@ static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md, info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM; } +static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data) +{ + VirtIOMEMPCI *pci_mem = container_of(notifier, VirtIOMEMPCI, + size_change_notifier); + DeviceState *dev = DEVICE(pci_mem); + const uint64_t * const size_p = data; + const char *id = NULL; + + if (dev->id) { + id = g_strdup(dev->id); + } + + qapi_event_send_memory_device_size_change(!!id, id, *size_p); +} + static void virtio_mem_pci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -98,9 +114,21 @@ static void virtio_mem_pci_class_init(ObjectClass *klass, void *data) static void virtio_mem_pci_instance_init(Object *obj) { VirtIOMEMPCI *dev = VIRTIO_MEM_PCI(obj); + VirtIOMEMClass *vmc; + VirtIOMEM *vmem; virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_MEM); + + dev->size_change_notifier.notify = virtio_mem_pci_size_change_notify; + vmem = VIRTIO_MEM(&dev->vdev); + vmc = VIRTIO_MEM_GET_CLASS(vmem); + /* + * We never remove the notifier again, as we expect both devices to + * disappear at the same time. + */ + vmc->add_size_change_notifier(vmem, &dev->size_change_notifier); + object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP); object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev), diff --git a/hw/virtio/virtio-mem-pci.h b/hw/virtio/virtio-mem-pci.h index 8820cd6628..b51a28b275 100644 --- a/hw/virtio/virtio-mem-pci.h +++ b/hw/virtio/virtio-mem-pci.h @@ -28,6 +28,7 @@ typedef struct VirtIOMEMPCI VirtIOMEMPCI; struct VirtIOMEMPCI { VirtIOPCIProxy parent_obj; VirtIOMEM vdev; + Notifier size_change_notifier; }; #endif /* QEMU_VIRTIO_MEM_PCI_H */ diff --git a/monitor/monitor.c b/monitor/monitor.c index 125494410a..19dcb8fbe3 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -235,6 +235,7 @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS }, [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, + [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS }, }; /* diff --git a/qapi/misc.json b/qapi/misc.json index 65ca3edf32..149c925246 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1434,6 +1434,31 @@ ## { 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] } +## +# @MEMORY_DEVICE_SIZE_CHANGE: +# +# Emitted when the size of a memory device changes. Only emitted for memory +# devices that can actually change the size (e.g., virtio-mem due to guest +# action). +# +# @id: device's ID +# @size: the new size of memory that the device provides +# +# Note: this event is rate-limited. +# +# Since: 5.1 +# +# Example: +# +# <- { "event": "MEMORY_DEVICE_SIZE_CHANGE", +# "data": { "id": "vm0", "size": 1073741824}, +# "timestamp": { "seconds": 1588168529, "microseconds": 201316 } } +# +## +{ 'event': 'MEMORY_DEVICE_SIZE_CHANGE', + 'data': { '*id': 'str', 'size': 'size' } } + + ## # @MEM_UNPLUG_ERROR: # -- cgit v1.2.3-55-g7522 From 1e0a84ea49b68b7cf60e229d91fd16333e0b7a90 Mon Sep 17 00:00:00 2001 From: Cindy Lu Date: Wed, 1 Jul 2020 22:55:38 +0800 Subject: vhost-vdpa: introduce vhost-vdpa net client This patch set introduces a new net client type: vhost-vdpa. vhost-vdpa net client will set up a vDPA device which is specified by a "vhostdev" parameter. Signed-off-by: Lingshan Zhu Signed-off-by: Tiwei Bie Signed-off-by: Cindy Lu Signed-off-by: Jason Wang Message-Id: <20200701145538.22333-15-lulu@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- include/net/vhost-vdpa.h | 22 +++++ net/Makefile.objs | 2 +- net/clients.h | 2 + net/net.c | 3 + net/vhost-vdpa.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++ qapi/net.json | 28 +++++- 6 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 include/net/vhost-vdpa.h create mode 100644 net/vhost-vdpa.c (limited to 'qapi') diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h new file mode 100644 index 0000000000..45e34b7cfc --- /dev/null +++ b/include/net/vhost-vdpa.h @@ -0,0 +1,22 @@ +/* + * vhost-vdpa.h + * + * Copyright(c) 2017-2018 Intel Corporation. + * Copyright(c) 2020 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef VHOST_VDPA_H +#define VHOST_VDPA_H + +#define TYPE_VHOST_VDPA "vhost-vdpa" + +struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc); +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc); + +extern const int vdpa_feature_bits[]; + +#endif /* VHOST_VDPA_H */ diff --git a/net/Makefile.objs b/net/Makefile.objs index c5d076d19c..5ab45545db 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -26,7 +26,7 @@ tap-obj-$(CONFIG_SOLARIS) = tap-solaris.o tap-obj-y ?= tap-stub.o common-obj-$(CONFIG_POSIX) += tap.o $(tap-obj-y) common-obj-$(CONFIG_WIN32) += tap-win32.o - +common-obj-$(CONFIG_VHOST_NET_VDPA) += vhost-vdpa.o vde.o-libs = $(VDE_LIBS) common-obj-$(CONFIG_CAN_BUS) += can/ diff --git a/net/clients.h b/net/clients.h index a6ef267e19..92f9b59aed 100644 --- a/net/clients.h +++ b/net/clients.h @@ -61,4 +61,6 @@ int net_init_netmap(const Netdev *netdev, const char *name, int net_init_vhost_user(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); #endif /* QEMU_NET_CLIENTS_H */ diff --git a/net/net.c b/net/net.c index 9099a327dd..94dc546fb2 100644 --- a/net/net.c +++ b/net/net.c @@ -966,6 +966,9 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( #ifdef CONFIG_VHOST_NET_USER [NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user, #endif +#ifdef CONFIG_VHOST_NET_VDPA + [NET_CLIENT_DRIVER_VHOST_VDPA] = net_init_vhost_vdpa, +#endif #ifdef CONFIG_L2TPV3 [NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3, #endif diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c new file mode 100644 index 0000000000..bc0e0d2d35 --- /dev/null +++ b/net/vhost-vdpa.c @@ -0,0 +1,228 @@ +/* + * vhost-vdpa.c + * + * Copyright(c) 2017-2018 Intel Corporation. + * Copyright(c) 2020 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "clients.h" +#include "net/vhost_net.h" +#include "net/vhost-vdpa.h" +#include "hw/virtio/vhost-vdpa.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qapi/error.h" +#include +#include +#include "standard-headers/linux/virtio_net.h" +#include "monitor/monitor.h" +#include "hw/virtio/vhost.h" + +/* Todo:need to add the multiqueue support here */ +typedef struct VhostVDPAState { + NetClientState nc; + struct vhost_vdpa vhost_vdpa; + VHostNetState *vhost_net; + uint64_t acked_features; + bool started; +} VhostVDPAState; + +const int vdpa_feature_bits[] = { + VIRTIO_F_NOTIFY_ON_EMPTY, + VIRTIO_RING_F_INDIRECT_DESC, + VIRTIO_RING_F_EVENT_IDX, + VIRTIO_F_ANY_LAYOUT, + VIRTIO_F_VERSION_1, + VIRTIO_NET_F_CSUM, + VIRTIO_NET_F_GUEST_CSUM, + VIRTIO_NET_F_GSO, + VIRTIO_NET_F_GUEST_TSO4, + VIRTIO_NET_F_GUEST_TSO6, + VIRTIO_NET_F_GUEST_ECN, + VIRTIO_NET_F_GUEST_UFO, + VIRTIO_NET_F_HOST_TSO4, + VIRTIO_NET_F_HOST_TSO6, + VIRTIO_NET_F_HOST_ECN, + VIRTIO_NET_F_HOST_UFO, + VIRTIO_NET_F_MRG_RXBUF, + VIRTIO_NET_F_MTU, + VIRTIO_F_IOMMU_PLATFORM, + VIRTIO_F_RING_PACKED, + VIRTIO_NET_F_GUEST_ANNOUNCE, + VHOST_INVALID_FEATURE_BIT +}; + +VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + return s->vhost_net; +} + +uint64_t vhost_vdpa_get_acked_features(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + s->acked_features = vhost_net_get_acked_features(s->vhost_net); + + return s->acked_features; +} + +static int vhost_vdpa_net_check_device_id(struct vhost_net *net) +{ + uint32_t device_id; + int ret; + struct vhost_dev *hdev; + + hdev = (struct vhost_dev *)&net->dev; + ret = hdev->vhost_ops->vhost_get_device_id(hdev, &device_id); + if (device_id != VIRTIO_ID_NET) { + return -ENOTSUP; + } + return ret; +} + +static void vhost_vdpa_del(NetClientState *ncs) +{ + VhostVDPAState *s; + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + s = DO_UPCAST(VhostVDPAState, nc, ncs); + if (s->vhost_net) { + vhost_net_cleanup(s->vhost_net); + } +} + +static int vhost_vdpa_add(NetClientState *ncs, void *be) +{ + VhostNetOptions options; + struct vhost_net *net = NULL; + VhostVDPAState *s; + int ret; + + options.backend_type = VHOST_BACKEND_TYPE_VDPA; + assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + s = DO_UPCAST(VhostVDPAState, nc, ncs); + options.net_backend = ncs; + options.opaque = be; + options.busyloop_timeout = 0; + + net = vhost_net_init(&options); + if (!net) { + error_report("failed to init vhost_net for queue"); + goto err; + } + if (s->vhost_net) { + vhost_net_cleanup(s->vhost_net); + g_free(s->vhost_net); + } + s->vhost_net = net; + ret = vhost_vdpa_net_check_device_id(net); + if (ret) { + goto err; + } + return 0; +err: + if (net) { + vhost_net_cleanup(net); + } + vhost_vdpa_del(ncs); + return -1; +} + +static void vhost_vdpa_cleanup(NetClientState *nc) +{ + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + + if (s->vhost_net) { + vhost_net_cleanup(s->vhost_net); + g_free(s->vhost_net); + s->vhost_net = NULL; + } +} + +static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc) +{ + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + + return true; +} + +static bool vhost_vdpa_has_ufo(NetClientState *nc) +{ + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); + uint64_t features = 0; + features |= (1ULL << VIRTIO_NET_F_HOST_UFO); + features = vhost_net_get_features(s->vhost_net, features); + return !!(features & (1ULL << VIRTIO_NET_F_HOST_UFO)); + +} + +static NetClientInfo net_vhost_vdpa_info = { + .type = NET_CLIENT_DRIVER_VHOST_VDPA, + .size = sizeof(VhostVDPAState), + .cleanup = vhost_vdpa_cleanup, + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, + .has_ufo = vhost_vdpa_has_ufo, +}; + +static int net_vhost_vdpa_init(NetClientState *peer, const char *device, + const char *name, const char *vhostdev) +{ + NetClientState *nc = NULL; + VhostVDPAState *s; + int vdpa_device_fd = -1; + int ret = 0; + assert(name); + nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name); + snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); + nc->queue_index = 0; + s = DO_UPCAST(VhostVDPAState, nc, nc); + vdpa_device_fd = qemu_open(vhostdev, O_RDWR); + if (vdpa_device_fd == -1) { + return -errno; + } + s->vhost_vdpa.device_fd = vdpa_device_fd; + ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa); + assert(s->vhost_net); + return ret; +} + +static int net_vhost_check_net(void *opaque, QemuOpts *opts, Error **errp) +{ + const char *name = opaque; + const char *driver, *netdev; + + driver = qemu_opt_get(opts, "driver"); + netdev = qemu_opt_get(opts, "netdev"); + if (!driver || !netdev) { + return 0; + } + if (strcmp(netdev, name) == 0 && + !g_str_has_prefix(driver, "virtio-net-")) { + error_setg(errp, "vhost-vdpa requires frontend driver virtio-net-*"); + return -1; + } + return 0; +} + +int net_init_vhost_vdpa(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + const NetdevVhostVDPAOptions *opts; + + assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); + opts = &netdev->u.vhost_vdpa; + /* verify net frontend */ + if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net, + (char *)name, errp)) { + return -1; + } + return net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, opts->vhostdev); +} diff --git a/qapi/net.json b/qapi/net.json index 9244c9af56..558d520a2f 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -428,16 +428,39 @@ '*vhostforce': 'bool', '*queues': 'int' } } +## +# @NetdevVhostVDPAOptions: +# +# Vhost-vdpa network backend +# +# vDPA device is a device that uses a datapath which complies with the virtio +# specifications with a vendor specific control path. +# +# @vhostdev: path of vhost-vdpa device +# (default:'/dev/vhost-vdpa-0') +# +# @queues: number of queues to be created for multiqueue vhost-vdpa +# (default: 1) +# +# Since: 5.1 +## +{ 'struct': 'NetdevVhostVDPAOptions', + 'data': { + '*vhostdev': 'str', + '*queues': 'int' } } + ## # @NetClientDriver: # # Available netdev drivers. # # Since: 2.7 +# +# @vhost-vdpa since 5.1 ## { 'enum': 'NetClientDriver', 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } + 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] } ## # @Netdev: @@ -465,7 +488,8 @@ 'bridge': 'NetdevBridgeOptions', 'hubport': 'NetdevHubPortOptions', 'netmap': 'NetdevNetmapOptions', - 'vhost-user': 'NetdevVhostUserOptions' } } + 'vhost-user': 'NetdevVhostUserOptions', + 'vhost-vdpa': 'NetdevVhostVDPAOptions' } } ## # @NetFilterDirection: -- cgit v1.2.3-55-g7522