qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 4/4] vhost-user: Add new option to specify vhost-


From: Tetsuya Mukawa
Subject: [Qemu-devel] [PATCH v1 4/4] vhost-user: Add new option to specify vhost-user backend features
Date: Fri, 29 May 2015 13:42:30 +0900

This patch adds below '-net' options to let QEMU know which features
vhost-user backend will support.

 [,backend_csum=on|off]
 [,backend_guest_csum=on|off]
 [,backend_gso=on|off]
 [,backend_guest_tso4=on|off]
 [,backend_guest_tso6=on|off]
 [,backend_guest_ecn=on|off]
 [,backend_guest_ufo=on|off]
 [,backend_guest_announce=on|off]
 [,backend_host_tso4=on|off]
 [,backend_host_tso6=on|off]
 [,backend_host_ecn=on|off]
 [,backend_host_ufo=on|off]
 [,backend_mrg_rxbuf=on|off]
 [,backend_status=on|off]
 [,backend_ctrl_vq=on|off]
 [,backend_ctrl_vx=on|off]
 [,backend_ctrl_vlan=on|off]
 [,backend_ctrl_rx_extra=on|off]
 [,backend_ctrl_mac_addr=on|off]
 [,backend_ctrl_guest_offloads=on|off]
 [,backend_mq=on|off]

If above features are specified, QEMU assumes vhost-user backend supports
the features, then QEMU can start without vhost-user backend connection.
(While no connection, link status of virtio-net device will be down)

Here are examples.
* QEMU is configured as vhost-user client.
 -chardev socket,id=chr0,path=/tmp/sock,reconnect=3 \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
 -device virtio-net-pci,netdev=net0 \

* QEMU is configured as vhost-user server.
 -chardev socket,id=chr0,path=/tmp/sock,server,nowait \
 -netdev vhost-user,id=net0,chardev=chr0,vhostforce,backend_mrg_rxbuf \
 -device virtio-net-pci,netdev=net0 \

Above cases, QEMU assumes vhost-user backend will support
VIRTIO_NET_F_MRG_RXBUF feature defined in linux/virtio_net.h

When connection between QEMU and the backend is established, QEMU checkes 
feature
values of the backend to make sure the expected features are provided.
If it doesn't, the connection will be closed by QEMU.

Signed-off-by: Tetsuya Mukawa <address@hidden>
---
 hw/net/vhost_net.c             |   6 ++-
 hw/net/virtio-net.c            |  13 +++++
 hw/scsi/vhost-scsi.c           |   2 +-
 hw/virtio/vhost-user.c         |   7 +++
 hw/virtio/vhost.c              |   7 ++-
 include/hw/virtio/vhost.h      |   3 +-
 include/hw/virtio/virtio-net.h |   1 +
 include/net/net.h              |   3 ++
 include/net/vhost_net.h        |   1 +
 net/net.c                      |   9 ++++
 net/tap.c                      |   1 +
 net/vhost-user.c               |  49 +++++++++++++++++-
 qapi-schema.json               | 114 +++++++++++++++++++++++++++++++++++------
 qemu-options.hx                |  10 ++++
 14 files changed, 204 insertions(+), 22 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 47f8b89..8799c75 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -158,8 +158,12 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
     net->dev.nvqs = 2;
     net->dev.vqs = net->vqs;
 
+    if (options->backend_features)
+        net->dev.backend_features = options->backend_features;
+
     r = vhost_dev_init(&net->dev, options->opaque,
-                       options->backend_type, options->force);
+                       options->backend_type, options->force,
+                       options->backend_features);
     if (r < 0) {
         goto fail;
     }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 3af6faf..7fbb306 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -366,6 +366,17 @@ static int peer_has_ufo(VirtIONet *n)
     return n->has_ufo;
 }
 
+static uint64_t peer_backend_features(VirtIONet *n)
+{
+    if (!peer_has_vnet_hdr(n))
+        return 0;
+
+    n->backend_features =
+            qemu_backend_features(qemu_get_queue(n->nic)->peer);
+
+    return n->backend_features;
+}
+
 static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
 {
     int i;
@@ -463,6 +474,8 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, 
uint32_t features)
     }
 
     if (!get_vhost_net(nc->peer)) {
+        if (peer_backend_features(n))
+            features = peer_backend_features(n);
         return features;
     }
     return vhost_net_get_features(get_vhost_net(nc->peer), features);
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 335f442..25fae56 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -246,7 +246,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error 
**errp)
     s->dev.backend_features = 0;
 
     ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
