aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 17:40:08 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-05 17:40:08 +0000
commit8eca6b1bc770982595db2f7207c65051572436cb (patch)
tree68ca13c0ea9c46ed473bf67aa9cb4e8d525d317c /hw/virtio.c
parent1da92db280961b3949712609b8771f582dab1f4a (diff)
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
Diffstat (limited to 'hw/virtio.c')
-rw-r--r--hw/virtio.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/hw/virtio.c b/hw/virtio.c
index 8a72d8d216..93a7de6899 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -451,6 +451,13 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
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 @@ static uint32_t virtio_ioport_read(void *opaque, 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_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);
break;
case VIRTIO_PCI_GUEST_FEATURES:
ret = vdev->features;