Revision ad0c9332

b/hw/s390-virtio-bus.c
254 254
    /* Update guest supported feature bitmap */
255 255

  
256 256
    features = bswap32(ldl_be_phys(dev->feat_offs));
257
    if (vdev->set_features) {
258
        vdev->set_features(vdev, features);
259
    }
260
    vdev->guest_features = features;
257
    virtio_set_features(vdev, features);
261 258
}
262 259

  
263 260
VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
b/hw/syborg_virtio.c
131 131
    }
132 132
    switch (offset >> 2) {
133 133
    case SYBORG_VIRTIO_GUEST_FEATURES:
134
        if (vdev->set_features)
135
            vdev->set_features(vdev, value);
136
        vdev->guest_features = value;
134
        virtio_set_features(vdev, value);
137 135
        break;
138 136
    case SYBORG_VIRTIO_QUEUE_BASE:
139 137
        if (value == 0)
b/hw/virtio-pci.c
285 285
    case VIRTIO_PCI_GUEST_FEATURES:
286 286
	/* Guest does not negotiate properly?  We have to assume nothing. */
287 287
	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
288
	    if (vdev->bad_features)
289
		val = proxy->host_features & vdev->bad_features(vdev);
290
	    else
291
		val = 0;
288
            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
292 289
	}
293
        if (vdev->set_features)
294
            vdev->set_features(vdev, val);
295
        vdev->guest_features = val;
290
        virtio_set_features(vdev, val);
296 291
        break;
297 292
    case VIRTIO_PCI_QUEUE_PFN:
298 293
        pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
b/hw/virtio.c
763 763
    }
764 764
}
765 765

  
766
int virtio_set_features(VirtIODevice *vdev, uint32_t val)
767
{
768
    uint32_t supported_features =
769
        vdev->binding->get_features(vdev->binding_opaque);
770
    bool bad = (val & ~supported_features) != 0;
771

  
772
    val &= supported_features;
773
    if (vdev->set_features) {
774
        vdev->set_features(vdev, val);
775
    }
776
    vdev->guest_features = val;
777
    return bad ? -1 : 0;
778
}
779

  
766 780
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
767 781
{
768 782
    int num, i, ret;
769 783
    uint32_t features;
770
    uint32_t supported_features =
771
        vdev->binding->get_features(vdev->binding_opaque);
784
    uint32_t supported_features;
772 785

  
773 786
    if (vdev->binding->load_config) {
774 787
        ret = vdev->binding->load_config(vdev->binding_opaque, f);
......
780 793
    qemu_get_8s(f, &vdev->isr);
781 794
    qemu_get_be16s(f, &vdev->queue_sel);
782 795
    qemu_get_be32s(f, &features);
783
    if (features & ~supported_features) {
796

  
797
    if (virtio_set_features(vdev, features) < 0) {
798
        supported_features = vdev->binding->get_features(vdev->binding_opaque);
784 799
        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
785 800
                     features, supported_features);
786 801
        return -1;
787 802
    }
788
    if (vdev->set_features)
789
        vdev->set_features(vdev, features);
790
    vdev->guest_features = features;
791 803
    vdev->config_len = qemu_get_be32(f);
792 804
    qemu_get_buffer(f, vdev->config, vdev->config_len);
793 805

  
b/hw/virtio.h
185 185
void virtio_set_status(VirtIODevice *vdev, uint8_t val);
186 186
void virtio_reset(void *opaque);
187 187
void virtio_update_irq(VirtIODevice *vdev);
188
int virtio_set_features(VirtIODevice *vdev, uint32_t val);
188 189

  
189 190
void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
190 191
                        void *opaque);

Also available in: Unified diff