|
@@ -763,12 +763,25 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int virtio_set_features(VirtIODevice *vdev, uint32_t val)
|
|
|
+{
|
|
|
+ uint32_t supported_features =
|
|
|
+ vdev->binding->get_features(vdev->binding_opaque);
|
|
|
+ bool bad = (val & ~supported_features) != 0;
|
|
|
+
|
|
|
+ val &= supported_features;
|
|
|
+ if (vdev->set_features) {
|
|
|
+ vdev->set_features(vdev, val);
|
|
|
+ }
|
|
|
+ vdev->guest_features = val;
|
|
|
+ return bad ? -1 : 0;
|
|
|
+}
|
|
|
+
|
|
|
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
|
|
{
|
|
|
int num, i, ret;
|
|
|
uint32_t features;
|
|
|
- uint32_t supported_features =
|
|
|
- vdev->binding->get_features(vdev->binding_opaque);
|
|
|
+ uint32_t supported_features;
|
|
|
|
|
|
if (vdev->binding->load_config) {
|
|
|
ret = vdev->binding->load_config(vdev->binding_opaque, f);
|
|
@@ -780,14 +793,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
|
|
qemu_get_8s(f, &vdev->isr);
|
|
|
qemu_get_be16s(f, &vdev->queue_sel);
|
|
|
qemu_get_be32s(f, &features);
|
|
|
- if (features & ~supported_features) {
|
|
|
+
|
|
|
+ if (virtio_set_features(vdev, features) < 0) {
|
|
|
+ supported_features = vdev->binding->get_features(vdev->binding_opaque);
|
|
|
error_report("Features 0x%x unsupported. Allowed features: 0x%x",
|
|
|
features, supported_features);
|
|
|
return -1;
|
|
|
}
|
|
|
- if (vdev->set_features)
|
|
|
- vdev->set_features(vdev, features);
|
|
|
- vdev->guest_features = features;
|
|
|
vdev->config_len = qemu_get_be32(f);
|
|
|
qemu_get_buffer(f, vdev->config, vdev->config_len);
|
|
|
|