diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-03-23 11:04:56 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-03-23 11:04:56 +0000 |
commit | 2077cabcac3e052af320cd93522467c2c5861c76 (patch) | |
tree | e1dd3fde3ef80239205cd2e30952d4aa6091f4ef | |
parent | ad3c6418c2e282633a2f0e91754980d1a4d5b078 (diff) | |
parent | f92063028a0ea9e15d8f962644bce76c0e8aa7d1 (diff) |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, pc: fixes
virtio and misc fixes for 2.9.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Wed 22 Mar 2017 16:29:50 GMT
# gpg: using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67
# Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469
* remotes/mst/tags/for_upstream:
hw/acpi/vmgenid: prevent more than one vmgenid device
hw/acpi/vmgenid: prevent device realization on pre-2.5 machine types
virtio: always use handle_aio_output if registered
virtio: Fix error handling in virtio_bus_device_plugged
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/acpi/vmgenid.c | 22 | ||||
-rw-r--r-- | hw/virtio/virtio-bus.c | 20 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 13 | ||||
-rw-r--r-- | include/hw/acpi/vmgenid.h | 2 | ||||
-rw-r--r-- | include/hw/compat.h | 4 |
5 files changed, 57 insertions, 4 deletions
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index 7a3ad17d66..a32b847fe0 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -205,9 +205,30 @@ static void vmgenid_handle_reset(void *opaque) memset(vms->vmgenid_addr_le, 0, ARRAY_SIZE(vms->vmgenid_addr_le)); } +static Property vmgenid_properties[] = { + DEFINE_PROP_BOOL("x-write-pointer-available", VmGenIdState, + write_pointer_available, true), + DEFINE_PROP_END_OF_LIST(), +}; + static void vmgenid_realize(DeviceState *dev, Error **errp) { VmGenIdState *vms = VMGENID(dev); + + if (!vms->write_pointer_available) { + error_setg(errp, "%s requires DMA write support in fw_cfg, " + "which this machine type does not provide", VMGENID_DEVICE); + return; + } + + /* Given that this function is executing, there is at least one VMGENID + * device. Check if there are several. + */ + if (!find_vmgenid_dev()) { + error_setg(errp, "at most one %s device is permitted", VMGENID_DEVICE); + return; + } + qemu_register_reset(vmgenid_handle_reset, vms); } @@ -218,6 +239,7 @@ static void vmgenid_device_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_vmgenid; dc->realize = vmgenid_realize; dc->hotpluggable = false; + dc->props = vmgenid_properties; object_class_property_add_str(klass, VMGENID_GUID, NULL, vmgenid_set_guid, NULL); diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index a886011e75..3042232daf 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "qemu/error-report.h" +#include "qapi/error.h" #include "hw/qdev.h" #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio.h" @@ -48,20 +49,33 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); bool has_iommu = virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); + Error *local_err = NULL; DPRINTF("%s: plug device.\n", qbus->name); if (klass->pre_plugged != NULL) { - klass->pre_plugged(qbus->parent, errp); + klass->pre_plugged(qbus->parent, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } /* Get the features of the plugged device. */ assert(vdc->get_features != NULL); vdev->host_features = vdc->get_features(vdev, vdev->host_features, - errp); + &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } if (klass->device_plugged != NULL) { - klass->device_plugged(qbus->parent, errp); + klass->device_plugged(qbus->parent, &local_err); + } + if (local_err) { + error_propagate(errp, local_err); + return; } if (klass->get_dma_as != NULL && has_iommu) { diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 82b6060b2a..03592c542a 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1528,7 +1528,18 @@ static void virtio_queue_notify_vq(VirtQueue *vq) void virtio_queue_notify(VirtIODevice *vdev, int n) { - virtio_queue_notify_vq(&vdev->vq[n]); + VirtQueue *vq = &vdev->vq[n]; + + if (unlikely(!vq->vring.desc || vdev->broken)) { + return; + } + + trace_virtio_queue_notify(vdev, vq - vdev->vq, vq); + if (vq->handle_aio_output) { + event_notifier_set(&vq->host_notifier); + } else if (vq->handle_output) { + vq->handle_output(vdev, vq); + } } uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) diff --git a/include/hw/acpi/vmgenid.h b/include/hw/acpi/vmgenid.h index db7fa0e633..7beb9592fb 100644 --- a/include/hw/acpi/vmgenid.h +++ b/include/hw/acpi/vmgenid.h @@ -21,8 +21,10 @@ typedef struct VmGenIdState { DeviceClass parent_obj; QemuUUID guid; /* The 128-bit GUID seen by the guest */ uint8_t vmgenid_addr_le[8]; /* Address of the GUID (little-endian) */ + bool write_pointer_available; } VmGenIdState; +/* returns NULL unless there is exactly one device */ static inline Object *find_vmgenid_dev(void) { return object_resolve_path_type("", VMGENID_DEVICE, NULL); diff --git a/include/hw/compat.h b/include/hw/compat.h index fc8c3e0600..5d5be91daf 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -131,6 +131,10 @@ .driver = "fw_cfg_io",\ .property = "dma_enabled",\ .value = "off",\ + },{\ + .driver = "vmgenid",\ + .property = "x-write-pointer-available",\ + .value = "off",\ }, #define HW_COMPAT_2_3 \ |