]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Revert "virtio_pci: harden MSI-X interrupts"
authorJason Wang <jasowang@redhat.com>
Wed, 23 Mar 2022 03:15:24 +0000 (11:15 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:06:52 +0000 (14:06 +0200)
commit eb4cecb453a19b34d5454b49532e09e9cb0c1529 upstream.

This reverts commit 9e35276a5344f74d4a3600fc4100b3dd251d5c56. 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: 9e35276a5344 ("virtio_pci: harden MSI-X interrupts")
Reported-by: Marc Zyngier <maz@kernel.org>
Reported-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Link: https://lore.kernel.org/r/20220323031524.6555-2-jasowang@redhat.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/virtio/virtio_pci_common.c
drivers/virtio/virtio_pci_common.h
drivers/virtio/virtio_pci_legacy.c
drivers/virtio/virtio_pci_modern.c

index 3f51fdb7be45431ae562c84cbbef19277197811d..d724f676608ba34a973803eb8643bf3bba604262 100644 (file)
@@ -24,8 +24,8 @@ MODULE_PARM_DESC(force_legacy,
                 "Force legacy mode for transitional virtio 1 devices");
 #endif
 
-/* disable irq handlers */
-void vp_disable_cbs(struct virtio_device *vdev)
+/* wait for pending irq handlers */
+void vp_synchronize_vectors(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        int i;
@@ -34,20 +34,7 @@ void vp_disable_cbs(struct virtio_device *vdev)
                synchronize_irq(vp_dev->pci_dev->irq);
 
        for (i = 0; i < vp_dev->msix_vectors; ++i)
-               disable_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));
+               synchronize_irq(pci_irq_vector(vp_dev->pci_dev, i));
 }
 
 /* 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,
        snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
                 "%s-config", name);
        err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
-                         vp_config_changed, IRQF_NO_AUTOEN,
-                         vp_dev->msix_names[v],
+                         vp_config_changed, 0, vp_dev->msix_names[v],
                          vp_dev);
        if (err)
                goto error;
@@ -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,
                         "%s-virtqueues", name);
                err = request_irq(pci_irq_vector(vp_dev->pci_dev, v),
-                                 vp_vring_interrupt, IRQF_NO_AUTOEN,
-                                 vp_dev->msix_names[v],
+                                 vp_vring_interrupt, 0, vp_dev->msix_names[v],
                                  vp_dev);
                if (err)
                        goto error;
@@ -352,7 +337,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
                         "%s-%s",
                         dev_name(&vp_dev->vdev.dev), names[i]);
                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],
                                  vqs[i]);
                if (err)
index d3c6f72c73906029b5c32451a32ea6c073cbf301..eb17a29fc7ef1f6cbc3c93a390d03a80f0076fc6 100644 (file)
@@ -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);
 }
 
-/* disable irq handlers */
-void vp_disable_cbs(struct virtio_device *vdev);
-/* enable irq handlers */
-void vp_enable_cbs(struct virtio_device *vdev);
+/* wait for pending irq handlers */
+void vp_synchronize_vectors(struct virtio_device *vdev);
 /* the notify function used when creating a virt queue */
 bool vp_notify(struct virtqueue *vq);
 /* the config->del_vqs() implementation */
index b3f8128b7983b234489ba0ed87e2f2aafdbf25b5..82eb437ad9205033f37812b0db4fa64a6a0ef5a9 100644 (file)
@@ -98,8 +98,8 @@ static void vp_reset(struct virtio_device *vdev)
        /* Flush out the status write, and flush in device writes,
         * including MSi-X interrupts, if any. */
        vp_legacy_get_status(&vp_dev->ldev);
-       /* Disable VQ/configuration callbacks. */
-       vp_disable_cbs(vdev);
+       /* Flush pending VQ/configuration callbacks. */
+       vp_synchronize_vectors(vdev);
 }
 
 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)
 }
 
 static const struct virtio_config_ops virtio_pci_config_ops = {
-       .enable_cbs     = vp_enable_cbs,
        .get            = vp_get,
        .set            = vp_set,
        .get_status     = vp_get_status,
index 5455bc041fb6916bf265d45565905668fbdf9cf3..30654d3a0b41ed6fca1a46f9dac6ac01d925da53 100644 (file)
@@ -172,8 +172,8 @@ static void vp_reset(struct virtio_device *vdev)
         */
        while (vp_modern_get_status(mdev))
                msleep(1);
-       /* Disable VQ/configuration callbacks. */
-       vp_disable_cbs(vdev);
+       /* Flush pending VQ/configuration callbacks. */
+       vp_synchronize_vectors(vdev);
 }
 
 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,
 }
 
 static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
-       .enable_cbs     = vp_enable_cbs,
        .get            = NULL,
        .set            = NULL,
        .generation     = vp_generation,
@@ -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 = {
-       .enable_cbs     = vp_enable_cbs,
        .get            = vp_get,
        .set            = vp_set,
        .generation     = vp_generation,