-                         VHOST_BACKEND_TYPE_KERNEL, true);
+                         VHOST_BACKEND_TYPE_KERNEL, true, 0);
     if (ret < 0) {
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
                    strerror(-ret));
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 4d7e3ba..d847ea5 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -307,6 +307,13 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned 
long int request,
                 error_report("Received bad msg size.");
                 goto close;
             }
+            if (dev->backend_features != (dev->backend_features & msg.u64)) {
+                    error_report("Lack of backend features. "
+                                 "Expected 0x%llx, but receives 0x%lx",
+                                 dev->backend_features, msg.u64);
+                    goto close;
+            }
+
             *((__u64 *) arg) = msg.u64;
             break;
         case VHOST_USER_GET_VRING_BASE:
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 54851b7..0663aed 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -811,7 +811,8 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue 
*vq)
 }
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type, bool force)
+                   VhostBackendType backend_type, bool force,
+                   unsigned long long backend_features)
 {
     uint64_t features;
     int i, r;
@@ -833,7 +834,9 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 
     r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features);
     if (r < 0) {
-        goto fail;
+        if (backend_features == 0)
+            goto fail;
+        features = backend_features;
     }
 
     for (i = 0; i < hdev->nvqs; ++i) {
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 8f04888..b75ed70 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -55,7 +55,8 @@ struct vhost_dev {
 };
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
-                   VhostBackendType backend_type, bool force);
+                   VhostBackendType backend_type, bool force,
+                   unsigned long long backend_features);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e0dbb41..3edd175 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -70,6 +70,7 @@ typedef struct VirtIONet {
     size_t guest_hdr_len;
     uint32_t host_features;
     uint8_t has_ufo;
+    uint64_t backend_features;
     int mergeable_rx_bufs;
     uint8_t promisc;
     uint8_t allmulti;
diff --git a/include/net/net.h b/include/net/net.h
index e66ca03..16b855e 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -55,6 +55,7 @@ typedef bool (HasVnetHdrLen)(NetClientState *, int);
 typedef void (UsingVnetHdr)(NetClientState *, bool);
 typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
+typedef unsigned long long (BackendFeatures)(NetClientState *);
 
 typedef struct NetClientInfo {
     NetClientOptionsKind type;
@@ -73,6 +74,7 @@ typedef struct NetClientInfo {
     UsingVnetHdr *using_vnet_hdr;
     SetOffload *set_offload;
     SetVnetHdrLen *set_vnet_hdr_len;
+    BackendFeatures *backend_features;
 } NetClientInfo;
 
 struct NetClientState {
@@ -136,6 +138,7 @@ bool qemu_has_ufo(NetClientState *nc);
 bool qemu_has_vnet_hdr(NetClientState *nc);
 bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
 void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
+unsigned long long qemu_backend_features(NetClientState *nc);
 void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
                       int ecn, int ufo);
 void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index b1c18a3..ca6c5ab 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -12,6 +12,7 @@ typedef struct VhostNetOptions {
     NetClientState *net_backend;
     void *opaque;
     bool force;
+    unsigned long long backend_features;
 } VhostNetOptions;
 
 struct vhost_net *vhost_net_init(VhostNetOptions *options);
diff --git a/net/net.c b/net/net.c
index db6be12..7415eb2 100644
--- a/net/net.c
+++ b/net/net.c
@@ -510,6 +510,15 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
     nc->info->set_vnet_hdr_len(nc, len);
 }
 
+unsigned long long qemu_backend_features(NetClientState *nc)
+{
+    if (!nc || !nc->info->backend_features) {
+        return false;
+    }
+
+    return nc->info->backend_features(nc);
+}
+
 int qemu_can_send_packet(NetClientState *sender)
 {
     int vm_running = runstate_is_running();
diff --git a/net/tap.c b/net/tap.c
index d1ca314..f2ba94d 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -656,6 +656,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
         options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
         options.net_backend = &s->nc;
         options.force = tap->has_vhostforce && tap->vhostforce;
+        options.backend_features = tap->backend_features;
 
         if (tap->has_vhostfd || tap->has_vhostfds) {
             vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
diff --git a/net/vhost-user.c b/net/vhost-user.c
index f823d78..6474a31 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -8,6 +8,8 @@
  *
  */
 
+#include <linux/virtio_net.h>
+
 #include "clients.h"
 #include "net/vhost_net.h"
 #include "net/vhost-user.h"
@@ -19,6 +21,7 @@ typedef struct VhostUserState {
     NetClientState nc;
     CharDriverState *chr;
     VHostNetState *vhost_net;
+    unsigned long long backend_features;
     int watch;
 } VhostUserState;
 
@@ -54,6 +57,7 @@ static int vhost_user_start(VhostUserState *s)
     options.net_backend = &s->nc;
     options.opaque = s->chr;
     options.force = true;
+    options.backend_features = s->backend_features;
 
     s->vhost_net = vhost_net_init(&options);
 
@@ -91,12 +95,22 @@ static bool vhost_user_has_ufo(NetClientState *nc)
     return true;
 }
 
+static unsigned long long vhost_user_backend_features(NetClientState *nc)
+{
+    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+
+    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+
+    return s->backend_features;
+}
+
 static NetClientInfo net_vhost_user_info = {
         .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
         .size = sizeof(VhostUserState),
         .cleanup = vhost_user_cleanup,
         .has_vnet_hdr = vhost_user_has_vnet_hdr,
         .has_ufo = vhost_user_has_ufo,
+        .backend_features = vhost_user_backend_features,
 };
 
 static void net_vhost_link_down(VhostUserState *s, bool link_down)
@@ -148,7 +162,8 @@ static void net_vhost_user_event(void *opaque, int event)
 }
 
 static int net_vhost_user_init(NetClientState *peer, const char *device,
-                               const char *name, CharDriverState *chr)
+                               const char *name, CharDriverState *chr,
+                               unsigned long long backend_features)
 {
     NetClientState *nc;
     VhostUserState *s;
@@ -163,6 +178,7 @@ static int net_vhost_user_init(NetClientState *peer, const 
char *device,
     /* We don't provide a receive callback */
     s->nc.receive_disabled = 1;
     s->chr = chr;
+    s->backend_features = backend_features;
 
     qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s);
 
@@ -242,12 +258,38 @@ static int net_vhost_check_net(QemuOpts *opts, void 
*opaque)
     return 0;
 }
 
