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