]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Apr 2026 13:53:52 +0000 (15:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Apr 2026 13:53:52 +0000 (15:53 +0200)
added patches:
input-edt-ft5x06-fix-use-after-free-in-debugfs-teardown.patch
spi-ch341-fix-memory-leaks-on-probe-failures.patch
spi-imx-fix-use-after-free-on-unbind.patch
thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch
vfio-cdx-serialize-vfio_device_set_irqs-with-a-per-device-mutex.patch
vfio-selftests-fix-vla-initialisation-in-vfio_pci_irq_set.patch
vfio-virtio-convert-list_lock-from-spinlock-to-mutex.patch
vfio-xe-add-a-missing-vfio_pci_core_release_dev.patch
wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
zram-do-not-forget-to-endio-for-partial-discard-requests.patch

14 files changed:
queue-7.0/input-edt-ft5x06-fix-use-after-free-in-debugfs-teardown.patch [new file with mode: 0644]
queue-7.0/series
queue-7.0/spi-ch341-fix-memory-leaks-on-probe-failures.patch [new file with mode: 0644]
queue-7.0/spi-imx-fix-use-after-free-on-unbind.patch [new file with mode: 0644]
queue-7.0/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch [new file with mode: 0644]
queue-7.0/um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch [new file with mode: 0644]
queue-7.0/vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch [new file with mode: 0644]
queue-7.0/vfio-cdx-serialize-vfio_device_set_irqs-with-a-per-device-mutex.patch [new file with mode: 0644]
queue-7.0/vfio-selftests-fix-vla-initialisation-in-vfio_pci_irq_set.patch [new file with mode: 0644]
queue-7.0/vfio-virtio-convert-list_lock-from-spinlock-to-mutex.patch [new file with mode: 0644]
queue-7.0/vfio-xe-add-a-missing-vfio_pci_core_release_dev.patch [new file with mode: 0644]
queue-7.0/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch [new file with mode: 0644]
queue-7.0/wifi-rtw88-check-for-pci-upstream-bridge-existence.patch [new file with mode: 0644]
queue-7.0/zram-do-not-forget-to-endio-for-partial-discard-requests.patch [new file with mode: 0644]

diff --git a/queue-7.0/input-edt-ft5x06-fix-use-after-free-in-debugfs-teardown.patch b/queue-7.0/input-edt-ft5x06-fix-use-after-free-in-debugfs-teardown.patch
new file mode 100644 (file)
index 0000000..74a90df
--- /dev/null
@@ -0,0 +1,42 @@
+From f5f9e07060519e2287e99019a6de1eb3ebb65c37 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Fri, 10 Apr 2026 21:13:43 -0700
+Subject: Input: edt-ft5x06 - fix use-after-free in debugfs teardown
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit f5f9e07060519e2287e99019a6de1eb3ebb65c37 upstream.
+
+The commit 68743c500c6e ("Input: edt-ft5x06 - use per-client debugfs
+directory") removed the manual debugfs teardown, relying on the I2C core
+to handle it. However, this creates a window where debugfs files are
+still accessible after edt_ft5x06_ts_teardown_debugfs() frees
+tsdata->raw_buffer.
+
+To prevent a use-after-free, protect the freeing of raw_buffer with the
+device mutex and set raw_buffer to NULL. The debugfs read function
+already checks if raw_buffer is NULL under the same mutex, so this
+safely avoids the use-after-free.
+
+Fixes: 68743c500c6e ("Input: edt-ft5x06 - use per-client debugfs directory")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/adnJicDh-bTUaWXP@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/touchscreen/edt-ft5x06.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -829,7 +829,10 @@ static void edt_ft5x06_ts_prepare_debugf
+ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
+ {
++      guard(mutex)(&tsdata->mutex);
++
+       kfree(tsdata->raw_buffer);
++      tsdata->raw_buffer = NULL;
+ }
+ #else
index 947d320c520808f8ddae1cc805e52cc31ca0b09a..f618466fad46a25974940e021582a4ebbb4eca26 100644 (file)
@@ -28,3 +28,16 @@ mm-migrate-requeue-destination-folio-on-deferred-split-queue.patch
 mm-prevent-droppable-mappings-from-being-locked.patch
 mm-fix-deferred-split-queue-races-during-migration.patch
 ocfs2-split-transactions-in-dio-completion-to-avoid-credit-exhaustion.patch
+input-edt-ft5x06-fix-use-after-free-in-debugfs-teardown.patch
+zram-do-not-forget-to-endio-for-partial-discard-requests.patch
+wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
+wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
+vfio-selftests-fix-vla-initialisation-in-vfio_pci_irq_set.patch
+vfio-xe-add-a-missing-vfio_pci_core_release_dev.patch
+vfio-virtio-convert-list_lock-from-spinlock-to-mutex.patch
+vfio-cdx-serialize-vfio_device_set_irqs-with-a-per-device-mutex.patch
+vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch
+um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
+thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
+spi-imx-fix-use-after-free-on-unbind.patch
+spi-ch341-fix-memory-leaks-on-probe-failures.patch
diff --git a/queue-7.0/spi-ch341-fix-memory-leaks-on-probe-failures.patch b/queue-7.0/spi-ch341-fix-memory-leaks-on-probe-failures.patch
new file mode 100644 (file)
index 0000000..d60be70
--- /dev/null
@@ -0,0 +1,102 @@
+From b99e3ddb91b499d920e63a2daff8880be68cfe9e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 27 Mar 2026 11:43:04 +0100
+Subject: spi: ch341: fix memory leaks on probe failures
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b99e3ddb91b499d920e63a2daff8880be68cfe9e upstream.
+
+Make sure to deregister the controller, disable pins, and kill and free
+the RX URB on probe failures to mirror disconnect and avoid memory
+leaks and use-after-free.
+
+Also add an explicit URB kill on disconnect for symmetry (even if that
+is not strictly required as USB core would have stopped it in the
+current setup).
+
+Fixes: 8846739f52af ("spi: add ch341a usb2spi driver")
+Cc: stable@vger.kernel.org     # 6.11
+Cc: Johannes Thumshirn <jth@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260327104305.1309915-2-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ch341.c |   36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+--- a/drivers/spi/spi-ch341.c
++++ b/drivers/spi/spi-ch341.c
+@@ -173,17 +173,17 @@ static int ch341_probe(struct usb_interf
+       ch341->tx_buf =
+               devm_kzalloc(&udev->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
+-      if (!ch341->tx_buf)
+-              return -ENOMEM;
++      if (!ch341->tx_buf) {
++              ret = -ENOMEM;
++              goto err_free_urb;
++      }
+       usb_fill_bulk_urb(ch341->rx_urb, udev, ch341->read_pipe, ch341->rx_buf,
+                         ch341->rx_len, ch341_recv, ch341);
+       ret = usb_submit_urb(ch341->rx_urb, GFP_KERNEL);
+-      if (ret) {
+-              usb_free_urb(ch341->rx_urb);
+-              return -ENOMEM;
+-      }
++      if (ret)
++              goto err_free_urb;
+       ctrl->bus_num = -1;
+       ctrl->mode_bits = SPI_CPHA;
+@@ -195,21 +195,34 @@ static int ch341_probe(struct usb_interf
+       ret = ch341_config_stream(ch341);
+       if (ret)
+-              return ret;
++              goto err_kill_urb;
+       ret = ch341_enable_pins(ch341, true);
+       if (ret)
+-              return ret;
++              goto err_kill_urb;
+       ret = spi_register_controller(ctrl);
+       if (ret)
+-              return ret;
++              goto err_disable_pins;
+       ch341->spidev = spi_new_device(ctrl, &chip);
+-      if (!ch341->spidev)
+-              return -ENOMEM;
++      if (!ch341->spidev) {
++              ret = -ENOMEM;
++              goto err_unregister;
++      }
+       return 0;
++
++err_unregister:
++      spi_unregister_controller(ctrl);
++err_disable_pins:
++      ch341_enable_pins(ch341, false);
++err_kill_urb:
++      usb_kill_urb(ch341->rx_urb);
++err_free_urb:
++      usb_free_urb(ch341->rx_urb);
++
++      return ret;
+ }
+ static void ch341_disconnect(struct usb_interface *intf)
+@@ -219,6 +232,7 @@ static void ch341_disconnect(struct usb_
+       spi_unregister_device(ch341->spidev);
+       spi_unregister_controller(ch341->ctrl);
+       ch341_enable_pins(ch341, false);
++      usb_kill_urb(ch341->rx_urb);
+       usb_free_urb(ch341->rx_urb);
+ }
diff --git a/queue-7.0/spi-imx-fix-use-after-free-on-unbind.patch b/queue-7.0/spi-imx-fix-use-after-free-on-unbind.patch
new file mode 100644 (file)
index 0000000..6c59a53
--- /dev/null
@@ -0,0 +1,47 @@
+From 1c78c2002380a1fe31bfb01a3d5f29809e55a096 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 24 Mar 2026 09:23:22 +0100
+Subject: spi: imx: fix use-after-free on unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 1c78c2002380a1fe31bfb01a3d5f29809e55a096 upstream.
+
+The SPI subsystem frees the controller and any subsystem allocated
+driver data as part of deregistration (unless the allocation is device
+managed).
+
+Take another reference before deregistering the controller so that the
+driver data is not freed until the driver is done with it.
+
+Fixes: 307c897db762 ("spi: spi-imx: replace struct spi_imx_data::bitbang by pointer to struct spi_controller")
+Cc: stable@vger.kernel.org     # 5.19
+Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260324082326.901043-2-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-imx.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -2401,6 +2401,8 @@ static void spi_imx_remove(struct platfo
+       struct spi_imx_data *spi_imx = spi_controller_get_devdata(controller);
+       int ret;
++      spi_controller_get(controller);
++
+       spi_unregister_controller(controller);
+       ret = pm_runtime_get_sync(spi_imx->dev);
+@@ -2414,6 +2416,8 @@ static void spi_imx_remove(struct platfo
+       pm_runtime_disable(spi_imx->dev);
+       spi_imx_sdma_exit(spi_imx);
++
++      spi_controller_put(controller);
+ }
+ static int spi_imx_runtime_resume(struct device *dev)
diff --git a/queue-7.0/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch b/queue-7.0/thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
new file mode 100644 (file)
index 0000000..c832251
--- /dev/null
@@ -0,0 +1,64 @@
+From 41ff66baf81c6541f4f985dd7eac4494d03d9440 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Tue, 7 Apr 2026 15:55:19 +0200
+Subject: thermal: core: Fix thermal zone governor cleanup issues
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 41ff66baf81c6541f4f985dd7eac4494d03d9440 upstream.
+
+If thermal_zone_device_register_with_trips() fails after adding
+a thermal governor to the thermal zone being registered, the
+governor is not removed from it as appropriate which may lead to
+a memory leak.
+
+In turn, thermal_zone_device_unregister() calls thermal_set_governor()
+without acquiring the thermal zone lock beforehand which may race with
+a governor update via sysfs and may lead to a use-after-free in that
+case.
+
+Address these issues by adding two thermal_set_governor() calls, one to
+thermal_release() to remove the governor from the given thermal zone,
+and one to the thermal zone registration error path to cover failures
+preceding the thermal zone device registration.
+
+Fixes: e33df1d2f3a0 ("thermal: let governors have private data for each thermal zone")
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/5092923.31r3eYUQgx@rafael.j.wysocki
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thermal/thermal_core.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -964,6 +964,7 @@ static void thermal_release(struct devic
+                    sizeof("thermal_zone") - 1)) {
+               tz = to_thermal_zone(dev);
+               thermal_zone_destroy_device_groups(tz);
++              thermal_set_governor(tz, NULL);
+               mutex_destroy(&tz->lock);
+               complete(&tz->removal);
+       } else if (!strncmp(dev_name(dev), "cooling_device",
+@@ -1611,8 +1612,10 @@ thermal_zone_device_register_with_trips(
+       /* sys I/F */
+       /* Add nodes that are always present via .groups */
+       result = thermal_zone_create_device_groups(tz);
+-      if (result)
++      if (result) {
++              thermal_set_governor(tz, NULL);
+               goto remove_id;
++      }
+       result = device_register(&tz->device);
+       if (result)
+@@ -1725,8 +1728,6 @@ void thermal_zone_device_unregister(stru
+       cancel_delayed_work_sync(&tz->poll_queue);
+-      thermal_set_governor(tz, NULL);
+-
+       thermal_thresholds_exit(tz);
+       thermal_remove_hwmon_sysfs(tz);
+       ida_free(&thermal_tz_ida, tz->id);
diff --git a/queue-7.0/um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch b/queue-7.0/um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
new file mode 100644 (file)
index 0000000..d64b730
--- /dev/null
@@ -0,0 +1,57 @@
+From 91e901c65b4da02a6fd543e3f0049829ae9645b7 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Wed, 8 Apr 2026 03:01:02 -0400
+Subject: um: drivers: call kernel_strrchr() explicitly in cow_user.c
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 91e901c65b4da02a6fd543e3f0049829ae9645b7 upstream.
+
+Building ARCH=um on glibc >= 2.43 fails:
+
+  arch/um/drivers/cow_user.c: error: implicit declaration of
+  function 'strrchr' [-Wimplicit-function-declaration]
+
+glibc 2.43's C23 const-preserving strrchr() macro does not survive
+UML's global -Dstrrchr=kernel_strrchr remap from arch/um/Makefile.
+Call kernel_strrchr() directly in cow_user.c so the source no longer
+depends on the -D rewrite.
+
+Fixes: 2c51a4bc0233 ("um: fix strrchr() problems")
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Assisted-by: Codex:gpt-5-4
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/20260408070102.2325572-1-michael.bommarito@gmail.com
+[remove unnecessary 'extern']
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/um/drivers/cow_user.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/arch/um/drivers/cow_user.c
++++ b/arch/um/drivers/cow_user.c
+@@ -15,6 +15,12 @@
+ #include "cow.h"
+ #include "cow_sys.h"
++/*
++ * arch/um/Makefile remaps strrchr to kernel_strrchr; call the kernel
++ * name directly to avoid glibc >= 2.43's C23 strrchr macro.
++ */
++char *kernel_strrchr(const char *, int);
++
+ #define PATH_LEN_V1 256
+ /* unsigned time_t works until year 2106 */
+@@ -153,7 +159,7 @@ static int absolutize(char *to, int size
+                          errno);
+               return -1;
+       }
+-      slash = strrchr(from, '/');
++      slash = kernel_strrchr(from, '/');
+       if (slash != NULL) {
+               *slash = '\0';
+               if (chdir(from)) {
diff --git a/queue-7.0/vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch b/queue-7.0/vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch
new file mode 100644 (file)
index 0000000..1ebea09
--- /dev/null
@@ -0,0 +1,49 @@
+From 5ea5880764cbb164afb17a62e76ca75dc371409d Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+Date: Fri, 17 Apr 2026 14:27:56 -0600
+Subject: vfio/cdx: Fix NULL pointer dereference in interrupt trigger path
+
+From: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+
+commit 5ea5880764cbb164afb17a62e76ca75dc371409d upstream.
+
+Add validation to ensure MSI is configured before accessing cdx_irqs
+array in vfio_cdx_set_msi_trigger(). Without this check, userspace
+can trigger a NULL pointer dereference by calling VFIO_DEVICE_SET_IRQS
+with VFIO_IRQ_SET_DATA_BOOL or VFIO_IRQ_SET_DATA_NONE flags before
+ever setting up interrupts via VFIO_IRQ_SET_DATA_EVENTFD.
+
+The vfio_cdx_msi_enable() function allocates the cdx_irqs array and
+sets config_msi to 1 only when called through the EVENTFD path. The
+trigger loop (for DATA_BOOL/DATA_NONE) assumed this had already been
+done, but there was no enforcement of this call ordering.
+
+This matches the protection used in the PCI VFIO driver where
+vfio_pci_set_msi_trigger() checks irq_is() before the trigger loop.
+
+Fixes: 848e447e000c ("vfio/cdx: add interrupt support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+Acked-by: Nipun Gupta <nipun.gupta@amd.com>
+Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
+Acked-by: Nikhil Agarwal <nikhil.agarwal@amd.com>
+Link: https://lore.kernel.org/r/20260417202800.88287-2-alex.williamson@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/cdx/intr.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/vfio/cdx/intr.c
++++ b/drivers/vfio/cdx/intr.c
+@@ -177,6 +177,10 @@ static int vfio_cdx_set_msi_trigger(stru
+               return ret;
+       }
++      /* Ensure MSI is configured before accessing cdx_irqs */
++      if (!vdev->config_msi)
++              return -EINVAL;
++
+       for (i = start; i < start + count; i++) {
+               if (!vdev->cdx_irqs[i].trigger)
+                       continue;
diff --git a/queue-7.0/vfio-cdx-serialize-vfio_device_set_irqs-with-a-per-device-mutex.patch b/queue-7.0/vfio-cdx-serialize-vfio_device_set_irqs-with-a-per-device-mutex.patch
new file mode 100644 (file)
index 0000000..8e4af4f
--- /dev/null
@@ -0,0 +1,121 @@
+From 670e8864b1a218d72f08db40d0103adf38fa1d9b Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@nvidia.com>
+Date: Fri, 17 Apr 2026 14:27:57 -0600
+Subject: vfio/cdx: Serialize VFIO_DEVICE_SET_IRQS with a per-device mutex
+
+From: Alex Williamson <alex.williamson@nvidia.com>
+
+commit 670e8864b1a218d72f08db40d0103adf38fa1d9b upstream.
+
+vfio_cdx_set_msi_trigger() reads vdev->config_msi and operates on the
+vdev->cdx_irqs array based on its value, but provides no serialization
+against concurrent VFIO_DEVICE_SET_IRQS ioctls.  Two callers can race
+such that one observes config_msi as set while another clears it and
+frees cdx_irqs via vfio_cdx_msi_disable(), resulting in a use-after-free
+of the cdx_irqs array.
+
+Add a cdx_irqs_lock mutex to struct vfio_cdx_device and acquire it in
+vfio_cdx_set_msi_trigger(), which is the single chokepoint through
+which all updates to config_msi, cdx_irqs, and msi_count flow, covering
+both the ioctl path and the close-device cleanup path.  This keeps the
+test of config_msi atomic with the subsequent enable, disable, or
+trigger operations.
+
+Drop the pre-call !cdx_irqs test from vfio_cdx_irqs_cleanup() as part
+of this change: the optimization it provided is redundant with the
+!config_msi early-return inside vfio_cdx_msi_disable(), and leaving the
+test in place would be an unsynchronized read of state the new lock is
+meant to protect.
+
+Fixes: 848e447e000c ("vfio/cdx: add interrupt support")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
+Acked-by: Nikhil Agarwal <nikhil.agarwal@amd.com>
+Link: https://lore.kernel.org/r/20260417202800.88287-3-alex.williamson@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/cdx/intr.c    |    9 ++-------
+ drivers/vfio/cdx/main.c    |   19 +++++++++++++++++++
+ drivers/vfio/cdx/private.h |    3 +++
+ 3 files changed, 24 insertions(+), 7 deletions(-)
+
+--- a/drivers/vfio/cdx/intr.c
++++ b/drivers/vfio/cdx/intr.c
+@@ -152,6 +152,8 @@ static int vfio_cdx_set_msi_trigger(stru
+       if (start + count > cdx_dev->num_msi)
+               return -EINVAL;
++      guard(mutex)(&vdev->cdx_irqs_lock);
++
+       if (!count && (flags & VFIO_IRQ_SET_DATA_NONE)) {
+               vfio_cdx_msi_disable(vdev);
+               return 0;
+@@ -206,12 +208,5 @@ int vfio_cdx_set_irqs_ioctl(struct vfio_
+ /* Free All IRQs for the given device */
+ void vfio_cdx_irqs_cleanup(struct vfio_cdx_device *vdev)
+ {
+-      /*
+-       * Device does not support any interrupt or the interrupts
+-       * were not configured
+-       */
+-      if (!vdev->cdx_irqs)
+-              return;
+-
+       vfio_cdx_set_msi_trigger(vdev, 0, 0, 0, VFIO_IRQ_SET_DATA_NONE, NULL);
+ }
+--- a/drivers/vfio/cdx/main.c
++++ b/drivers/vfio/cdx/main.c
+@@ -8,6 +8,23 @@
+ #include "private.h"
++static int vfio_cdx_init_dev(struct vfio_device *core_vdev)
++{
++      struct vfio_cdx_device *vdev =
++              container_of(core_vdev, struct vfio_cdx_device, vdev);
++
++      mutex_init(&vdev->cdx_irqs_lock);
++      return 0;
++}
++
++static void vfio_cdx_release_dev(struct vfio_device *core_vdev)
++{
++      struct vfio_cdx_device *vdev =
++              container_of(core_vdev, struct vfio_cdx_device, vdev);
++
++      mutex_destroy(&vdev->cdx_irqs_lock);
++}
++
+ static int vfio_cdx_open_device(struct vfio_device *core_vdev)
+ {
+       struct vfio_cdx_device *vdev =
+@@ -273,6 +290,8 @@ static int vfio_cdx_mmap(struct vfio_dev
+ static const struct vfio_device_ops vfio_cdx_ops = {
+       .name           = "vfio-cdx",
++      .init           = vfio_cdx_init_dev,
++      .release        = vfio_cdx_release_dev,
+       .open_device    = vfio_cdx_open_device,
+       .close_device   = vfio_cdx_close_device,
+       .ioctl          = vfio_cdx_ioctl,
+--- a/drivers/vfio/cdx/private.h
++++ b/drivers/vfio/cdx/private.h
+@@ -6,6 +6,8 @@
+ #ifndef VFIO_CDX_PRIVATE_H
+ #define VFIO_CDX_PRIVATE_H
++#include <linux/mutex.h>
++
+ #define VFIO_CDX_OFFSET_SHIFT    40
+ static inline u64 vfio_cdx_index_to_offset(u32 index)
+@@ -31,6 +33,7 @@ struct vfio_cdx_region {
+ struct vfio_cdx_device {
+       struct vfio_device      vdev;
+       struct vfio_cdx_region  *regions;
++      struct mutex            cdx_irqs_lock;
+       struct vfio_cdx_irq     *cdx_irqs;
+       u32                     flags;
+ #define BME_SUPPORT BIT(0)
diff --git a/queue-7.0/vfio-selftests-fix-vla-initialisation-in-vfio_pci_irq_set.patch b/queue-7.0/vfio-selftests-fix-vla-initialisation-in-vfio_pci_irq_set.patch
new file mode 100644 (file)
index 0000000..3c55ad7
--- /dev/null
@@ -0,0 +1,56 @@
+From 4f42d716707654134789a0205a050b0d022be948 Mon Sep 17 00:00:00 2001
+From: Manish Honap <mhonap@nvidia.com>
+Date: Tue, 17 Mar 2026 10:44:02 +0530
+Subject: vfio: selftests: Fix VLA initialisation in vfio_pci_irq_set()
+
+From: Manish Honap <mhonap@nvidia.com>
+
+commit 4f42d716707654134789a0205a050b0d022be948 upstream.
+
+C does not permit an initialiser expression on a variable-length array
+(C99 Section 6.7.9 constraint: "The type of the entity to be initialized
+shall not be a variable length array type").
+
+vfio_pci_irq_set() declared:
+
+      u8 buf[sizeof(struct vfio_irq_set) + sizeof(int) * count] = {};
+
+where `count` is a runtime function parameter, making `buf` a VLA.
+
+GCC rejects this with (tried with GCC-9.4.0):
+
+      error: variable-sized object may not be initialized
+
+Fix by removing the `= {}` initialiser and inserting an explicit
+memset() immediately after the declaration.  memset() on a VLA is
+perfectly legal and achieves the same zero-initialisation on all
+conforming C implementations.
+
+Fixes: 19faf6fd969c ("vfio: selftests: Add a helper library for VFIO selftests")
+Cc: stable@vger.kernel.org
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: David Matlack <dmatlack@google.com>
+Signed-off-by: Manish Honap <mhonap@nvidia.com>
+Link: https://lore.kernel.org/r/20260317051402.3725670-1-mhonap@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/vfio/lib/vfio_pci_device.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c
++++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c
+@@ -30,10 +30,12 @@
+ static void vfio_pci_irq_set(struct vfio_pci_device *device,
+                            u32 index, u32 vector, u32 count, int *fds)
+ {
+-      u8 buf[sizeof(struct vfio_irq_set) + sizeof(int) * count] = {};
++      u8 buf[sizeof(struct vfio_irq_set) + sizeof(int) * count];
+       struct vfio_irq_set *irq = (void *)&buf;
+       int *irq_fds = (void *)&irq->data;
++      memset(buf, 0, sizeof(buf));
++
+       irq->argsz = sizeof(buf);
+       irq->flags = VFIO_IRQ_SET_ACTION_TRIGGER;
+       irq->index = index;
diff --git a/queue-7.0/vfio-virtio-convert-list_lock-from-spinlock-to-mutex.patch b/queue-7.0/vfio-virtio-convert-list_lock-from-spinlock-to-mutex.patch
new file mode 100644 (file)
index 0000000..967214e
--- /dev/null
@@ -0,0 +1,169 @@
+From 903570835f12b7436ca0edb0a9ed351c0349121e Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@nvidia.com>
+Date: Tue, 14 Apr 2026 14:06:19 -0600
+Subject: vfio/virtio: Convert list_lock from spinlock to mutex
+
+From: Alex Williamson <alex.williamson@nvidia.com>
+
+commit 903570835f12b7436ca0edb0a9ed351c0349121e upstream.
+
+The list_lock spinlock with IRQ disabling was copied from the mlx5
+vfio-pci variant driver, where it is justified by a hardirq async
+command completion callback that accesses the protected lists.  The
+virtio driver has no such interrupt context usage; all list_lock
+acquisitions occur in process context via file read/write operations
+or state transitions under state_mutex.
+
+Convert list_lock to a mutex to be consistent with peer vfio-pci
+variant drivers (hisilicon, pds, qat, xe) which all use mutexes for
+equivalent migration data protection.  This also fixes a mismatched
+spin_lock()/spin_unlock_irq() pair in virtiovf_read_device_context_chunk()
+that could incorrectly enable interrupts.
+
+Reported-by: Jinhui Guo <guojinhui.liam@bytedance.com>
+Closes: https://lore.kernel.org/all/20260413073603.30538-1-guojinhui.liam@bytedance.com
+Fixes: 0bbc82e4ec79 ("vfio/virtio: Add support for the basic live migration functionality")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Alex Williamson <alex.williamson@nvidia.com>
+Reviewed-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://lore.kernel.org/r/20260414200625.3601509-2-alex.williamson@nvidia.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/pci/virtio/common.h  |    2 +-
+ drivers/vfio/pci/virtio/migrate.c |   33 +++++++++++++++++----------------
+ 2 files changed, 18 insertions(+), 17 deletions(-)
+
+--- a/drivers/vfio/pci/virtio/common.h
++++ b/drivers/vfio/pci/virtio/common.h
+@@ -68,7 +68,7 @@ struct virtiovf_migration_file {
+       enum virtiovf_migf_state state;
+       enum virtiovf_load_state load_state;
+       /* synchronize access to the lists */
+-      spinlock_t list_lock;
++      struct mutex list_lock;
+       struct list_head buf_list;
+       struct list_head avail_list;
+       struct virtiovf_data_buffer *buf;
+--- a/drivers/vfio/pci/virtio/migrate.c
++++ b/drivers/vfio/pci/virtio/migrate.c
+@@ -142,9 +142,9 @@ end:
+ static void virtiovf_put_data_buffer(struct virtiovf_data_buffer *buf)
+ {
+-      spin_lock_irq(&buf->migf->list_lock);
++      mutex_lock(&buf->migf->list_lock);
+       list_add_tail(&buf->buf_elm, &buf->migf->avail_list);
+-      spin_unlock_irq(&buf->migf->list_lock);
++      mutex_unlock(&buf->migf->list_lock);
+ }
+ static int
+@@ -170,21 +170,21 @@ virtiovf_get_data_buffer(struct virtiovf
+       INIT_LIST_HEAD(&free_list);
+-      spin_lock_irq(&migf->list_lock);
++      mutex_lock(&migf->list_lock);
+       list_for_each_entry_safe(buf, temp_buf, &migf->avail_list, buf_elm) {
+               list_del_init(&buf->buf_elm);
+               if (buf->allocated_length >= length) {
+-                      spin_unlock_irq(&migf->list_lock);
++                      mutex_unlock(&migf->list_lock);
+                       goto found;
+               }
+               /*
+                * Prevent holding redundant buffers. Put in a free
+-               * list and call at the end not under the spin lock
++               * list and call at the end not under the mutex
+                * (&migf->list_lock) to minimize its scope usage.
+                */
+               list_add(&buf->buf_elm, &free_list);
+       }
+-      spin_unlock_irq(&migf->list_lock);
++      mutex_unlock(&migf->list_lock);
+       buf = virtiovf_alloc_data_buffer(migf, length);
+ found:
+@@ -295,6 +295,7 @@ static int virtiovf_release_file(struct
+       struct virtiovf_migration_file *migf = filp->private_data;
+       virtiovf_disable_fd(migf);
++      mutex_destroy(&migf->list_lock);
+       mutex_destroy(&migf->lock);
+       kfree(migf);
+       return 0;
+@@ -308,7 +309,7 @@ virtiovf_get_data_buff_from_pos(struct v
+       bool found = false;
+       *end_of_data = false;
+-      spin_lock_irq(&migf->list_lock);
++      mutex_lock(&migf->list_lock);
+       if (list_empty(&migf->buf_list)) {
+               *end_of_data = true;
+               goto end;
+@@ -329,7 +330,7 @@ virtiovf_get_data_buff_from_pos(struct v
+       migf->state = VIRTIOVF_MIGF_STATE_ERROR;
+ end:
+-      spin_unlock_irq(&migf->list_lock);
++      mutex_unlock(&migf->list_lock);
+       return found ? buf : NULL;
+ }
+@@ -369,10 +370,10 @@ static ssize_t virtiovf_buf_read(struct
+       }
+       if (*pos >= vhca_buf->start_pos + vhca_buf->length) {
+-              spin_lock_irq(&vhca_buf->migf->list_lock);
++              mutex_lock(&vhca_buf->migf->list_lock);
+               list_del_init(&vhca_buf->buf_elm);
+               list_add_tail(&vhca_buf->buf_elm, &vhca_buf->migf->avail_list);
+-              spin_unlock_irq(&vhca_buf->migf->list_lock);
++              mutex_unlock(&vhca_buf->migf->list_lock);
+       }
+       return done;
+@@ -554,9 +555,9 @@ virtiovf_add_buf_header(struct virtiovf_
+       header_buf->length = sizeof(header);
+       header_buf->start_pos = header_buf->migf->max_pos;
+       migf->max_pos += header_buf->length;
+-      spin_lock_irq(&migf->list_lock);
++      mutex_lock(&migf->list_lock);
+       list_add_tail(&header_buf->buf_elm, &migf->buf_list);
+-      spin_unlock_irq(&migf->list_lock);
++      mutex_unlock(&migf->list_lock);
+       return 0;
+ }
+@@ -621,9 +622,9 @@ virtiovf_read_device_context_chunk(struc
+       buf->start_pos = buf->migf->max_pos;
+       migf->max_pos += buf->length;
+-      spin_lock(&migf->list_lock);
++      mutex_lock(&migf->list_lock);
+       list_add_tail(&buf->buf_elm, &migf->buf_list);
+-      spin_unlock_irq(&migf->list_lock);
++      mutex_unlock(&migf->list_lock);
+       return 0;
+ out_header:
+@@ -692,7 +693,7 @@ virtiovf_pci_save_device_data(struct vir
+       mutex_init(&migf->lock);
+       INIT_LIST_HEAD(&migf->buf_list);
+       INIT_LIST_HEAD(&migf->avail_list);
+-      spin_lock_init(&migf->list_lock);
++      mutex_init(&migf->list_lock);
+       migf->virtvdev = virtvdev;
+       lockdep_assert_held(&virtvdev->state_mutex);
+@@ -1082,7 +1083,7 @@ virtiovf_pci_resume_device_data(struct v
+       mutex_init(&migf->lock);
+       INIT_LIST_HEAD(&migf->buf_list);
+       INIT_LIST_HEAD(&migf->avail_list);
+-      spin_lock_init(&migf->list_lock);
++      mutex_init(&migf->list_lock);
+       buf = virtiovf_alloc_data_buffer(migf, VIRTIOVF_TARGET_INITIAL_BUF_SIZE);
+       if (IS_ERR(buf)) {
diff --git a/queue-7.0/vfio-xe-add-a-missing-vfio_pci_core_release_dev.patch b/queue-7.0/vfio-xe-add-a-missing-vfio_pci_core_release_dev.patch
new file mode 100644 (file)
index 0000000..8517699
--- /dev/null
@@ -0,0 +1,40 @@
+From 493c7eff3c2ffa94ce3c5e62172948a1e38b491e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20Winiarski?= <michal.winiarski@intel.com>
+Date: Sat, 11 Apr 2026 00:49:48 +0200
+Subject: vfio/xe: Add a missing vfio_pci_core_release_dev()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Winiarski <michal.winiarski@intel.com>
+
+commit 493c7eff3c2ffa94ce3c5e62172948a1e38b491e upstream.
+
+The driver is implementing its own .release(), which means that it needs
+to call vfio_pci_core_release_dev().
+Add the missing call.
+
+Fixes: 1f5556ec8b9ef ("vfio/xe: Add device specific vfio_pci driver variant for Intel graphics")
+Reported-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Closes: https://lore.kernel.org/kvm/408e262c507e8fd628a71e39904fedd99fa0ee8e.camel@linux.ibm.com/
+Cc: stable@vger.kernel.org
+Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
+Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20260410224948.900550-2-michal.winiarski@intel.com
+Signed-off-by: Alex Williamson <alex@shazbot.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vfio/pci/xe/main.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/vfio/pci/xe/main.c
++++ b/drivers/vfio/pci/xe/main.c
+@@ -504,6 +504,7 @@ static void xe_vfio_pci_release_dev(stru
+               container_of(core_vdev, struct xe_vfio_pci_core_device, core_device.vdev);
+       mutex_destroy(&xe_vdev->state_mutex);
++      vfio_pci_core_release_dev(core_vdev);
+ }
+ static const struct vfio_device_ops xe_vfio_pci_ops = {
diff --git a/queue-7.0/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch b/queue-7.0/wifi-mwifiex-fix-use-after-free-in-mwifiex_adapter_cleanup.patch
new file mode 100644 (file)
index 0000000..dfa86f9
--- /dev/null
@@ -0,0 +1,44 @@
+From ae5e95d4157481693be2317e3ffcd84e36010cbb Mon Sep 17 00:00:00 2001
+From: Daniel Hodges <git@danielhodges.dev>
+Date: Fri, 6 Feb 2026 14:44:01 -0500
+Subject: wifi: mwifiex: fix use-after-free in mwifiex_adapter_cleanup()
+
+From: Daniel Hodges <git@danielhodges.dev>
+
+commit ae5e95d4157481693be2317e3ffcd84e36010cbb upstream.
+
+The mwifiex_adapter_cleanup() function uses timer_delete()
+(non-synchronous) for the wakeup_timer before the adapter structure is
+freed. This is incorrect because timer_delete() does not wait for any
+running timer callback to complete.
+
+If the wakeup_timer callback (wakeup_timer_fn) is executing when
+mwifiex_adapter_cleanup() is called, the callback will continue to
+access adapter fields (adapter->hw_status, adapter->if_ops.card_reset,
+etc.) which may be freed by mwifiex_free_adapter() called later in the
+mwifiex_remove_card() path.
+
+Use timer_delete_sync() instead to ensure any running timer callback has
+completed before returning.
+
+Fixes: 4636187da60b ("mwifiex: add wakeup timer based recovery mechanism")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Hodges <git@danielhodges.dev>
+Link: https://patch.msgid.link/20260206194401.2346-1-git@danielhodges.dev
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/mwifiex/init.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/marvell/mwifiex/init.c
++++ b/drivers/net/wireless/marvell/mwifiex/init.c
+@@ -391,7 +391,7 @@ static void mwifiex_invalidate_lists(str
+ static void
+ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
+ {
+-      timer_delete(&adapter->wakeup_timer);
++      timer_delete_sync(&adapter->wakeup_timer);
+       cancel_delayed_work_sync(&adapter->devdump_work);
+       mwifiex_cancel_all_pending_cmd(adapter);
+       wake_up_interruptible(&adapter->cmd_wait_q.wait);
diff --git a/queue-7.0/wifi-rtw88-check-for-pci-upstream-bridge-existence.patch b/queue-7.0/wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
new file mode 100644 (file)
index 0000000..658e479
--- /dev/null
@@ -0,0 +1,44 @@
+From eb101d2abdcccb514ca4fccd3b278dd8267374f6 Mon Sep 17 00:00:00 2001
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+Date: Fri, 20 Feb 2026 12:47:30 +0300
+Subject: wifi: rtw88: check for PCI upstream bridge existence
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+commit eb101d2abdcccb514ca4fccd3b278dd8267374f6 upstream.
+
+pci_upstream_bridge() returns NULL if the device is on a root bus.  If
+8821CE is installed in the system with such a PCI topology, the probing
+routine will crash.  This has probably been unnoticed as 8821CE is mostly
+supplied in laptops where there is a PCI-to-PCI bridge located upstream
+from the device.  However the card might be installed on a system with
+different configuration.
+
+Check if the bridge does exist for the specific workaround to be applied.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace static
+analysis tool.
+
+Fixes: 24f5e38a13b5 ("rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20260220094730.49791-1-pchelkin@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/realtek/rtw88/pci.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/realtek/rtw88/pci.c
++++ b/drivers/net/wireless/realtek/rtw88/pci.c
+@@ -1804,7 +1804,8 @@ int rtw_pci_probe(struct pci_dev *pdev,
+       }
+       /* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */
+-      if (rtwdev->chip->id == RTW_CHIP_TYPE_8821C && bridge->vendor == PCI_VENDOR_ID_INTEL)
++      if (rtwdev->chip->id == RTW_CHIP_TYPE_8821C &&
++          bridge && bridge->vendor == PCI_VENDOR_ID_INTEL)
+               rtwpci->rx_no_aspm = true;
+       rtw_pci_phy_cfg(rtwdev);
diff --git a/queue-7.0/zram-do-not-forget-to-endio-for-partial-discard-requests.patch b/queue-7.0/zram-do-not-forget-to-endio-for-partial-discard-requests.patch
new file mode 100644 (file)
index 0000000..038d91d
--- /dev/null
@@ -0,0 +1,59 @@
+From e3668b371329ea036ff022ce8ecc82f8befcf003 Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <senozhatsky@chromium.org>
+Date: Tue, 31 Mar 2026 16:42:44 +0900
+Subject: zram: do not forget to endio for partial discard requests
+
+From: Sergey Senozhatsky <senozhatsky@chromium.org>
+
+commit e3668b371329ea036ff022ce8ecc82f8befcf003 upstream.
+
+As reported by Qu Wenruo and Avinesh Kumar, the following
+
+ getconf PAGESIZE
+ 65536
+ blkdiscard -p 4k /dev/zram0
+
+takes literally forever to complete.  zram doesn't support partial
+discards and just returns immediately w/o doing any discard work in such
+cases.  The problem is that we forget to endio on our way out, so
+blkdiscard sleeps forever in submit_bio_wait().  Fix this by jumping to
+end_bio label, which does bio_endio().
+
+Link: https://lore.kernel.org/20260331074255.777019-1-senozhatsky@chromium.org
+Fixes: 0120dd6e4e20 ("zram: make zram_bio_discard more self-contained")
+Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reported-by: Qu Wenruo <wqu@suse.com>
+Closes: https://lore.kernel.org/linux-block/92361cd3-fb8b-482e-bc89-15ff1acb9a59@suse.com
+Tested-by: Qu Wenruo <wqu@suse.com>
+Reported-by: Avinesh Kumar <avinesh.kumar@suse.com>
+Closes: https://bugzilla.suse.com/show_bug.cgi?id=1256530
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Brian Geffon <bgeffon@google.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -2697,7 +2697,7 @@ static void zram_bio_discard(struct zram
+        */
+       if (offset) {
+               if (n <= (PAGE_SIZE - offset))
+-                      return;
++                      goto end_bio;
+               n -= (PAGE_SIZE - offset);
+               index++;
+@@ -2712,6 +2712,7 @@ static void zram_bio_discard(struct zram
+               n -= PAGE_SIZE;
+       }
++end_bio:
+       bio_endio(bio);
+ }