]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Oct 2025 08:27:57 +0000 (10:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Oct 2025 08:27:57 +0000 (10:27 +0200)
added patches:
uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch

queue-5.4/series
queue-5.4/uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch [new file with mode: 0644]

index 06bc8ce472e9f165bf166f26f83112fc9ca9ab0d..16eb552257591da7d54a54137189574e9d93921d 100644 (file)
@@ -71,3 +71,4 @@ nfp-fix-rss-hash-key-size-when-rss-is-not-supported.patch
 net-ena-return-0-in-ena_get_rxfh_key_size-when-rss-h.patch
 revert-net-mlx5e-update-and-set-xon-xoff-upon-mtu-se.patch
 squashfs-fix-uninit-value-in-squashfs_get_parent.patch
+uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch
diff --git a/queue-5.4/uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch b/queue-5.4/uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch
new file mode 100644 (file)
index 0000000..2ffd512
--- /dev/null
@@ -0,0 +1,97 @@
+From b15b7d2a1b09ef5428a8db260251897405a19496 Mon Sep 17 00:00:00 2001
+From: Naman Jain <namjain@linux.microsoft.com>
+Date: Thu, 28 Aug 2025 10:12:00 +0530
+Subject: uio_hv_generic: Let userspace take care of interrupt mask
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Naman Jain <namjain@linux.microsoft.com>
+
+commit b15b7d2a1b09ef5428a8db260251897405a19496 upstream.
+
+Remove the logic to set interrupt mask by default in uio_hv_generic
+driver as the interrupt mask value is supposed to be controlled
+completely by the user space. If the mask bit gets changed
+by the driver, concurrently with user mode operating on the ring,
+the mask bit may be set when it is supposed to be clear, and the
+user-mode driver will miss an interrupt which will cause a hang.
+
+For eg- when the driver sets inbound ring buffer interrupt mask to 1,
+the host does not interrupt the guest on the UIO VMBus channel.
+However, setting the mask does not prevent the host from putting a
+message in the inbound ring buffer. So let’s assume that happens,
+the host puts a message into the ring buffer but does not interrupt.
+
+Subsequently, the user space code in the guest sets the inbound ring
+buffer interrupt mask to 0, saying “Hey, I’m ready for interrupts”.
+User space code then calls pread() to wait for an interrupt.
+Then one of two things happens:
+
+* The host never sends another message. So the pread() waits forever.
+* The host does send another message. But because there’s already a
+  message in the ring buffer, it doesn’t generate an interrupt.
+  This is the correct behavior, because the host should only send an
+  interrupt when the inbound ring buffer transitions from empty to
+  not-empty. Adding an additional message to a ring buffer that is not
+  empty is not supposed to generate an interrupt on the guest.
+  Since the guest is waiting in pread() and not removing messages from
+  the ring buffer, the pread() waits forever.
+
+This could be easily reproduced in hv_fcopy_uio_daemon if we delay
+setting interrupt mask to 0.
+
+Similarly if hv_uio_channel_cb() sets the interrupt_mask to 1,
+there’s a race condition. Once user space empties the inbound ring
+buffer, but before user space sets interrupt_mask to 0, the host could
+put another message in the ring buffer but it wouldn’t interrupt.
+Then the next pread() would hang.
+
+Fix these by removing all instances where interrupt_mask is changed,
+while keeping the one in set_event() unchanged to enable userspace
+control the interrupt mask by writing 0/1 to /dev/uioX.
+
+Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus")
+Suggested-by: John Starks <jostarks@microsoft.com>
+Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Reviewed-by: Tianyu Lan <tiala@microsoft.com>
+Tested-by: Tianyu Lan <tiala@microsoft.com>
+Link: https://lore.kernel.org/r/20250828044200.492030-1-namjain@linux.microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/uio/uio_hv_generic.c |    7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/uio/uio_hv_generic.c
++++ b/drivers/uio/uio_hv_generic.c
+@@ -96,7 +96,6 @@ static void hv_uio_channel_cb(void *cont
+       struct hv_device *hv_dev = chan->device_obj;
+       struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
+-      chan->inbound.ring_buffer->interrupt_mask = 1;
+       virt_mb();
+       uio_event_notify(&pdata->info);
+@@ -173,8 +172,6 @@ hv_uio_new_channel(struct vmbus_channel
+               return;
+       }
+-      /* Disable interrupts on sub channel */
+-      new_sc->inbound.ring_buffer->interrupt_mask = 1;
+       set_channel_read_mode(new_sc, HV_CALL_ISR);
+       ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr);
+@@ -218,9 +215,7 @@ hv_uio_open(struct uio_info *info, struc
+       ret = vmbus_connect_ring(dev->channel,
+                                hv_uio_channel_cb, dev->channel);
+-      if (ret == 0)
+-              dev->channel->inbound.ring_buffer->interrupt_mask = 1;
+-      else
++      if (ret)
+               atomic_dec(&pdata->refcnt);
+       return ret;