Skip to contentSkip to conversation

qemu/virtio: move features to an inline function

PATCH In review Michael S. Tsirkin 5 participants 22 messages Nov 2, 2009 – Nov 5, 2009 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Michael S. Tsirkin

author maintainer
#1 lore raw

PATCH v4 1/6 qemu/virtio: move features to an inline function

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

No functional changes.

---
 hw/virtio-balloon.c |    2 +-
 hw/virtio-blk.c     |    2 +-
 hw/virtio-console.c |    2 +-
 hw/virtio-net.c     |    2 +-
 hw/virtio-pci.c     |    3 ---
 hw/virtio.h         |   10 ++++++++++
 6 files changed, 14 insertions(+), 7 deletions(-)
hw/virtio-balloon.c +1 -1
index 7ca783e..15b50bb 100644
@@ -127,7 +127,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
 
 static uint32_t virtio_balloon_get_features(VirtIODevice *vdev)
 {
-    return 0;
+    return virtio_common_features();
 }
 
 static ram_addr_t virtio_balloon_to_target(void *opaque, ram_addr_t target)
hw/virtio-blk.c +1 -1
index 2630b99..db727b9 100644
@@ -445,7 +445,7 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
     if (strcmp(s->serial_str, "0"))
         features |= 1 << VIRTIO_BLK_F_IDENTIFY;
 
-    return features;
+    return features | virtio_common_features();
 }
 
 static void virtio_blk_save(QEMUFile *f, void *opaque)
hw/virtio-console.c +1 -1
index 92c953c..79544bb 100644
@@ -53,7 +53,7 @@ static void virtio_console_handle_input(VirtIODevice *vdev, VirtQueue *vq)
 
 static uint32_t virtio_console_get_features(VirtIODevice *vdev)
 {
-    return 0;
+    return virtio_common_features();
 }
 
 static int vcon_can_read(void *opaque)
hw/virtio-net.c +1 -1
index ce8e6cb..469c6e3 100644
@@ -154,7 +154,7 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
     }
 #endif
 
-    return features;
+    return features | virtio_common_features();
 }
 
 static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
hw/virtio-pci.c +0 -3
index 01782e5..0716f6f 100644
@@ -230,9 +230,6 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
     switch (addr) {
     case VIRTIO_PCI_HOST_FEATURES:
         ret = vdev->get_features(vdev);
-        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
-        ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
-        ret |= (1 << VIRTIO_F_BAD_FEATURE);
         break;
     case VIRTIO_PCI_GUEST_FEATURES:
         ret = vdev->features;
hw/virtio.h +10 -0
index 0f9be7d..799e608 100644
@@ -167,4 +167,14 @@ VirtIODevice *virtio_net_init(DeviceState *dev);
 VirtIODevice *virtio_console_init(DeviceState *dev);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
 
+static inline uint32_t virtio_common_features(void)
+{
+    uint32_t features = 0;
+    features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+    features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
+    features |= (1 << VIRTIO_F_BAD_FEATURE);
+
+    return features;
+}
+
 #endif
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#2 lore raw

PATCH v4 1/6 qemu/virtio: move features to an inline function

In reply to a message not in the archive

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

No functional changes.

---
 hw/virtio-balloon.c |    2 +-
 hw/virtio-blk.c     |    2 +-
 hw/virtio-console.c |    2 +-
 hw/virtio-net.c     |    2 +-
 hw/virtio-pci.c     |    3 ---
 hw/virtio.h         |   10 ++++++++++
 6 files changed, 14 insertions(+), 7 deletions(-)
hw/virtio-balloon.c +1 -1
index 7ca783e..15b50bb 100644
@@ -127,7 +127,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
 
 static uint32_t virtio_balloon_get_features(VirtIODevice *vdev)
 {
-    return 0;
+    return virtio_common_features();
 }
 
 static ram_addr_t virtio_balloon_to_target(void *opaque, ram_addr_t target)
hw/virtio-blk.c +1 -1
index 2630b99..db727b9 100644
@@ -445,7 +445,7 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
     if (strcmp(s->serial_str, "0"))
         features |= 1 << VIRTIO_BLK_F_IDENTIFY;
 
-    return features;
+    return features | virtio_common_features();
 }
 
 static void virtio_blk_save(QEMUFile *f, void *opaque)
hw/virtio-console.c +1 -1
index 92c953c..79544bb 100644
@@ -53,7 +53,7 @@ static void virtio_console_handle_input(VirtIODevice *vdev, VirtQueue *vq)
 
 static uint32_t virtio_console_get_features(VirtIODevice *vdev)
 {
-    return 0;
+    return virtio_common_features();
 }
 
 static int vcon_can_read(void *opaque)
hw/virtio-net.c +1 -1
index ce8e6cb..469c6e3 100644
@@ -154,7 +154,7 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
     }
 #endif
 
-    return features;
+    return features | virtio_common_features();
 }
 
 static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
