Commit eb4cecb4 authored by Jason Wang's avatar Jason Wang Committed by Michael S. Tsirkin

Revert "virtio_pci: harden MSI-X interrupts"

This reverts commit 9e35276a. Issue
were reported for the drivers that are using affinity managed IRQ
where manually toggling IRQ status is not expected. And we forget to
enable the interrupts in the restore path as well.

In the future, we will rework on the interrupt hardening.

Fixes: 9e35276a ("virtio_pci: harden MSI-X interrupts")
Reported-by: default avatarMarc Zyngier <maz@kernel.org>
Reported-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Link: https://lore.kernel.org/r/20220323031524.6555-2-jasowang@redhat.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 7b79edfb
...@@ -24,8 +24,8 @@ MODULE_PARM_DESC(force_legacy, ...@@ -24,8 +24,8 @@ MODULE_PARM_DESC(force_legacy,
"Force legacy mode for transitional virtio 1 devices"); "Force legacy mode for transitional virtio 1 devices");
#endif #endif
/* disable irq handlers */ /* wait for pending irq handlers */
void vp_disable_cbs(struct virtio_device *vdev) void vp_synchronize_vectors(struct virtio_device *vdev)
{ {
struct virtio_pci_device *vp_dev = to_vp_device(vdev); struct virtio_pci_device *vp_dev = to_vp_device(vdev);
int i; int i;
...@@ -34,20 +34,7 @@ void vp_disable_cbs(struct virtio_device *vdev) ...@@ -34,20 +34,7 @@ void vp_disable_cbs(struct virtio_device *vdev)
synchronize_irq(vp_dev->pci_dev->irq); synchronize_irq(vp_dev->pci_dev->irq);
for (i = 0; i < vp_dev->msix_vectors; ++i) for (i = 0; i < vp_dev->msix_vectors; ++i)
disable_irq(pci_irq_vector(vp_dev->pci_dev, i)); synchronize_irq(pci_irq_vector(vp_dev->pci_dev, i));
}
/* enable irq handlers */
void vp_enable_cbs(struct virtio_device *vdev)
{
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
int i;
if (vp_dev->intx_enabled)
return;
for (i = 0; i < vp_dev->msix_vectors; ++i)
enable_irq(pci_irq_vector(vp_dev->pci_dev, i));
} }
/* the notify function used when creating a virt queue */ /* the notify function used when creating a virt queue */
...@@ -154,8 +141,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, ...@@ -154,8 +141,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names, snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
"%s-config", name); "%s-config", name);
err = request_irq(pci_irq_vector(vp_dev->pci_dev, v), err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
vp_config_changed, IRQF_NO_AUTOEN, vp_config_changed, 0, vp_dev->msix_names[v],
vp_dev->msix_names[v],
vp_dev); vp_dev);
if (err) if (err)
goto error; goto error;
...@@ -174,8 +160,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, ...@@ -174,8 +160,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names, snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
"%s-virtqueues", name); "%s-virtqueues", name);
err = request_irq(pci_irq_vector(vp_dev->pci_dev, v), err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
vp_vring_interrupt, IRQF_NO_AUTOEN, vp_vring_interrupt, 0, vp_dev->msix_names[v],
vp_dev->msix_names[v],
vp_dev); vp_dev);
if (err) if (err)
goto error; goto error;
...@@ -352,7 +337,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, ...@@ -352,7 +337,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
"%s-%s", "%s-%s",
dev_name(&vp_dev->vdev.dev), names[i]); dev_name(&vp_dev->vdev.dev), names[i]);
err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec), err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec),
vring_interrupt, IRQF_NO_AUTOEN, vring_interrupt, 0,
vp_dev->msix_names[msix_vec], vp_dev->msix_names[msix_vec],
vqs[i]); vqs[i]);
if (err) if (err)
......
...@@ -101,10 +101,8 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) ...@@ -101,10 +101,8 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
return container_of(vdev, struct virtio_pci_device, vdev); return container_of(vdev, struct virtio_pci_device, vdev);
} }
/* disable irq handlers */ /* wait for pending irq handlers */
void vp_disable_cbs(struct virtio_device *vdev); void vp_synchronize_vectors(struct virtio_device *vdev);
/* enable irq handlers */
void vp_enable_cbs(struct virtio_device *vdev);
/* the notify function used when creating a virt queue */ /* the notify function used when creating a virt queue */
bool vp_notify(struct virtqueue *vq); bool vp_notify(struct virtqueue *vq);
/* the config->del_vqs() implementation */ /* the config->del_vqs() implementation */
......
...@@ -98,8 +98,8 @@ static void vp_reset(struct virtio_device *vdev) ...@@ -98,8 +98,8 @@ static void vp_reset(struct virtio_device *vdev)
/* Flush out the status write, and flush in device writes, /* Flush out the status write, and flush in device writes,
* including MSi-X interrupts, if any. */ * including MSi-X interrupts, if any. */
vp_legacy_get_status(&vp_dev->ldev); vp_legacy_get_status(&vp_dev->ldev);
/* Disable VQ/configuration callbacks. */ /* Flush pending VQ/configuration callbacks. */
vp_disable_cbs(vdev); vp_synchronize_vectors(vdev);
} }
static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
...@@ -185,7 +185,6 @@ static void del_vq(struct virtio_pci_vq_info *info) ...@@ -185,7 +185,6 @@ static void del_vq(struct virtio_pci_vq_info *info)
} }
static const struct virtio_config_ops virtio_pci_config_ops = { static const struct virtio_config_ops virtio_pci_config_ops = {
.enable_cbs = vp_enable_cbs,
.get = vp_get, .get = vp_get,
.set = vp_set, .set = vp_set,
.get_status = vp_get_status, .get_status = vp_get_status,
......
...@@ -172,8 +172,8 @@ static void vp_reset(struct virtio_device *vdev) ...@@ -172,8 +172,8 @@ static void vp_reset(struct virtio_device *vdev)
*/ */
while (vp_modern_get_status(mdev)) while (vp_modern_get_status(mdev))
msleep(1); msleep(1);
/* Disable VQ/configuration callbacks. */ /* Flush pending VQ/configuration callbacks. */
vp_disable_cbs(vdev); vp_synchronize_vectors(vdev);
} }
static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
...@@ -380,7 +380,6 @@ static bool vp_get_shm_region(struct virtio_device *vdev, ...@@ -380,7 +380,6 @@ static bool vp_get_shm_region(struct virtio_device *vdev,
} }
static const struct virtio_config_ops virtio_pci_config_nodev_ops = { static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
.enable_cbs = vp_enable_cbs,
.get = NULL, .get = NULL,
.set = NULL, .set = NULL,
.generation = vp_generation, .generation = vp_generation,
...@@ -398,7 +397,6 @@ static const struct virtio_config_ops virtio_pci_config_nodev_ops = { ...@@ -398,7 +397,6 @@ static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
}; };
static const struct virtio_config_ops virtio_pci_config_ops = { static const struct virtio_config_ops virtio_pci_config_ops = {
.enable_cbs = vp_enable_cbs,
.get = vp_get, .get = vp_get,
.set = vp_set, .set = vp_set,
.generation = vp_generation, .generation = vp_generation,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment