Blame qemu-virtio-add-features-as-qdev-properties.patch

Justin M. Forbes 272dfe
Add feature bits as properties to virtio. This makes it possible to e.g. define
Justin M. Forbes 272dfe
machine without indirect buffer support, which is required for 0.10
Justin M. Forbes 272dfe
compatibility, or without hardware checksum support, which is required for 0.11
Justin M. Forbes 272dfe
compatibility.  Since default values for optional features are now set by qdev,
Justin M. Forbes 272dfe
get_features callback has been modified: it sets non-optional bits, and clears
Justin M. Forbes 272dfe
bits not supported by host.
Justin M. Forbes 272dfe
Justin M. Forbes 272dfe
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Justin M. Forbes 272dfe
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Justin M. Forbes 272dfe
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Justin M. Forbes 272dfe
(cherry picked from commit 8172539d21a03e982aa7f139ddc1607dc1422045)
Justin M. Forbes 272dfe
---
Justin M. Forbes 272dfe
 hw/s390-virtio-bus.c |   12 +++++++++---
Justin M. Forbes 272dfe
 hw/s390-virtio-bus.h |    1 +
Justin M. Forbes 272dfe
 hw/syborg_virtio.c   |   13 ++++++++-----
Justin M. Forbes 272dfe
 hw/virtio-balloon.c  |    4 ++--
Justin M. Forbes 272dfe
 hw/virtio-blk.c      |    6 +-----
Justin M. Forbes 272dfe
 hw/virtio-blk.h      |    8 ++++++++
Justin M. Forbes 272dfe
 hw/virtio-net.c      |   39 ++++++++++++++++-----------------------
Justin M. Forbes 272dfe
 hw/virtio-net.h      |   20 ++++++++++++++++++++
Justin M. Forbes 272dfe
 hw/virtio-pci.c      |   25 +++++++++++++++++--------
Justin M. Forbes 272dfe
 hw/virtio.c          |    2 +-
Justin M. Forbes 272dfe
 hw/virtio.h          |    7 ++++++-
Justin M. Forbes 272dfe
 12 files changed, 91 insertions(+), 50 deletions(-)