hw/virtio-pci.c +0 -3
index 01782e5..0716f6f 100644
@@ -230,9 +230,6 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
     switch (addr) {
     case VIRTIO_PCI_HOST_FEATURES:
         ret = vdev->get_features(vdev);
-        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
-        ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
-        ret |= (1 << VIRTIO_F_BAD_FEATURE);
         break;
     case VIRTIO_PCI_GUEST_FEATURES:
         ret = vdev->features;
hw/virtio.h +10 -0
index 0f9be7d..799e608 100644
@@ -167,4 +167,14 @@ VirtIODevice *virtio_net_init(DeviceState *dev);
 VirtIODevice *virtio_console_init(DeviceState *dev);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
 
+static inline uint32_t virtio_common_features(void)
+{
+    uint32_t features = 0;
+    features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+    features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
+    features |= (1 << VIRTIO_F_BAD_FEATURE);
+
+    return features;
+}
+
 #endif
Signature · 1 line
1.6.5.2.143.g8cc62
#3 lore raw
Quoted 8 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.

Regards,

Anthony Liguori

#4 lore raw
Quoted 7 lines · Anthony Liguori
Quoted 6 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

Quoted 5 lines
Quoted 1 line

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

It's equivalent to -cpu host. Sometimes you want to pass-through host capabilities in order to make the best use of your hardware. In fact, even -cpu !host allows the host kernel to nack features since the cost of emulation is prohibitive.

Quoted 3 lines

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.

Since the kernel and qemu are developed independently, there's no way to ensure they support exactly the same capabilities. The kernel can always lag. The only options are to allow the host kernel to nack features, or to fall back to the userspace implementation.

It needs to be finer grained (qemu invoker telling qemu what the minimum features are needed, and qemu telling the invoker what capabilties it supports) but there's no way around it IMO.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#5 lore raw
In reply to Anthony Liguori
Quoted 10 lines · Anthony Liguori
Quoted 7 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

It's equivalent to -cpu host. Sometimes you want to pass-through host capabilities in order to make the best use of your hardware. In fact, even -cpu !host allows the host kernel to nack features since the cost of emulation is prohibitive.

Quoted 1 line

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.

Since the kernel and qemu are developed independently, there's no way to ensure they support exactly the same capabilities. The kernel can always lag. The only options are to allow the host kernel to nack features, or to fall back to the userspace implementation.

It needs to be finer grained (qemu invoker telling qemu what the minimum features are needed, and qemu telling the invoker what capabilties it supports) but there's no way around it IMO.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
author maintainer
#6 lore raw
In reply to Anthony Liguori
Quoted 7 lines · Anthony Liguori
Quoted 6 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

Quoted 6 lines
Quoted 2 lines

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

We could pass "vhost" flag to virtio, and have virtio query the device for features. Would that be better?

Quoted 6 lines

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.
Regards,

Anthony Liguori

Yes, you can make vhost an alternative transport in qemu. This might be one way to handle this. However, this seems to go contrary to your previous proposal to make vhost a networking back end. Which will it be?

Signature · 1 line
MST
author maintainer
#7 lore raw
In reply to Anthony Liguori
Quoted 7 lines · Anthony Liguori
Quoted 6 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

Quoted 6 lines
Quoted 2 lines

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

We could pass "vhost" flag to virtio, and have virtio query the device for features. Would that be better?

Quoted 6 lines

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.
Regards,

Anthony Liguori

Yes, you can make vhost an alternative transport in qemu. This might be one way to handle this. However, this seems to go contrary to your previous proposal to make vhost a networking back end. Which will it be?

Signature · 1 line
MST
#8 lore raw
In reply to Michael S. Tsirkin
Quoted 8 lines · Michael S. Tsirkin

devices should have the final say over which virtio features they support. E.g. indirect entries may or may not make sense in the context of virtio-console. In particular, for vhost, we do not want to report to guest bits not supported by kernel backend. Move the common bits from virtio-pci to an inline function and let each device call it.

No functional changes.

This is a layering violation. There are transport specific features and device specific features. The virtio-net device should have no knowledge or nack'ing ability for transport features.

If you need to change transport features, it suggests you're modeling things incorrectly and should be supplying an alternative transport implementation.

Regards,

Anthony Liguori

#9 lore raw

PATCH v4 3/6 qemu/net: add raw backend

In reply to a message not in the archive

Add raw network backend option which uses a packet socket to provide raw networking access. Once the socket is opened it's bound to a provided host interface, such that packets received on the interface are delivered to the VM and packets sent by the VM are sent to the interface.

This is functionally similar to the existing pcap network backend, with the same advantages and problems. Differences from pcap:
- can get an open socket from the monitor,
which allows running without NET_ADMIN priviledges
- support iovec sends with writev, saving one data copy
- one less dependency on an external library
- we have access to the underlying file descriptor
which makes it possible to connect to vhost net
- don't support polling all interfaces, always bind to a specific one

---
 hw/virtio-net.c |    3 +-
 net.c           |  192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx |    4 +
 3 files changed, 198 insertions(+), 1 deletions(-)
hw/virtio-net.c +2 -1
index 469c6e3..2e51a6a 100644
@@ -531,7 +531,8 @@ static ssize_t virtio_net_receive2(VLANClientState *vc, const uint8_t *buf, size
             virtqueue_pop(n->rx_vq, &elem) == 0) {
             if (i == 0)
                 return -1;
-            fprintf(stderr, "virtio-net truncating packet\n");
+            fprintf(stderr, "virtio-net truncating packet. offset %zd size %zd\n",
+		    offset, size);
             exit(1);
         }
 
net.c +192 -0

216 lines not on this page · raw message

qemu-options.hx +4 -0
index bde3e3f..0d5440f 100644
@@ -825,6 +825,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "                default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
 #endif
 #endif
+    "-net raw[,vlan=n][,name=str],ifname=name[,promisc=m]\n"
+    "                bound the host network interface to VLAN 'n' in a raw manner:\n"
+    "                packets received on the interface are delivered to the vlan and\n"
+    "                packets delivered on the vlan are sent to the interface\n"
     "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
     "                connect the vlan 'n' to another VLAN using a socket connection\n"
     "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#10 lore raw

PATCH v4 2/6 qemu/net: routines to get tap fd

In reply to a message not in the archive

vhost need tap fd, add API to get it from vlan client

---
 net.c |   10 ++++++++++
 net.h |    1 +
 2 files changed, 11 insertions(+), 0 deletions(-)
net.c +10 -0
index 6a7f1c2..8ac639b 100644
@@ -1472,6 +1472,16 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 }
 #endif /* TUNSETSNDBUF */
 
