Fix oops on 2.6.25 guest (Rusty Russell)

I believe this is behind the following:
https://bugs.edge.launchpad.net/ubuntu/jaunty/+source/linux/+bug/331128

virtio_pci in 2.6.25 didn't do feature negotiation correctly: it acked every
bit.  Fortunately, we can detect this.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6975 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index ad55bb7..ae9b7d9 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -113,6 +113,21 @@
     return features;
 }
 
+static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
+{
+    uint32_t features = 0;
+
+    /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
+     * but also these: */
+    features |= (1 << VIRTIO_NET_F_MAC);
+    features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
+    features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
+    features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
+    features |= (1 << VIRTIO_NET_F_GUEST_ECN);
+
+    return features & virtio_net_get_features(vdev);
+}
+
 static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIONet *n = to_virtio_net(vdev);
@@ -580,6 +595,7 @@
     n->vdev.set_config = virtio_net_set_config;
     n->vdev.get_features = virtio_net_get_features;
     n->vdev.set_features = virtio_net_set_features;
+    n->vdev.bad_features = virtio_net_bad_features;
     n->vdev.reset = virtio_net_reset;
     n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
     n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);