qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [6975] Fix oops on 2.6.25 guest (Rusty Russell)
Date: Sun, 05 Apr 2009 17:40:14 +0000	[thread overview]
Message-ID: <E1LqWKL-00065U-R2@cvs.savannah.gnu.org> (raw)

Revision: 6975
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6975
Author:   aliguori
Date:     2009-04-05 17:40:08 +0000 (Sun, 05 Apr 2009)
Log Message:
-----------
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>

Modified Paths:
--------------
    trunk/hw/virtio-net.c
    trunk/hw/virtio.c
    trunk/hw/virtio.h

Modified: trunk/hw/virtio-net.c
===================================================================
--- trunk/hw/virtio-net.c	2009-04-04 19:10:26 UTC (rev 6974)
+++ trunk/hw/virtio-net.c	2009-04-05 17:40:08 UTC (rev 6975)
@@ -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);

Modified: trunk/hw/virtio.c
===================================================================
--- trunk/hw/virtio.c	2009-04-04 19:10:26 UTC (rev 6974)
+++ trunk/hw/virtio.c	2009-04-05 17:40:08 UTC (rev 6975)
@@ -451,6 +451,13 @@
 
     switch (addr) {
     case VIRTIO_PCI_GUEST_FEATURES:
+	/* Guest does not negotiate properly?  We have to assume nothing. */
+	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
+	    if (vdev->bad_features)
+		val = vdev->bad_features(vdev);
+	    else
+		val = 0;
+	}
         if (vdev->set_features)
             vdev->set_features(vdev, val);
         vdev->features = val;
@@ -490,7 +497,7 @@
     switch (addr) {
     case VIRTIO_PCI_HOST_FEATURES:
         ret = vdev->get_features(vdev);
-        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);
         break;
     case VIRTIO_PCI_GUEST_FEATURES:
         ret = vdev->features;

Modified: trunk/hw/virtio.h
===================================================================
--- trunk/hw/virtio.h	2009-04-04 19:10:26 UTC (rev 6974)
+++ trunk/hw/virtio.h	2009-04-05 17:40:08 UTC (rev 6975)
@@ -32,6 +32,8 @@
 /* We notify when the ring is completely used, even if the guest is supressing
  * callbacks */
 #define VIRTIO_F_NOTIFY_ON_EMPTY        24
+/* A guest should never accept this.  It implies negotiation is broken. */
+#define VIRTIO_F_BAD_FEATURE		30
 
 /* from Linux's linux/virtio_ring.h */
 
@@ -82,6 +84,7 @@
     size_t config_len;
     void *config;
     uint32_t (*get_features)(VirtIODevice *vdev);
+    uint32_t (*bad_features)(VirtIODevice *vdev);
     void (*set_features)(VirtIODevice *vdev, uint32_t val);
     void (*get_config)(VirtIODevice *vdev, uint8_t *config);
     void (*set_config)(VirtIODevice *vdev, const uint8_t *config);

                 reply	other threads:[~2009-04-05 17:40 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1LqWKL-00065U-R2@cvs.savannah.gnu.org \
    --to=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).