+int tap_get_fd(VLANClientState *vc)
+{
+    TAPState *s = vc->opaque;
+
+    if (vc->receive != tap_receive)
+        return -1;
+
+    return s->fd;
+}
+
 int tap_has_vnet_hdr(void *opaque)
 {
     VLANClientState *vc = opaque;
net.h +1 -0
index d1ba23b..7246d16 100644
@@ -92,6 +92,7 @@ void do_set_link(Monitor *mon, const QDict *qdict);
 
 void do_info_usernet(Monitor *mon);
 
+int tap_get_fd(VLANClientState *vc);
 int tap_has_vnet_hdr(void *opaque);
 void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr);
 
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#11 lore raw

PATCH v4 2/6 qemu/net: routines to get tap fd

In reply to a message not in the archive

vhost need tap fd, add API to get it from vlan client

---
 net.c |   10 ++++++++++
 net.h |    1 +
 2 files changed, 11 insertions(+), 0 deletions(-)
net.c +10 -0
index 6a7f1c2..8ac639b 100644
@@ -1472,6 +1472,16 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
 }
 #endif /* TUNSETSNDBUF */
 
+int tap_get_fd(VLANClientState *vc)
+{
+    TAPState *s = vc->opaque;
+
+    if (vc->receive != tap_receive)
+        return -1;
+
+    return s->fd;
+}
+
 int tap_has_vnet_hdr(void *opaque)
 {
     VLANClientState *vc = opaque;
net.h +1 -0
index d1ba23b..7246d16 100644
@@ -92,6 +92,7 @@ void do_set_link(Monitor *mon, const QDict *qdict);
 
 void do_info_usernet(Monitor *mon);
 
+int tap_get_fd(VLANClientState *vc);
 int tap_has_vnet_hdr(void *opaque);
 void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr);
 
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#12 lore raw

PATCH v4 4/6 qemu/net: move typedef to qemu-common.h

In reply to a message not in the archive

Move typedef VLANClientState to qemu-common.h so that users can use forward-declared type without pulling in net.h

---
 net.h         |    2 --
 qemu-common.h |    1 +
 2 files changed, 1 insertions(+), 2 deletions(-)
net.h +0 -2
index 7246d16..00485e2 100644
@@ -8,8 +8,6 @@
 
 /* VLANs support */
 
-typedef struct VLANClientState VLANClientState;
-
 typedef int (NetCanReceive)(VLANClientState *);
 typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
qemu-common.h +1 -0
index 875010b..704796e 100644
@@ -193,6 +193,7 @@ typedef struct uWireSlave uWireSlave;
 typedef struct I2SCodec I2SCodec;
 typedef struct DeviceState DeviceState;
 typedef struct SSIBus SSIBus;
+typedef struct VLANClientState VLANClientState;
 
 /* CPU save/load.  */
 void cpu_save(QEMUFile *f, void *opaque);
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#13 lore raw

PATCH v4 4/6 qemu/net: move typedef to qemu-common.h

In reply to a message not in the archive

Move typedef VLANClientState to qemu-common.h so that users can use forward-declared type without pulling in net.h

---
 net.h         |    2 --
 qemu-common.h |    1 +
 2 files changed, 1 insertions(+), 2 deletions(-)
net.h +0 -2
index 7246d16..00485e2 100644
@@ -8,8 +8,6 @@
 
 /* VLANs support */
 
-typedef struct VLANClientState VLANClientState;
-
 typedef int (NetCanReceive)(VLANClientState *);
 typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
qemu-common.h +1 -0
index 875010b..704796e 100644
@@ -193,6 +193,7 @@ typedef struct uWireSlave uWireSlave;
 typedef struct I2SCodec I2SCodec;
 typedef struct DeviceState DeviceState;
 typedef struct SSIBus SSIBus;
+typedef struct VLANClientState VLANClientState;
 
 /* CPU save/load.  */
 void cpu_save(QEMUFile *f, void *opaque);
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#14 lore raw

PATCH v4 5/6 qemu/raw: add API to get raw socket

In reply to a message not in the archive

Add API to get raw socket from vlanclient, so that we can connect it to frontend such as vhost.

---
 net.c |    8 ++++++++
 net.h |    2 ++
 2 files changed, 10 insertions(+), 0 deletions(-)
net.c +8 -0
index 1fb2f2f..9168460 100644
@@ -2025,6 +2025,14 @@ static int net_raw_init(Monitor *mon, VLANState *vlan, const char *model,
 	return 0;
 }
 
+int raw_get_fd(VLANClientState *vc)
+{
+	RAWState *s = vc->opaque;
+	if (vc->receive != raw_receive)
+		return -1;
+	return s->fd;
+}
+
 #if defined(CONFIG_VDE)
 typedef struct VDEState {
     VLANClientState *vc;
net.h +2 -0
index 00485e2..932b50d 100644
@@ -94,6 +94,8 @@ int tap_get_fd(VLANClientState *vc);
 int tap_has_vnet_hdr(void *opaque);
 void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr);
 