+static inline unsigned long long
+net_get_vhost_backend_features(const NetdevVhostUserOptions *opts)
+{
+    return (opts->backend_csum ? 1 << VIRTIO_NET_F_CSUM : 0) |
+        (opts->backend_guest_csum ? 1 << VIRTIO_NET_F_GUEST_CSUM : 0) |
+        (opts->backend_gso ? 1 << VIRTIO_NET_F_GSO : 0) |
+        (opts->backend_guest_tso4 ? 1 << VIRTIO_NET_F_GUEST_TSO4 : 0) |
+        (opts->backend_guest_tso6 ? 1 << VIRTIO_NET_F_GUEST_TSO6 : 0) |
+        (opts->backend_guest_ecn ? 1 << VIRTIO_NET_F_GUEST_ECN : 0) |
+        (opts->backend_guest_ufo ? 1 << VIRTIO_NET_F_GUEST_UFO : 0) |
+        (opts->backend_guest_announce ? 1 << VIRTIO_NET_F_GUEST_ANNOUNCE : 0) |
+        (opts->backend_host_tso4 ? 1 << VIRTIO_NET_F_HOST_TSO4 : 0) |
+        (opts->backend_host_tso6 ? 1 << VIRTIO_NET_F_HOST_TSO6 : 0) |
+        (opts->backend_host_ecn ? 1 << VIRTIO_NET_F_HOST_ECN : 0) |
+        (opts->backend_host_ufo ? 1 << VIRTIO_NET_F_HOST_UFO : 0) |
+        (opts->backend_mrg_rxbuf ? 1 << VIRTIO_NET_F_MRG_RXBUF : 0) |
+        (opts->backend_status ? 1 << VIRTIO_NET_F_STATUS : 0) |
+        (opts->backend_ctrl_vq ? 1 << VIRTIO_NET_F_CTRL_VQ : 0) |
+        (opts->backend_ctrl_rx ? 1 << VIRTIO_NET_F_CTRL_RX : 0) |
+        (opts->backend_ctrl_vlan ? 1 << VIRTIO_NET_F_CTRL_VLAN : 0) |
+        (opts->backend_ctrl_rx_extra ? 1 << VIRTIO_NET_F_CTRL_RX_EXTRA : 0) |
+        (opts->backend_ctrl_mac_addr ? 1 << VIRTIO_NET_F_CTRL_MAC_ADDR : 0) |
+        (opts->backend_mq ? 1 << VIRTIO_NET_F_MQ : 0);
+}
+
 int net_init_vhost_user(const NetClientOptions *opts, const char *name,
                         NetClientState *peer, Error **errp)
 {
     /* FIXME error_setg(errp, ...) on failure */
     const NetdevVhostUserOptions *vhost_user_opts;
     CharDriverState *chr;
+    unsigned long long backend_features;
 
     assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
     vhost_user_opts = opts->vhost_user;
@@ -264,6 +306,9 @@ int net_init_vhost_user(const NetClientOptions *opts, const 
char *name,
         return -1;
     }
 
+    /* backend features */
+    backend_features = net_get_vhost_backend_features(vhost_user_opts);
 
-    return net_vhost_user_init(peer, "vhost_user", name, chr);
+    return net_vhost_user_init(peer, "vhost_user", name, chr,
+                                backend_features);
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index f97ffa1..1e868a9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2241,25 +2241,29 @@
 #
 # @vhostforce: #optional vhost on for non-MSIX virtio guests
 #
+# @backend_features: #optional feature flag to support vhost user backend
+#                    (Since 2.4)
+#
 # @queues: #optional number of queues to be created for multiqueue capable tap
 #
 # Since 1.2
 ##
 { 'struct': 'NetdevTapOptions',
   'data': {
-    '*ifname':     'str',
-    '*fd':         'str',
-    '*fds':        'str',
-    '*script':     'str',
-    '*downscript': 'str',
-    '*helper':     'str',
-    '*sndbuf':     'size',
-    '*vnet_hdr':   'bool',
-    '*vhost':      'bool',
-    '*vhostfd':    'str',
-    '*vhostfds':   'str',
-    '*vhostforce': 'bool',
-    '*queues':     'uint32'} }
+    '*ifname':           'str',
+    '*fd':               'str',
+    '*fds':              'str',
+    '*script':           'str',
+    '*downscript':       'str',
+    '*helper':           'str',
+    '*sndbuf':           'size',
+    '*vnet_hdr':         'bool',
+    '*vhost':            'bool',
+    '*vhostfd':          'str',
+    '*vhostfds':         'str',
+    '*vhostforce':       'bool',
+    '*backend_features': 'uint64',
+    '*queues':           'uint32'} }
 
 ##
 # @NetdevSocketOptions
