summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-12-04 13:08:13 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-12-04 13:08:13 +0000
commite80a25611c67a93947ae99f4057b850410a54497 (patch)
tree044976b93f69ce3053911c61095cb25ba71d1c99 /hw
parent495566ec38817e6625294e6909cffb4de040c8e7 (diff)
parent75ba2ddb188fa07c3442446766782036e3085cba (diff)
downloadqemu-e80a25611c67a93947ae99f4057b850410a54497.zip
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, pci, virtio: fixes for rc3 A bunch of fixes all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 01 Dec 2017 17:06:33 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: pc: fix crash on attempted cpu unplug virtio: check VirtQueue Vring object is set vhost: fix error check in vhost_verify_ring_mappings() dump-guest-memory.py: fix No symbol "vmcoreinfo_find" vhost: restore avail index from vring used index on disconnection virtio: Add queue interface to restore avail index from vring used index i386/msi: Correct mask of destination ID in MSI address Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/pc.c5
-rw-r--r--hw/virtio/vhost.c10
-rw-r--r--hw/virtio/virtio.c24
3 files changed, 33 insertions, 6 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c3afe5b7f1..186545d2a4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1842,6 +1842,11 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
X86CPU *cpu = X86_CPU(dev);
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+ if (!pcms->acpi_dev) {
+ error_setg(&local_err, "CPU hot unplug not supported without ACPI");
+ goto out;
+ }
+
pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);
assert(idx != -1);
if (idx == 0) {
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index ddc42f0f93..e4290ce93d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -493,21 +493,21 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
j = 0;
r = vhost_verify_ring_part_mapping(dev, vq->desc, vq->desc_phys,
vq->desc_size, start_addr, size);
- if (!r) {
+ if (r) {
break;
}
j++;
r = vhost_verify_ring_part_mapping(dev, vq->avail, vq->avail_phys,
vq->avail_size, start_addr, size);
- if (!r) {
+ if (r) {
break;
}
j++;
r = vhost_verify_ring_part_mapping(dev, vq->used, vq->used_phys,
vq->used_size, start_addr, size);
- if (!r) {
+ if (r) {
break;
}
}
@@ -1138,6 +1138,10 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
if (r < 0) {
VHOST_OPS_DEBUG("vhost VQ %d ring restore failed: %d", idx, r);
+ /* Connection to the backend is broken, so let's sync internal
+ * last avail idx to the device used idx.
+ */
+ virtio_queue_restore_last_avail_idx(vdev, idx);
} else {
virtio_queue_set_last_avail_idx(vdev, idx, state.num);
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ea532dc35f..ad564b0132 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -182,7 +182,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n)
{
VRing *vring = &vdev->vq[n].vring;
- if (!vring->desc) {
+ if (!vring->num || !vring->desc || !vring->align) {
/* not yet setup -> nothing to do */
return;
}
@@ -1414,6 +1414,9 @@ void virtio_config_modern_writel(VirtIODevice *vdev,
void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
{
+ if (!vdev->vq[n].vring.num) {
+ return;
+ }
vdev->vq[n].vring.desc = addr;
virtio_queue_update_rings(vdev, n);
}
@@ -1426,6 +1429,9 @@ hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
hwaddr avail, hwaddr used)
{
+ if (!vdev->vq[n].vring.num) {
+ return;
+ }
vdev->vq[n].vring.desc = desc;
vdev->vq[n].vring.avail = avail;
vdev->vq[n].vring.used = used;
@@ -1494,8 +1500,10 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
*/
assert(k->has_variable_vring_alignment);
- vdev->vq[n].vring.align = align;
- virtio_queue_update_rings(vdev, n);
+ if (align) {
+ vdev->vq[n].vring.align = align;
+ virtio_queue_update_rings(vdev, n);
+ }
}
static bool virtio_queue_notify_aio_vq(VirtQueue *vq)
@@ -2310,6 +2318,16 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
vdev->vq[n].shadow_avail_idx = idx;
}
+void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n)
+{
+ rcu_read_lock();
+ if (vdev->vq[n].vring.desc) {
+ vdev->vq[n].last_avail_idx = vring_used_idx(&vdev->vq[n]);
+ vdev->vq[n].shadow_avail_idx = vdev->vq[n].last_avail_idx;
+ }
+ rcu_read_unlock();
+}
+
void virtio_queue_update_used_idx(VirtIODevice *vdev, int n)
{
rcu_read_lock();