+int raw_get_fd(VLANClientState *vc);
+
 /* NIC info */
 
 #define MAX_NICS 8
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#15 lore raw

PATCH v4 5/6 qemu/raw: add API to get raw socket

In reply to a message not in the archive

Add API to get raw socket from vlanclient, so that we can connect it to frontend such as vhost.

---
 net.c |    8 ++++++++
 net.h |    2 ++
 2 files changed, 10 insertions(+), 0 deletions(-)
net.c +8 -0
index 1fb2f2f..9168460 100644
@@ -2025,6 +2025,14 @@ static int net_raw_init(Monitor *mon, VLANState *vlan, const char *model,
 	return 0;
 }
 
+int raw_get_fd(VLANClientState *vc)
+{
+	RAWState *s = vc->opaque;
+	if (vc->receive != raw_receive)
+		return -1;
+	return s->fd;
+}
+
 #if defined(CONFIG_VDE)
 typedef struct VDEState {
     VLANClientState *vc;
net.h +2 -0
index 00485e2..932b50d 100644
@@ -94,6 +94,8 @@ int tap_get_fd(VLANClientState *vc);
 int tap_has_vnet_hdr(void *opaque);
 void tap_using_vnet_hdr(void *opaque, int using_vnet_hdr);
 
+int raw_get_fd(VLANClientState *vc);
+
 /* NIC info */
 
 #define MAX_NICS 8
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#16 lore raw

PATCH v4 6/6 qemu-kvm: vhost-net implementation

In reply to a message not in the archive

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

This patchset is RFC, but works without issues for me.

TODO:
* migration support
* level triggered interrupts
* fix driver unloading/hotplug
* general cleanup and upstreaming

It still needs to be split up, tested and benchmarked properly, but posting it here in case people want to test drive the kernel bits I posted.

Some further info, performance etc:
http://www.linux-kvm.org/page/VhostNet

---
 Makefile.target           |    3 +-
 hw/vhost_net.c            |  251 +++++++++++++++++++++++++++++++++++++++++++++
 hw/vhost_net.h            |   38 +++++++
 hw/virtio-net.c           |   67 ++++++++++--
 hw/virtio-pci.c           |   40 +++++++
 hw/virtio.c               |   19 ----
 hw/virtio.h               |   28 +++++-
 kvm/include/linux/vhost.h |  126 +++++++++++++++++++++++
 net.c                     |    7 ++
 net.h                     |    1 +
 qemu-kvm.c                |    8 --
 qemu-kvm.h                |    9 ++
 12 files changed, 555 insertions(+), 42 deletions(-)
 create mode 100644 hw/vhost_net.c
 create mode 100644 hw/vhost_net.h
 create mode 100644 kvm/include/linux/vhost.h
Makefile.target +2 -1
index acee285..0d8e688 100644
@@ -160,7 +160,8 @@ obj-y = vl.o monitor.o pci.o isa_mmio.o machine.o \
         gdbstub.o gdbstub-xml.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
-obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o
+obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o \
+	vhost_net.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 # MSI-X depends on kvm for interrupt injection,
 # so moved it from Makefile.hw to Makefile.target for now
hw/vhost_net.c new file +251 -0

251 lines not on this page · raw message

hw/vhost_net.h new file +38 -0
new file mode 100644
index 0000000..65720e1
@@ -0,0 +1,38 @@
+#ifndef VHOST_NET_H
+#define VHOST_NET_H
+
+#include "hw/virtio.h"
+
+struct vhost_virtqueue {
+	int kick;
+	int call;
+	void *desc;
+	void *avail;
+	void *used;
+};
+
+struct vhost_dev {
+	int control;
+	struct vhost_virtqueue *vqs;
+	int nvqs;
+	unsigned long long features;
+	unsigned long long acked_features;
+	unsigned long long backend_features;
+};
+
+struct vhost_net {
+	struct vhost_dev dev;
+	struct vhost_virtqueue vqs[2];
+	int backend;
+};
+
+int vhost_net_init(struct vhost_net *net,
+		   VLANClientState *backend);
+
+int vhost_net_start(struct vhost_net *net,
+		   VirtIODevice *dev);
+
+unsigned vhost_net_get_features(struct vhost_net *net);
+void vhost_net_ack_features(struct vhost_net *net, unsigned features);
+
+#endif
hw/virtio-net.c +56 -11

156 lines not on this page · raw message

hw/virtio-pci.c +40 -0
index 0716f6f..b7f073b 100644
@@ -15,11 +15,13 @@
 
 #include <inttypes.h>
 
+#include <linux/kvm.h>
 #include "virtio.h"
 #include "pci.h"
 #include "sysemu.h"
 #include "msix.h"
 #include "net.h"
+#include "qemu-kvm.h"
 
 /* from Linux's linux/virtio_pci.h */
 
@@ -199,6 +201,8 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         vdev->status = val & 0xFF;
         if (vdev->status == 0)
             virtio_pci_reset(&proxy->pci_dev.qdev);
+	if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && vdev->driver_ok)
+		vdev->driver_ok(vdev);
         break;
     case VIRTIO_MSI_CONFIG_VECTOR:
         msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
@@ -373,12 +377,48 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
     msix_write_config(pci_dev, address, val, len);
 }
 
