FAILED: patch "[PATCH] xen-blkfront: unbind irq before tearing down ring and shadow" failed to apply to 5.15-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x f3e27b7955727a4d7c0e9264a2a209fbba788bdc
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110402-division-regulate-7540@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f3e27b7955727a4d7c0e9264a2a209fbba788bdc Mon Sep 17 00:00:00 2001
From: Yuchao Zhang <[email protected]>
Date: Tue, 22 Sep 2026 15:21:55 +0800
Subject: [PATCH] xen-blkfront: unbind irq before tearing down ring and shadow
requests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In blkif_free_ring(), the driver tears down the ring's persistent grants, shadow request arrays, and shared ring structure (xenbus_teardown_ring), and only calls unbind_from_irqhandler() at the very end.
While blkif_free_ring() is freeing persistent grants and clearing the shadow array, the event channel interrupt (blkif_interrupt) is still registered and active. If an interrupt arrives from the backend during this teardown window, blkif_interrupt() reads rinfo->ring.sring and, via blkif_completion(), accesses rinfo->shadow[id].grants_used and rinfo->shadow[id].sg. blkif_free_ring() tears these structures down without holding rinfo->ring_lock, and the handler only checks info->connected at entry, so this is a real race resulting in a use-after-free or NULL pointer dereference.
Fix this by moving unbind_from_irqhandler() to the beginning of blkif_free_ring(). Calling unbind_from_irqhandler() first frees the IRQ and synchronizes with any in-flight interrupt handlers on other CPUs before ring memory and shadow request structures are deallocated, matching the teardown order in drivers/net/xen-netfront.c.
Message-ID: <[email protected]>
drivers/block/xen-blkfront.c +8 -4
@@ -1210,6 +1210,14 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)struct blkfront_info *info = rinfo->dev_info;int i, j, segs; +/* +* Interrupt teardown must be done ahead of freeing queue-related +* data, otherwise the interrupt handler can race with the cleanup. +*/ +if (rinfo->irq) +unbind_from_irqhandler (rinfo->irq, rinfo); + rinfo->evtchn = rinfo->irq =0 ; +/* * Remove indirect pages, this only happens when using indirect * descriptors but not persistent grants
@@ -1292,10 +1300,6 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)/* Free resources associated with old device channel. */ xenbus_teardown_ring ((void **)&rinfo->ring.sring, info->nr_ring_pages, rinfo->ring_ref); - -if (rinfo->irq) -unbind_from_irqhandler (rinfo->irq, rinfo); - rinfo->evtchn = rinfo->irq =0 ; }static void blkif_free (struct blkfront_info *info,int suspend)
Sasha Levin
maintainerPATCH 1/1 xen-blkfront: unbind irq before tearing down ring and shadow requests
From: Yuchao Zhang <[email protected]>
[ Upstream commit f3e27b7955727a4d7c0e9264a2a209fbba788bdc ]
In blkif_free_ring(), the driver tears down the ring's persistent grants, shadow request arrays, and shared ring structure (xenbus_teardown_ring), and only calls unbind_from_irqhandler() at the very end.
While blkif_free_ring() is freeing persistent grants and clearing the shadow array, the event channel interrupt (blkif_interrupt) is still registered and active. If an interrupt arrives from the backend during this teardown window, blkif_interrupt() reads rinfo->ring.sring and, via blkif_completion(), accesses rinfo->shadow[id].grants_used and rinfo->shadow[id].sg. blkif_free_ring() tears these structures down without holding rinfo->ring_lock, and the handler only checks info->connected at entry, so this is a real race resulting in a use-after-free or NULL pointer dereference.
Fix this by moving unbind_from_irqhandler() to the beginning of blkif_free_ring(). Calling unbind_from_irqhandler() first frees the IRQ and synchronizes with any in-flight interrupt handlers on other CPUs before ring memory and shadow request structures are deallocated, matching the teardown order in drivers/net/xen-netfront.c.
Message-ID: <[email protected]>
--- drivers/block/xen-blkfront.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/block/xen-blkfront.c +8 -4
@@ -1215,6 +1215,14 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)struct blkfront_info *info = rinfo->dev_info;int i, j, segs; +/* +* Interrupt teardown must be done ahead of freeing queue-related +* data, otherwise the interrupt handler can race with the cleanup. +*/ +if (rinfo->irq) +unbind_from_irqhandler (rinfo->irq, rinfo); + rinfo->evtchn = rinfo->irq =0 ; +/* * Remove indirect pages, this only happens when using indirect * descriptors but not persistent grants
@@ -1304,10 +1312,6 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)free_pages_exact (rinfo->ring.sring, info->nr_ring_pages *XEN_PAGE_SIZE ); rinfo->ring.sring =NULL ; - -if (rinfo->irq) -unbind_from_irqhandler (rinfo->irq, rinfo); - rinfo->evtchn = rinfo->irq =0 ; }static void blkif_free (struct blkfront_info *info,int suspend)
Signature · 1 line
2.53.0