Justin M. Forbes 272dfe
Justin M. Forbes 272dfe
--- a/hw/s390-virtio-bus.c	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/s390-virtio-bus.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -101,6 +101,7 @@ static int s390_virtio_device_init(VirtI
Justin M. Forbes 272dfe
     bus->dev_offs += dev_len;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     virtio_bind_device(vdev, &virtio_s390_bindings, dev);
Justin M. Forbes 272dfe
+    dev->host_features = vdev->get_features(vdev, dev->host_features);
Justin M. Forbes 272dfe
     s390_virtio_device_sync(dev);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     return 0;
Justin M. Forbes 272dfe
@@ -222,9 +223,7 @@ static void s390_virtio_device_sync(Virt
Justin M. Forbes 272dfe
     cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     /* Sync feature bitmap */
Justin M. Forbes 272dfe
-    if (dev->vdev->get_features) {
Justin M. Forbes 272dfe
-        stl_phys(cur_offs, dev->vdev->get_features(dev->vdev));
Justin M. Forbes 272dfe
-    }
Justin M. Forbes 272dfe
+    stl_phys(cur_offs, dev->host_features);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     dev->feat_offs = cur_offs + dev->feat_len;
Justin M. Forbes 272dfe
     cur_offs += dev->feat_len * 2;
Justin M. Forbes 272dfe
@@ -310,10 +309,17 @@ static void virtio_s390_notify(void *opa
Justin M. Forbes 272dfe
     kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+static unsigned virtio_s390_get_features(void *opaque)
Justin M. Forbes 272dfe
+{
Justin M. Forbes 272dfe
+    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
Justin M. Forbes 272dfe
+    return dev->host_features;
Justin M. Forbes 272dfe
+}
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
 /**************** S390 Virtio Bus Device Descriptions *******************/
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static const VirtIOBindings virtio_s390_bindings = {
Justin M. Forbes 272dfe
     .notify = virtio_s390_notify,
Justin M. Forbes 272dfe
+    .get_features = virtio_s390_get_features,
Justin M. Forbes 272dfe
 };
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static VirtIOS390DeviceInfo s390_virtio_net = {
Justin M. Forbes 272dfe
--- a/hw/s390-virtio-bus.h	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/s390-virtio-bus.h	2010-02-09 00:18:16.000000000 -0600
Justin M. Forbes 272dfe
@@ -40,6 +40,7 @@ typedef struct VirtIOS390Device {
Justin M. Forbes 272dfe
     VirtIODevice *vdev;
Justin M. Forbes 272dfe
     DriveInfo *dinfo;
Justin M. Forbes 272dfe
     NICConf nic;
Justin M. Forbes 272dfe
+    uint32_t host_features;
Justin M. Forbes 272dfe
     /* Max. number of ports we can have for a the virtio-serial device */
Justin M. Forbes 272dfe
     uint32_t max_virtserial_ports;
Justin M. Forbes 272dfe
 } VirtIOS390Device;
Justin M. Forbes 272dfe
--- a/hw/syborg_virtio.c	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/syborg_virtio.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -25,6 +25,7 @@
Justin M. Forbes 272dfe
 #include "syborg.h"
Justin M. Forbes 272dfe
 #include "sysbus.h"
Justin M. Forbes 272dfe
 #include "virtio.h"
Justin M. Forbes 272dfe
+#include "virtio-net.h"
Justin M. Forbes 272dfe
 #include "sysemu.h"
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 //#define DEBUG_SYBORG_VIRTIO
Justin M. Forbes 272dfe
@@ -66,6 +67,7 @@ typedef struct {
Justin M. Forbes 272dfe
     uint32_t int_enable;
Justin M. Forbes 272dfe
     uint32_t id;
Justin M. Forbes 272dfe
     NICConf nic;
Justin M. Forbes 272dfe
+    uint32_t host_features;
Justin M. Forbes 272dfe
 } SyborgVirtIOProxy;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
Justin M. Forbes 272dfe
@@ -86,8 +88,7 @@ static uint32_t syborg_virtio_readl(void
Justin M. Forbes 272dfe
         ret = s->id;
Justin M. Forbes 272dfe
         break;
Justin M. Forbes 272dfe
     case SYBORG_VIRTIO_HOST_FEATURES:
Justin M. Forbes 272dfe
-        ret = vdev->get_features(vdev);
Justin M. Forbes 272dfe
-        ret |= vdev->binding->get_features(s);
Justin M. Forbes 272dfe
+        ret = s->host_features;
Justin M. Forbes 272dfe
         break;
Justin M. Forbes 272dfe
     case SYBORG_VIRTIO_GUEST_FEATURES:
Justin M. Forbes 272dfe
         ret = vdev->guest_features;
Justin M. Forbes 272dfe
@@ -244,9 +245,8 @@ static void syborg_virtio_update_irq(voi
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static unsigned syborg_virtio_get_features(void *opaque)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
-    unsigned ret = 0;
Justin M. Forbes 272dfe
-    ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
Justin M. Forbes 272dfe
-    return ret;
Justin M. Forbes 272dfe
+    SyborgVirtIOProxy *proxy = opaque;
Justin M. Forbes 272dfe
+    return proxy->host_features;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static VirtIOBindings syborg_virtio_bindings = {
Justin M. Forbes 272dfe
@@ -272,6 +272,8 @@ static int syborg_virtio_init(SyborgVirt
Justin M. Forbes 272dfe
     qemu_register_reset(virtio_reset, vdev);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
Justin M. Forbes 272dfe
+    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
Justin M. Forbes 272dfe
+    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
Justin M. Forbes 272dfe
     return 0;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
@@ -292,6 +294,7 @@ static SysBusDeviceInfo syborg_virtio_ne
Justin M. Forbes 272dfe
     .qdev.size  = sizeof(SyborgVirtIOProxy),
Justin M. Forbes 272dfe
     .qdev.props = (Property[]) {
Justin M. Forbes 272dfe
         DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
Justin M. Forbes 272dfe
+        DEFINE_VIRTIO_NET_FEATURES(SyborgVirtIOProxy, host_features),
Justin M. Forbes 272dfe
         DEFINE_PROP_END_OF_LIST(),
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
 };
Justin M. Forbes 272dfe
--- a/hw/virtio-balloon.c	2010-01-18 12:48:25.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-balloon.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -125,9 +125,9 @@ static void virtio_balloon_set_config(Vi
Justin M. Forbes 272dfe
     dev->actual = config.actual;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
-static uint32_t virtio_balloon_get_features(VirtIODevice *vdev)
Justin M. Forbes 272dfe
+static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
-    return 0;
Justin M. Forbes 272dfe
+    return f;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static ram_addr_t virtio_balloon_to_target(void *opaque, ram_addr_t target)
Justin M. Forbes 272dfe
--- a/hw/virtio-blk.c	2010-01-18 12:48:25.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-blk.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -432,19 +432,15 @@ static void virtio_blk_update_config(Vir
Justin M. Forbes 272dfe
     memcpy(config, &blkcfg, s->config_size);
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
-static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
Justin M. Forbes 272dfe
+static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
     VirtIOBlock *s = to_virtio_blk(vdev);
Justin M. Forbes 272dfe
-    uint32_t features = 0;
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     features |= (1 << VIRTIO_BLK_F_SEG_MAX);
Justin M. Forbes 272dfe
     features |= (1 << VIRTIO_BLK_F_GEOMETRY);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     if (bdrv_enable_write_cache(s->bs))
Justin M. Forbes 272dfe
         features |= (1 << VIRTIO_BLK_F_WCACHE);
Justin M. Forbes 272dfe
-#ifdef __linux__
Justin M. Forbes 272dfe
-    features |= (1 << VIRTIO_BLK_F_SCSI);
Justin M. Forbes 272dfe
-#endif
Justin M. Forbes 272dfe
     if (strcmp(s->serial_str, "0"))
Justin M. Forbes 272dfe
         features |= 1 << VIRTIO_BLK_F_IDENTIFY;
Justin M. Forbes 272dfe
     
Justin M. Forbes 272dfe
--- a/hw/virtio-blk.h	2010-01-18 12:48:25.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-blk.h	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -92,4 +92,12 @@ struct virtio_scsi_inhdr
Justin M. Forbes 272dfe
     uint32_t residual;
Justin M. Forbes 272dfe
 };
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+#ifdef __linux__
Justin M. Forbes 272dfe
+#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
Justin M. Forbes 272dfe
+        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("scsi", _state, _field, VIRTIO_BLK_F_SCSI, true)
Justin M. Forbes 272dfe
+#else
Justin M. Forbes 272dfe
+#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
Justin M. Forbes 272dfe
+        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field)
Justin M. Forbes 272dfe
+#endif
Justin M. Forbes 272dfe
 #endif
Justin M. Forbes 272dfe
--- a/hw/virtio.c	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -650,7 +650,7 @@ int virtio_load(VirtIODevice *vdev, QEMU
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
     int num, i, ret;
Justin M. Forbes 272dfe
     uint32_t features;
Justin M. Forbes 272dfe
-    uint32_t supported_features = vdev->get_features(vdev) |
Justin M. Forbes 272dfe
+    uint32_t supported_features =
Justin M. Forbes 272dfe
         vdev->binding->get_features(vdev->binding_opaque);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     if (vdev->binding->load_config) {
Justin M. Forbes 272dfe
--- a/hw/virtio.h	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ bhw/virtio.h	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -105,7 +105,7 @@ struct VirtIODevice
Justin M. Forbes 272dfe
     void *config;
Justin M. Forbes 272dfe
     uint16_t config_vector;
Justin M. Forbes 272dfe
     int nvectors;
Justin M. Forbes 272dfe
-    uint32_t (*get_features)(VirtIODevice *vdev);
Justin M. Forbes 272dfe
+    uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
Justin M. Forbes 272dfe
     uint32_t (*bad_features)(VirtIODevice *vdev);
Justin M. Forbes 272dfe
     void (*set_features)(VirtIODevice *vdev, uint32_t val);
Justin M. Forbes 272dfe
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
Justin M. Forbes 272dfe
@@ -176,4 +176,9 @@ VirtIODevice *virtio_balloon_init(Device
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 void virtio_net_exit(VirtIODevice *vdev);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
Justin M. Forbes 272dfe
+	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
Justin M. Forbes 272dfe
+			VIRTIO_RING_F_INDIRECT_DESC, true)
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
 #endif
Justin M. Forbes 272dfe
--- a/hw/virtio-net.c	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-net.c	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -147,34 +147,27 @@ static int peer_has_ufo(VirtIONet *n)
Justin M. Forbes 272dfe
     return n->has_ufo;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
-static uint32_t virtio_net_get_features(VirtIODevice *vdev)
Justin M. Forbes 272dfe
+static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
     VirtIONet *n = to_virtio_net(vdev);
Justin M. Forbes 272dfe
-    uint32_t features = (1 << VIRTIO_NET_F_MAC) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_MRG_RXBUF) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_STATUS) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_CTRL_VQ) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_CTRL_RX) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_CTRL_VLAN) |
Justin M. Forbes 272dfe
-                        (1 << VIRTIO_NET_F_CTRL_RX_EXTRA);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     if (peer_has_vnet_hdr(n)) {
Justin M. Forbes 272dfe
         tap_using_vnet_hdr(n->nic->nc.peer, 1);
Justin M. Forbes 272dfe
+    } else {
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_CSUM);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
Justin M. Forbes 272dfe
+
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
Justin M. Forbes 272dfe
+    }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_CSUM);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_HOST_TSO4);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_HOST_TSO6);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_HOST_ECN);
Justin M. Forbes 272dfe
-
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
Justin M. Forbes 272dfe
-        features |= (1 << VIRTIO_NET_F_GUEST_ECN);
Justin M. Forbes 272dfe
-
Justin M. Forbes 272dfe
-        if (peer_has_ufo(n)) {
Justin M. Forbes 272dfe
-            features |= (1 << VIRTIO_NET_F_GUEST_UFO);
Justin M. Forbes 272dfe
-            features |= (1 << VIRTIO_NET_F_HOST_UFO);
Justin M. Forbes 272dfe
-        }
Justin M. Forbes 272dfe
+    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
Justin M. Forbes 272dfe
+        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
Justin M. Forbes 272dfe
     }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     return features;
Justin M. Forbes 272dfe
@@ -192,7 +185,7 @@ static uint32_t virtio_net_bad_features(
Justin M. Forbes 272dfe
     features |= (1 << VIRTIO_NET_F_HOST_TSO6);
Justin M. Forbes 272dfe
     features |= (1 << VIRTIO_NET_F_HOST_ECN);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
-    return features & virtio_net_get_features(vdev);
Justin M. Forbes 272dfe
+    return features;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
Justin M. Forbes 272dfe
--- a/hw/virtio-net.h	2010-01-18 12:48:25.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-net.h	2010-02-09 00:02:12.000000000 -0600
Justin M. Forbes 272dfe
@@ -153,4 +153,24 @@ struct virtio_net_ctrl_mac {
Justin M. Forbes 272dfe
  #define VIRTIO_NET_CTRL_VLAN_ADD             0
Justin M. Forbes 272dfe
  #define VIRTIO_NET_CTRL_VLAN_DEL             1
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
+#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
Justin M. Forbes 272dfe
+        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("mac", _state, _field, VIRTIO_NET_F_MAC, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
Justin M. Forbes 272dfe
+        DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true)
Justin M. Forbes 272dfe
 #endif
Justin M. Forbes 272dfe
--- a/hw/virtio-pci.c	2010-02-09 00:18:58.000000000 -0600
Justin M. Forbes 272dfe
+++ b/hw/virtio-pci.c	2010-02-09 00:16:13.000000000 -0600
Justin M. Forbes 272dfe
@@ -16,6 +16,8 @@
Justin M. Forbes 272dfe
 #include <inttypes.h>
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 #include "virtio.h"
Justin M. Forbes 272dfe
+#include "virtio-blk.h"
Justin M. Forbes 272dfe
+#include "virtio-net.h"
Justin M. Forbes 272dfe
 #include "pci.h"
Justin M. Forbes 272dfe
 #include "sysemu.h"
Justin M. Forbes 272dfe
 #include "msix.h"
Justin M. Forbes 272dfe
@@ -92,6 +94,7 @@ typedef struct {
Justin M. Forbes 272dfe
     uint32_t nvectors;
Justin M. Forbes 272dfe
     DriveInfo *dinfo;
Justin M. Forbes 272dfe
     NICConf nic;
Justin M. Forbes 272dfe
+    uint32_t host_features;
Justin M. Forbes 272dfe
     /* Max. number of ports we can have for a the virtio-serial device */
Justin M. Forbes 272dfe
     uint32_t max_virtserial_ports;
Justin M. Forbes 272dfe
 } VirtIOPCIProxy;
Justin M. Forbes 272dfe
@@ -177,7 +180,7 @@ static void virtio_ioport_write(void *op
Justin M. Forbes 272dfe
 	/* Guest does not negotiate properly?  We have to assume nothing. */
Justin M. Forbes 272dfe
 	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
Justin M. Forbes 272dfe
 	    if (vdev->bad_features)
Justin M. Forbes 272dfe
-		val = vdev->bad_features(vdev);
Justin M. Forbes 272dfe
+		val = proxy->host_features & vdev->bad_features(vdev);
Justin M. Forbes 272dfe
 	    else
Justin M. Forbes 272dfe
 		val = 0;
Justin M. Forbes 272dfe
 	}
Justin M. Forbes 272dfe
@@ -237,8 +240,7 @@ static uint32_t virtio_ioport_read(VirtI
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     switch (addr) {
Justin M. Forbes 272dfe
     case VIRTIO_PCI_HOST_FEATURES:
Justin M. Forbes 272dfe
-        ret = vdev->get_features(vdev);
Justin M. Forbes 272dfe
-        ret |= vdev->binding->get_features(proxy);
Justin M. Forbes 272dfe
+        ret = proxy->host_features;
Justin M. Forbes 272dfe
         break;
Justin M. Forbes 272dfe
     case VIRTIO_PCI_GUEST_FEATURES:
Justin M. Forbes 272dfe
         ret = vdev->guest_features;
Justin M. Forbes 272dfe
@@ -384,11 +386,8 @@ static void virtio_write_config(PCIDevic
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static unsigned virtio_pci_get_features(void *opaque)
Justin M. Forbes 272dfe
 {
Justin M. Forbes 272dfe
-    unsigned ret = 0;
Justin M. Forbes 272dfe
-    ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
Justin M. Forbes 272dfe
-    ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
Justin M. Forbes 272dfe
-    ret |= (1 << VIRTIO_F_BAD_FEATURE);
Justin M. Forbes 272dfe
-    return ret;
Justin M. Forbes 272dfe
+    VirtIOPCIProxy *proxy = opaque;
Justin M. Forbes 272dfe
+    return proxy->host_features;
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static const VirtIOBindings virtio_pci_bindings = {
Justin M. Forbes 272dfe
@@ -444,6 +443,9 @@ static void virtio_init_pci(VirtIOPCIPro
Justin M. Forbes 272dfe
                            virtio_map);
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
     virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
Justin M. Forbes 272dfe
+    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
Justin M. Forbes 272dfe
+    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
Justin M. Forbes 272dfe
+    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
Justin M. Forbes 272dfe
 }
Justin M. Forbes 272dfe
 
Justin M. Forbes 272dfe
 static int virtio_blk_init_pci(PCIDevice *pci_dev)
Justin M. Forbes 272dfe
@@ -558,6 +560,7 @@ static PCIDeviceInfo virtio_info[] = {
Justin M. Forbes 272dfe
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
Justin M. Forbes 272dfe
             DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo),
Justin M. Forbes 272dfe
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
Justin M. Forbes 272dfe
+            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
Justin M. Forbes 272dfe
             DEFINE_PROP_END_OF_LIST(),
Justin M. Forbes 272dfe
         },
Justin M. Forbes 272dfe
         .qdev.reset = virtio_pci_reset,
Justin M. Forbes 272dfe
@@ -569,6 +572,7 @@ static PCIDeviceInfo virtio_info[] = {
Justin M. Forbes 272dfe
         .romfile    = "pxe-virtio.bin",
Justin M. Forbes 272dfe
         .qdev.props = (Property[]) {
Justin M. Forbes 272dfe
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
Justin M. Forbes 272dfe
+            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
Justin M. Forbes 272dfe
             DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
Justin M. Forbes 272dfe
             DEFINE_PROP_END_OF_LIST(),
Justin M. Forbes 272dfe
         },
Justin M. Forbes 272dfe
@@ -582,6 +586,7 @@ static PCIDeviceInfo virtio_info[] = {
Justin M. Forbes 272dfe
         .qdev.props = (Property[]) {
Justin M. Forbes 272dfe
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 0),
Justin M. Forbes 272dfe
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
Justin M. Forbes 272dfe
+            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
Justin M. Forbes 272dfe
             DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
Justin M. Forbes 272dfe
                                31),
Justin M. Forbes 272dfe
             DEFINE_PROP_END_OF_LIST(),
Justin M. Forbes 272dfe
@@ -592,6 +597,10 @@ static PCIDeviceInfo virtio_info[] = {
Justin M. Forbes 272dfe
         .qdev.size = sizeof(VirtIOPCIProxy),
Justin M. Forbes 272dfe
         .init      = virtio_balloon_init_pci,
Justin M. Forbes 272dfe
         .exit      = virtio_exit_pci,
Justin M. Forbes 272dfe
+        .qdev.props = (Property[]) {
Justin M. Forbes 272dfe
+            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
Justin M. Forbes 272dfe
+            DEFINE_PROP_END_OF_LIST(),
Justin M. Forbes 272dfe
+        },
Justin M. Forbes 272dfe
         .qdev.reset = virtio_pci_reset,
Justin M. Forbes 272dfe
     },{
Justin M. Forbes 272dfe
         /* end of list */