+static int virtio_pci_irqfd(void * opaque, uint16_t vector, int fd)
+{
+    VirtIOPCIProxy *proxy = opaque;
+    struct kvm_irqfd call = { };
+    int r;
+
+    if (vector >= proxy->pci_dev.msix_entries_nr)
+        return -EINVAL;
+    if (!proxy->pci_dev.msix_entry_used[vector])
+        return -ENOENT;
+    call.fd = fd;
+    call.gsi = proxy->pci_dev.msix_irq_entries[vector].gsi;
+    r = kvm_vm_ioctl(kvm_state, KVM_IRQFD, &call);
+    if (r < 0)
+        return r;
+    return 0;
+}
+
+static int virtio_pci_queuefd(void * opaque, int n, int fd)
+{
+    VirtIOPCIProxy *proxy = opaque;
+    struct kvm_ioeventfd kick = {
+        .datamatch = n,
+        .addr = proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
+        .len = 2,
+        .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO,
+        .fd = fd,
+    };
+    int r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
+    if (r < 0)
+        return r;
+    return 0;
+}
+
 static const VirtIOBindings virtio_pci_bindings = {
     .notify = virtio_pci_notify,
     .save_config = virtio_pci_save_config,
     .load_config = virtio_pci_load_config,
     .save_queue = virtio_pci_save_queue,
     .load_queue = virtio_pci_load_queue,
+    .irqfd = virtio_pci_irqfd,
+    .queuefd = virtio_pci_queuefd,
 };
 
 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
hw/virtio.c +0 -19
index 337ff27..cc5c205 100644
@@ -54,24 +54,6 @@ typedef struct VRingUsed
     VRingUsedElem ring[0];
 } VRingUsed;
 
-typedef struct VRing
-{
-    unsigned int num;
-    target_phys_addr_t desc;
-    target_phys_addr_t avail;
-    target_phys_addr_t used;
-} VRing;
-
-struct VirtQueue
-{
-    VRing vring;
-    target_phys_addr_t pa;
-    uint16_t last_avail_idx;
-    int inuse;
-    uint16_t vector;
-    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
-};
-
 #define VIRTIO_PCI_QUEUE_MAX        16
 
 /* virt queue functions */
@@ -401,7 +383,6 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 
         sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i),
                                                &len, is_write);
-
         if (sg->iov_base == NULL || len != sg->iov_len) {
             fprintf(stderr, "virtio: trying to map MMIO memory\n");
             exit(1);
hw/virtio.h +25 -3
index 799e608..12792da 100644
@@ -54,15 +54,34 @@
 
 struct VirtQueue;
 
+typedef struct VRing
+{
+    unsigned int num;
+    target_phys_addr_t desc;
+    target_phys_addr_t avail;
+    target_phys_addr_t used;
+} VRing;
+
+typedef struct VirtQueue VirtQueue;
+struct VirtIODevice;
+typedef struct VirtIODevice VirtIODevice;
+
+struct VirtQueue
+{
+    VRing vring;
+    target_phys_addr_t pa;
+    uint16_t last_avail_idx;
+    int inuse;
+    uint16_t vector;
+    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
+};
+
 static inline target_phys_addr_t vring_align(target_phys_addr_t addr,
                                              unsigned long align)
 {
     return (addr + align - 1) & ~(align - 1);
 }
 
-typedef struct VirtQueue VirtQueue;
-typedef struct VirtIODevice VirtIODevice;
-
 #define VIRTQUEUE_MAX_SIZE 1024
 
 typedef struct VirtQueueElement
@@ -81,6 +100,8 @@ typedef struct {
     void (*save_queue)(void * opaque, int n, QEMUFile *f);
     int (*load_config)(void * opaque, QEMUFile *f);
     int (*load_queue)(void * opaque, int n, QEMUFile *f);
+    int (*irqfd)(void * opaque, uint16_t vector, int fd);
+    int (*queuefd)(void * opaque, int n, int fd);
 } VirtIOBindings;
 
 #define VIRTIO_PCI_QUEUE_MAX 16
@@ -104,6 +125,7 @@ struct VirtIODevice
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
+    void (*driver_ok)(VirtIODevice *vdev);
     VirtQueue *vq;
     const VirtIOBindings *binding;
     void *binding_opaque;
kvm/include/linux/vhost.h new file +126 -0

126 lines not on this page · raw message

net.c +7 -0
index 9168460..5d98e90 100644
@@ -2767,6 +2767,9 @@ static int net_init_nic(QemuOpts *opts, Monitor *mon)
     if (qemu_opt_get(opts, "addr")) {
         nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
     }
+    if (qemu_opt_get(opts, "vhost")) {
+        nd->vhost_device = qemu_opt_get_bool(opts, "vhost", 0);
+    }
 
     nd->macaddr[0] = 0x52;
     nd->macaddr[1] = 0x54;
@@ -3182,6 +3185,10 @@ static struct {
                 .name = "vectors",
                 .type = QEMU_OPT_NUMBER,
                 .help = "number of MSI-x vectors, 0 to disable MSI-X",
+            }, {
+                .name = "vhost",
+                .type = QEMU_OPT_BOOL,
+                .help = "enable vhost backend",
             },
             { /* end of list */ }
         },
net.h +1 -0
index 932b50d..adcd5c6 100644
@@ -115,6 +115,7 @@ struct NICInfo {
     int used;
     int bootable;
     int nvectors;
+    int vhost_device;
 };
 
 extern int nb_nics;