@@ -2444,12 +2448,92 @@
 #
 # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false).
 #
+# @backend_csum: #optional feature backend supports (default: false).
+#                (Since 2.4)
+#
+# @backend_guest_csum: #optional feature backend supports (default: false).
+#                      (Since 2.4)
+#
+# @backend_gso: #optional feature backend supports (default: false).
+#               (Since 2.4)
+#
+# @backend_guest_tso4: #optional feature backend supports (default: false).
+#                      (Since 2.4)
+#
+# @backend_guest_tso6: #optional feature backend supports (default: false).
+#                      (Since 2.4)
+#
+# @backend_guest_ecn: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_guest_ufo: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_guest_announce: #optional feature backend supports (default: false).
+#                          (Since 2.4)
+#
+# @backend_host_tso4: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_host_tso6: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_host_ecn: #optional feature backend supports (default: false).
+#                    (Since 2.4)
+#
+# @backend_host_ufo: #optional feature backend supports (default: false).
+#                    (Since 2.4)
+#
+# @backend_mrg_rxbuf: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_status: #optional feature backend supports (default: false).
+#                  (Since 2.4)
+#
+# @backend_ctrl_vq: #optional feature backend supports (default: false).
+#                   (Since 2.4)
+#
+# @backend_ctrl_rx: #optional feature backend supports (default: false).
+#                   (Since 2.4)
+#
+# @backend_ctrl_vlan: #optional feature backend supports (default: false).
+#                     (Since 2.4)
+#
+# @backend_ctrl_rx_extra: #optional feature backend supports (default: false).
+#                         (Since 2.4)
+#
+# @backend_ctrl_mac_addr: #optional feature backend supports (default: false).
+#                         (Since 2.4)
+#
+# @backend_mq: #optional feature backend supports (default: false).
+#              (Since 2.4)
+#
 # Since 2.1
 ##
 { 'struct': 'NetdevVhostUserOptions',
   'data': {
-    'chardev':        'str',
-    '*vhostforce':    'bool' } }
+    'chardev':                 'str',
+    '*vhostforce':             'bool',
+    '*backend_csum':           'bool',
+    '*backend_guest_csum':     'bool',
+    '*backend_gso':            'bool',
+    '*backend_guest_tso4':     'bool',
+    '*backend_guest_tso6':     'bool',
+    '*backend_guest_ecn':      'bool',
+    '*backend_guest_ufo':      'bool',
+    '*backend_guest_announce': 'bool',
+    '*backend_host_tso4':      'bool',
+    '*backend_host_tso6':      'bool',
+    '*backend_host_ecn':       'bool',
+    '*backend_host_ufo':       'bool',
+    '*backend_mrg_rxbuf':      'bool',
+    '*backend_status':         'bool',
+    '*backend_ctrl_vq':        'bool',
+    '*backend_ctrl_rx':        'bool',
+    '*backend_ctrl_vlan':      'bool',
+    '*backend_ctrl_rx_extra':  'bool',
+    '*backend_ctrl_mac_addr':  'bool',
+    '*backend_mq':             'bool' } }
 
 ##
 # @NetClientOptions
