summary refs log tree commit diff stats
path: root/hw/virtio.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2009-12-08 20:07:48 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-12-12 07:59:38 -0600
commit6d74ca5aa83b83fb52332f7735c61ecb7a5328c1 (patch)
tree6ea05e57ca0165275eda7e6d57cecd5fd52757b6 /hw/virtio.c
parentb3c3f123f785fb861d930080f083507b51f5ce79 (diff)
downloadfocaccia-qemu-6d74ca5aa83b83fb52332f7735c61ecb7a5328c1.tar.gz
focaccia-qemu-6d74ca5aa83b83fb52332f7735c61ecb7a5328c1.zip
virtio: verify features on load
migrating between hosts which have different features
might break silently, if the migration destination
does not support some features supported by source.

Prevent this from happening by comparing acked feature
bits with the mask supported by the device.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/virtio.c')
-rw-r--r--hw/virtio.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/hw/virtio.c b/hw/virtio.c
index 1f92171f68..cecd0dc042 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -651,6 +651,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
 int virtio_load(VirtIODevice *vdev, QEMUFile *f)
 {
     int num, i, ret;
+    uint32_t features;
+    uint32_t supported_features = vdev->get_features(vdev) |
+        vdev->binding->get_features(vdev->binding_opaque);
 
     if (vdev->binding->load_config) {
         ret = vdev->binding->load_config(vdev->binding_opaque, f);
@@ -661,7 +664,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
     qemu_get_8s(f, &vdev->status);
     qemu_get_8s(f, &vdev->isr);
     qemu_get_be16s(f, &vdev->queue_sel);
-    qemu_get_be32s(f, &vdev->features);
+    qemu_get_be32s(f, &features);
+    if (features & ~supported_features) {
+        fprintf(stderr, "Features 0x%x unsupported. Allowed features: 0x%x\n",
+                features, supported_features);
+        return -1;
+    }
+    vdev->features = features;
     vdev->config_len = qemu_get_be32(f);
     qemu_get_buffer(f, vdev->config, vdev->config_len);