qemu-kvm.c +0 -8
index 62ca050..a547975 100644
@@ -150,14 +150,6 @@ static inline void clear_gsi(kvm_context_t kvm, unsigned int gsi)
         DPRINTF("Invalid GSI %d\n");
 }
 
-struct slot_info {
-    unsigned long phys_addr;
-    unsigned long len;
-    unsigned long userspace_addr;
-    unsigned flags;
-    int logging_count;
-};
-
 struct slot_info slots[KVM_MAX_NUM_MEM_REGIONS];
 
 static void init_slots(void)
qemu-kvm.h +9 -0
index d6748c7..2ab6c33 100644
@@ -1240,6 +1240,15 @@ int kvm_ioctl(KVMState *s, int type, ...);
 int kvm_vm_ioctl(KVMState *s, int type, ...);
 int kvm_check_extension(KVMState *s, unsigned int ext);
 
+struct slot_info {
+	unsigned long phys_addr;
+	unsigned long len;
+	unsigned long userspace_addr;
+	unsigned flags;
+	int logging_count;
+};
+
+extern struct slot_info slots[KVM_MAX_NUM_MEM_REGIONS];
 #endif
 
 #endif
Signature · 1 line
1.6.5.2.143.g8cc62
#17 lore raw

PATCH v4 3/6 qemu/net: add raw backend

In reply to a message not in the archive

Add raw network backend option which uses a packet socket to provide raw networking access. Once the socket is opened it's bound to a provided host interface, such that packets received on the interface are delivered to the VM and packets sent by the VM are sent to the interface.

This is functionally similar to the existing pcap network backend, with the same advantages and problems. Differences from pcap:
- can get an open socket from the monitor,
which allows running without NET_ADMIN priviledges
- support iovec sends with writev, saving one data copy
- one less dependency on an external library
- we have access to the underlying file descriptor
which makes it possible to connect to vhost net
- don't support polling all interfaces, always bind to a specific one

---
 hw/virtio-net.c |    3 +-
 net.c           |  192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx |    4 +
 3 files changed, 198 insertions(+), 1 deletions(-)
hw/virtio-net.c +2 -1
index 469c6e3..2e51a6a 100644
@@ -531,7 +531,8 @@ static ssize_t virtio_net_receive2(VLANClientState *vc, const uint8_t *buf, size
             virtqueue_pop(n->rx_vq, &elem) == 0) {
             if (i == 0)
                 return -1;
-            fprintf(stderr, "virtio-net truncating packet\n");
+            fprintf(stderr, "virtio-net truncating packet. offset %zd size %zd\n",
+		    offset, size);
             exit(1);
         }
 
net.c +192 -0

216 lines not on this page · raw message

qemu-options.hx +4 -0
index bde3e3f..0d5440f 100644
@@ -825,6 +825,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "                default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
 #endif
 #endif
+    "-net raw[,vlan=n][,name=str],ifname=name[,promisc=m]\n"
+    "                bound the host network interface to VLAN 'n' in a raw manner:\n"
+    "                packets received on the interface are delivered to the vlan and\n"
+    "                packets delivered on the vlan are sent to the interface\n"
     "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
     "                connect the vlan 'n' to another VLAN using a socket connection\n"
     "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
Signature · 1 line
1.6.5.2.143.g8cc62
author maintainer
#18 lore raw

PATCH v4 6/6 qemu-kvm: vhost-net implementation

In reply to a message not in the archive

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

This patchset is RFC, but works without issues for me.

TODO:
* migration support
* level triggered interrupts
* fix driver unloading/hotplug
* general cleanup and upstreaming

It still needs to be split up, tested and benchmarked properly, but posting it here in case people want to test drive the kernel bits I posted.

Some further info, performance etc:
http://www.linux-kvm.org/page/VhostNet

---
 Makefile.target           |    3 +-
 hw/vhost_net.c            |  251 +++++++++++++++++++++++++++++++++++++++++++++
 hw/vhost_net.h            |   38 +++++++
 hw/virtio-net.c           |   67 ++++++++++--
 hw/virtio-pci.c           |   40 +++++++
 hw/virtio.c               |   19 ----
 hw/virtio.h               |   28 +++++-
 kvm/include/linux/vhost.h |  126 +++++++++++++++++++++++
 net.c                     |    7 ++
 net.h                     |    1 +
 qemu-kvm.c                |    8 --
 qemu-kvm.h                |    9 ++
 12 files changed, 555 insertions(+), 42 deletions(-)
 create mode 100644 hw/vhost_net.c
 create mode 100644 hw/vhost_net.h
 create mode 100644 kvm/include/linux/vhost.h
Makefile.target +2 -1
index acee285..0d8e688 100644
@@ -160,7 +160,8 @@ obj-y = vl.o monitor.o pci.o isa_mmio.o machine.o \
         gdbstub.o gdbstub-xml.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
-obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o
+obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o \
+	vhost_net.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 # MSI-X depends on kvm for interrupt injection,
 # so moved it from Makefile.hw to Makefile.target for now
hw/vhost_net.c new file +251 -0

251 lines not on this page · raw message

