--- /dev/null
+From 55db009926634b20955bd8abbee921adbc8d2cb4 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Fri, 20 Feb 2026 12:09:12 +0900
+Subject: ata: libata-core: fix cancellation of a port deferred qc work
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit 55db009926634b20955bd8abbee921adbc8d2cb4 upstream.
+
+cancel_work_sync() is a sleeping function so it cannot be called with
+the spin lock of a port being held. Move the call to this function in
+ata_port_detach() after EH completes, with the port lock released,
+together with other work cancellation calls.
+
+Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-core.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -6233,10 +6233,6 @@ static void ata_port_detach(struct ata_p
+ }
+ }
+
+- /* Make sure the deferred qc work finished. */
+- cancel_work_sync(&ap->deferred_qc_work);
+- WARN_ON(ap->deferred_qc);
+-
+ /* Tell EH to disable all devices */
+ ap->pflags |= ATA_PFLAG_UNLOADING;
+ ata_port_schedule_eh(ap);
+@@ -6247,9 +6243,11 @@ static void ata_port_detach(struct ata_p
+ /* wait till EH commits suicide */
+ ata_port_wait_eh(ap);
+
+- /* it better be dead now */
++ /* It better be dead now and not have any remaining deferred qc. */
+ WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
++ WARN_ON(ap->deferred_qc);
+
++ cancel_work_sync(&ap->deferred_qc_work);
+ cancel_delayed_work_sync(&ap->hotplug_task);
+ cancel_delayed_work_sync(&ap->scsi_rescan_task);
+
--- /dev/null
+From eddb98ad9364b4e778768785d46cfab04ce52100 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Fri, 20 Feb 2026 13:43:00 +0900
+Subject: ata: libata-eh: correctly handle deferred qc timeouts
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit eddb98ad9364b4e778768785d46cfab04ce52100 upstream.
+
+A deferred qc may timeout while waiting for the device queue to drain
+to be submitted. In such case, since the qc is not active,
+ata_scsi_cmd_error_handler() ends up calling scsi_eh_finish_cmd(),
+which frees the qc. But as the port deferred_qc field still references
+this finished/freed qc, the deferred qc work may eventually attempt to
+call ata_qc_issue() against this invalid qc, leading to errors such as
+reported by UBSAN (syzbot run):
+
+UBSAN: shift-out-of-bounds in drivers/ata/libata-core.c:5166:24
+shift exponent 4210818301 is too large for 64-bit type 'long long unsigned int'
+...
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ ubsan_epilogue+0xa/0x30 lib/ubsan.c:233
+ __ubsan_handle_shift_out_of_bounds+0x279/0x2a0 lib/ubsan.c:494
+ ata_qc_issue.cold+0x38/0x9f drivers/ata/libata-core.c:5166
+ ata_scsi_deferred_qc_work+0x154/0x1f0 drivers/ata/libata-scsi.c:1679
+ process_one_work+0x9d7/0x1920 kernel/workqueue.c:3275
+ process_scheduled_works kernel/workqueue.c:3358 [inline]
+ worker_thread+0x5da/0xe40 kernel/workqueue.c:3439
+ kthread+0x370/0x450 kernel/kthread.c:467
+ ret_from_fork+0x754/0xd80 arch/x86/kernel/process.c:158
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+Fix this by checking if the qc of a timed out SCSI command is a deferred
+one, and in such case, clear the port deferred_qc field and finish the
+SCSI command with DID_TIME_OUT.
+
+Reported-by: syzbot+1f77b8ca15336fff21ff@syzkaller.appspotmail.com
+Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-eh.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -640,12 +640,28 @@ void ata_scsi_cmd_error_handler(struct S
+ set_host_byte(scmd, DID_OK);
+
+ ata_qc_for_each_raw(ap, qc, i) {
+- if (qc->flags & ATA_QCFLAG_ACTIVE &&
+- qc->scsicmd == scmd)
++ if (qc->scsicmd != scmd)
++ continue;
++ if ((qc->flags & ATA_QCFLAG_ACTIVE) ||
++ qc == ap->deferred_qc)
+ break;
+ }
+
+- if (i < ATA_MAX_QUEUE) {
++ if (qc == ap->deferred_qc) {
++ /*
++ * This is a deferred command that timed out while
++ * waiting for the command queue to drain. Since the qc
++ * is not active yet (deferred_qc is still set, so the
++ * deferred qc work has not issued the command yet),
++ * simply signal the timeout by finishing the SCSI
++ * command and clear the deferred qc to prevent the
++ * deferred qc work from issuing this qc.
++ */
++ WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);
++ ap->deferred_qc = NULL;
++ set_host_byte(scmd, DID_TIME_OUT);
++ scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
++ } else if (i < ATA_MAX_QUEUE) {
+ /* the scmd has an associated qc */
+ if (!(qc->flags & ATA_QCFLAG_EH)) {
+ /* which hasn't failed yet, timeout */