diff --git a/qemu-options.hx b/qemu-options.hx
index 88d7661..133dc99 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1467,6 +1467,15 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "-netdev 
tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]\n"
     "         
[,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]\n"
     "         
[,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]\n"
+    "         
[,backend_csum=on|off][,backend_guest_csum=on|off][,backend_gso=on|off]\n"
+    "         [,backend_guest_tso4=on|off][,backend_guest_tso6=on|off]\n"
+    "         [,backend_guest_ecn=on|off][,backend_guest_ufo=on|off]\n"
+    "         [,backend_guest_announce=on|off][,backend_host_tso4=on|off]\n"
+    "         [,backend_host_tso6=on|off][,backend_host_ecn=on|off]\n"
+    "         
[,backend_host_ufo=on|off][,backend_mrg_rxbuf=on|off][,backend_status=on|off]\n"
+    "         
[,backend_ctrl_vq=on|off][,backend_ctrl_vx=on|off][,backend_ctrl_vlan=on|off]\n"
+    "         [,backend_ctrl_rx_extra=on|off][,backend_ctrl_mac_addr=on|off]\n"
+    "         [,backend_ctrl_guest_offloads=on|off][,backend_mq=on|off]\n"
     "                configure a host TAP network backend with ID 'str'\n"
     "                use network scripts 'file' (default=" 
DEFAULT_NETWORK_SCRIPT ")\n"
     "                to configure it and 'dfile' (default=" 
DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
@@ -1486,6 +1495,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
     "                use 'vhostfd=h' to connect to an already opened vhost net 
device\n"
     "                use 'vhostfds=x:y:...:z to connect to multiple already 
opened vhost net devices\n"
     "                use 'queues=n' to specify the number of queues to be 
created for multiqueue TAP\n"
+    "                use 'backend_*=on' to specify virtio-net feature that 
vhost-user backend supports\n"
     "-netdev bridge,id=str[,br=bridge][,helper=helper]\n"
     "                configure a host TAP network backend with ID 'str' that 
is\n"
     "                connected to a bridge (default=" DEFAULT_BRIDGE_INTERFACE 
")\n"
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]