hw/vhost_net.h new file +38 -0
new file mode 100644
index 0000000..65720e1
@@ -0,0 +1,38 @@
+#ifndef VHOST_NET_H
+#define VHOST_NET_H
+
+#include "hw/virtio.h"
+
+struct vhost_virtqueue {
+	int kick;
+	int call;
+	void *desc;
+	void *avail;
+	void *used;
+};
+
+struct vhost_dev {
+	int control;
+	struct vhost_virtqueue *vqs;
+	int nvqs;
+	unsigned long long features;
+	unsigned long long acked_features;
+	unsigned long long backend_features;
+};
+
+struct vhost_net {
+	struct vhost_dev dev;
+	struct vhost_virtqueue vqs[2];
+	int backend;
+};
+
+int vhost_net_init(struct vhost_net *net,
+		   VLANClientState *backend);
+
+int vhost_net_start(struct vhost_net *net,
+		   VirtIODevice *dev);
+
+unsigned vhost_net_get_features(struct vhost_net *net);
+void vhost_net_ack_features(struct vhost_net *net, unsigned features);
+
+#endif
hw/virtio-net.c +56 -11

156 lines not on this page · raw message

hw/virtio-pci.c +40 -0
index 0716f6f..b7f073b 100644
@@ -15,11 +15,13 @@
 
 #include <inttypes.h>
 
+#include <linux/kvm.h>
 #include "virtio.h"
 #include "pci.h"
 #include "sysemu.h"
 #include "msix.h"
 #include "net.h"
+#include "qemu-kvm.h"
 
 /* from Linux's linux/virtio_pci.h */
 
@@ -199,6 +201,8 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         vdev->status = val & 0xFF;
         if (vdev->status == 0)
             virtio_pci_reset(&proxy->pci_dev.qdev);
+	if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && vdev->driver_ok)
+		vdev->driver_ok(vdev);
         break;
     case VIRTIO_MSI_CONFIG_VECTOR:
         msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
@@ -373,12 +377,48 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
     msix_write_config(pci_dev, address, val, len);
 }
 
+static int virtio_pci_irqfd(void * opaque, uint16_t vector, int fd)
+{
+    VirtIOPCIProxy *proxy = opaque;
+    struct kvm_irqfd call = { };
+    int r;
+
+    if (vector >= proxy->pci_dev.msix_entries_nr)
+        return -EINVAL;
+    if (!proxy->pci_dev.msix_entry_used[vector])
+        return -ENOENT;
+    call.fd = fd;
+    call.gsi = proxy->pci_dev.msix_irq_entries[vector].gsi;
+    r = kvm_vm_ioctl(kvm_state, KVM_IRQFD, &call);
+    if (r < 0)
+        return r;
+    return 0;
+}
+
+static int virtio_pci_queuefd(void * opaque, int n, int fd)
+{
+    VirtIOPCIProxy *proxy = opaque;
+    struct kvm_ioeventfd kick = {
+        .datamatch = n,
+        .addr = proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
+        .len = 2,
+        .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO,
+        .fd = fd,
+    };
+    int r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
+    if (r < 0)
+        return r;
+    return 0;
+}
+
 static const VirtIOBindings virtio_pci_bindings = {
     .notify = virtio_pci_notify,
     .save_config = virtio_pci_save_config,
     .load_config = virtio_pci_load_config,
     .save_queue = virtio_pci_save_queue,
     .load_queue = virtio_pci_load_queue,
+    .irqfd = virtio_pci_irqfd,
+    .queuefd = virtio_pci_queuefd,
 };
 
 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
hw/virtio.c +0 -19
index 337ff27..cc5c205 100644
@@ -54,24 +54,6 @@ typedef struct VRingUsed
     VRingUsedElem ring[0];
 } VRingUsed;
 
-typedef struct VRing
-{
-    unsigned int num;
-    target_phys_addr_t desc;
-    target_phys_addr_t avail;
-    target_phys_addr_t used;
-} VRing;
-
-struct VirtQueue
-{
-    VRing vring;
-    target_phys_addr_t pa;
-    uint16_t last_avail_idx;
-    int inuse;
-    uint16_t vector;
-    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
-};
-
 #define VIRTIO_PCI_QUEUE_MAX        16
 
 /* virt queue functions */
@@ -401,7 +383,6 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 
         sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i),
                                                &len, is_write);
