virtio-pci: don't try to mask or unmask vqs without notifiers

We should validate the vq index against nvqs_with_notifiers. Otherwise we may
try to mask or unmask vector for vqs without notifiers (e.g control vq). This
will lead qemu abort on kvm_irqchip_commit_routes() when trying to boot win8.1
guest.

Fixes 851c2a75a6 ("virtio-pci: speedup MSI-X
masking and unmasking")

Reported-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Jason Wang 2015-05-27 16:26:07 +08:00 committed by Michael S. Tsirkin
parent 557772f26b
commit 6652d0811c

View File

@ -632,21 +632,26 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
if (!virtio_queue_get_num(vdev, index)) {
break;
}
ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
if (ret < 0) {
goto undo;
if (index < proxy->nvqs_with_notifiers) {
ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
if (ret < 0) {
goto undo;
}
++unmasked;
}
vq = virtio_vector_next_queue(vq);
++unmasked;
}
return 0;
undo:
vq = virtio_vector_first_queue(vdev, vector);
while (vq && --unmasked >= 0) {
while (vq && unmasked >= 0) {
index = virtio_get_queue_index(vq);
virtio_pci_vq_vector_mask(proxy, index, vector);
if (index < proxy->nvqs_with_notifiers) {
virtio_pci_vq_vector_mask(proxy, index, vector);
--unmasked;
}
vq = virtio_vector_next_queue(vq);
}
return ret;
@ -664,7 +669,9 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
if (!virtio_queue_get_num(vdev, index)) {
break;
}
virtio_pci_vq_vector_mask(proxy, index, vector);
if (index < proxy->nvqs_with_notifiers) {
virtio_pci_vq_vector_mask(proxy, index, vector);
}
vq = virtio_vector_next_queue(vq);
}
}