/* QEMU doesn't strictly need write barriers since everything runs in
* lock-step. We'll leave the calls to wmb() in though to make it obvious for
* KVM or if kqemu gets SMP support.
+ * In any case, we must prevent the compiler from reordering the code.
+ * TODO: we likely need some rmb()/mb() as well.
*/
-#define wmb() do { } while (0)
+
+#define wmb() __asm__ __volatile__("": : :"memory")
typedef struct VRingDesc
{
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);
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);