-
         if (sg->iov_base == NULL || len != sg->iov_len) {
             fprintf(stderr, "virtio: trying to map MMIO memory\n");
             exit(1);
hw/virtio.h +25 -3
index 799e608..12792da 100644
@@ -54,15 +54,34 @@
 
 struct VirtQueue;
 
+typedef struct VRing
+{
+    unsigned int num;
+    target_phys_addr_t desc;
+    target_phys_addr_t avail;
+    target_phys_addr_t used;
+} VRing;
+
+typedef struct VirtQueue VirtQueue;
+struct VirtIODevice;
+typedef struct VirtIODevice VirtIODevice;
+
+struct VirtQueue
+{
+    VRing vring;
+    target_phys_addr_t pa;
+    uint16_t last_avail_idx;
+    int inuse;
+    uint16_t vector;
+    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
+};
+
 static inline target_phys_addr_t vring_align(target_phys_addr_t addr,
                                              unsigned long align)
 {
     return (addr + align - 1) & ~(align - 1);
 }
 
-typedef struct VirtQueue VirtQueue;
-typedef struct VirtIODevice VirtIODevice;
-
 #define VIRTQUEUE_MAX_SIZE 1024
 
 typedef struct VirtQueueElement
@@ -81,6 +100,8 @@ typedef struct {
     void (*save_queue)(void * opaque, int n, QEMUFile *f);
     int (*load_config)(void * opaque, QEMUFile *f);
     int (*load_queue)(void * opaque, int n, QEMUFile *f);
+    int (*irqfd)(void * opaque, uint16_t vector, int fd);
+    int (*queuefd)(void * opaque, int n, int fd);
 } VirtIOBindings;
 
 #define VIRTIO_PCI_QUEUE_MAX 16
@@ -104,6 +125,7 @@ struct VirtIODevice
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
     void (*reset)(VirtIODevice *vdev);
+    void (*driver_ok)(VirtIODevice *vdev);
     VirtQueue *vq;
     const VirtIOBindings *binding;
     void *binding_opaque;
kvm/include/linux/vhost.h new file +126 -0

126 lines not on this page · raw message

net.c +7 -0
index 9168460..5d98e90 100644
@@ -2767,6 +2767,9 @@ static int net_init_nic(QemuOpts *opts, Monitor *mon)
     if (qemu_opt_get(opts, "addr")) {
         nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
     }
+    if (qemu_opt_get(opts, "vhost")) {
+        nd->vhost_device = qemu_opt_get_bool(opts, "vhost", 0);
+    }
 
     nd->macaddr[0] = 0x52;
     nd->macaddr[1] = 0x54;
@@ -3182,6 +3185,10 @@ static struct {
                 .name = "vectors",
                 .type = QEMU_OPT_NUMBER,
                 .help = "number of MSI-x vectors, 0 to disable MSI-X",
+            }, {
+                .name = "vhost",
+                .type = QEMU_OPT_BOOL,
+                .help = "enable vhost backend",
             },
             { /* end of list */ }
         },
net.h +1 -0
index 932b50d..adcd5c6 100644
@@ -115,6 +115,7 @@ struct NICInfo {
     int used;
     int bootable;
     int nvectors;
+    int vhost_device;
 };
 
 extern int nb_nics;
qemu-kvm.c +0 -8
index 62ca050..a547975 100644
@@ -150,14 +150,6 @@ static inline void clear_gsi(kvm_context_t kvm, unsigned int gsi)
         DPRINTF("Invalid GSI %d\n");
 }
 
-struct slot_info {
-    unsigned long phys_addr;
-    unsigned long len;
-    unsigned long userspace_addr;
-    unsigned flags;
-    int logging_count;
-};
-
 struct slot_info slots[KVM_MAX_NUM_MEM_REGIONS];
 
 static void init_slots(void)
qemu-kvm.h +9 -0
index d6748c7..2ab6c33 100644
@@ -1240,6 +1240,15 @@ int kvm_ioctl(KVMState *s, int type, ...);
 int kvm_vm_ioctl(KVMState *s, int type, ...);
 int kvm_check_extension(KVMState *s, unsigned int ext);
 
+struct slot_info {
+	unsigned long phys_addr;
+	unsigned long len;
+	unsigned long userspace_addr;
+	unsigned flags;
+	int logging_count;
+};
+
+extern struct slot_info slots[KVM_MAX_NUM_MEM_REGIONS];
 #endif
 
 #endif
Signature · 1 line
1.6.5.2.143.g8cc62
#19 lore raw

Re: [PATCHv4 6/6] qemu-kvm: vhost-net implementation

Quoted 16 lines · Michael S. Tsirkin

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Quoted 5 lines

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

As the vhost is a backend feature, i think the 'vhost' flag should be added to the -net tap or -net raw option rather than the -net nic which specifies the guest options.

Thanks
Sridhar

#20 lore raw

Re: [PATCHv4 6/6] qemu-kvm: vhost-net implementation

In reply to Michael S. Tsirkin
Quoted 16 lines · Michael S. Tsirkin

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Quoted 5 lines

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

As the vhost is a backend feature, i think the 'vhost' flag should be added to the -net tap or -net raw option rather than the -net nic which specifies the guest options.

Thanks
Sridhar

author maintainer
#21 lore raw

Re: [PATCHv4 6/6] qemu-kvm: vhost-net implementation

Quoted 27 lines · Sridhar Samudrala
Quoted 16 lines · Michael S. Tsirkin

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Quoted 5 lines

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

As the vhost is a backend feature, i think the 'vhost' flag should be added to the -net tap or -net raw option rather than the -net nic which specifies the guest options.

Quoted 2 lines

Thanks
Sridhar

Yes.

Signature · 1 line
MST
author maintainer
#22 lore raw

Re: [PATCHv4 6/6] qemu-kvm: vhost-net implementation

In reply to Sridhar Samudrala
Quoted 27 lines · Sridhar Samudrala
Quoted 16 lines · Michael S. Tsirkin

This adds support for vhost-net virtio kernel backend.

This patch is not intended to being merged yet.
I'm posting it for the benefit of people testing
the backend.

Usage instructions:
vhost currently requires MSI-X support in guest virtio. This means guests kernel version should be >= 2.6.31.

To enable vhost, simply add ",vhost" flag to nic options. Example with tap backend:
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net tap,ifname=msttap0,script=/home/mst/ifup,downscript=no \
-net nic,model=virtio,vhost

Quoted 5 lines

Example with raw socket backend:
ifconfig eth3 promisc
qemu-system-x86_64 -m 1G disk-c.qcow2 \
-net raw,ifname=eth3 \
-net nic,model=virtio,vhost

As the vhost is a backend feature, i think the 'vhost' flag should be added to the -net tap or -net raw option rather than the -net nic which specifies the guest options.

Quoted 2 lines

Thanks
Sridhar

Yes.

Signature · 1 line
MST