From: Greg Kroah-Hartman Date: Wed, 17 Jun 2026 03:26:22 +0000 (+0530) Subject: 5.15-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b68cbf4f39c9bd166434731db01f66ffc6ad959b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch ata-libata-scsi-link-ata-port-and-scsi-device.patch ata-scsi-do-not-issue-start-stop-unit-on-resume.patch batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.patch media-rc-igorplugusb-fix-control-request-setup-packet.patch media-rc-ttusbir-fix-inverted-error-logic.patch nvme-fix-discard-support-without-oncs.patch scsi-core-declare-scsi_scan_type-static.patch scsi-core-suppress-a-kernel-doc-warning.patch scsi-sd-rework-asynchronous-resume-support.patch scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch --- diff --git a/queue-5.15/ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch b/queue-5.15/ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch new file mode 100644 index 0000000000..a6b47861ae --- /dev/null +++ b/queue-5.15/ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch @@ -0,0 +1,132 @@ +From 6aa0365a3c8512587fffd42fe438768709ddef8e Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 15 Jun 2023 17:18:53 +0900 +Subject: ata: libata-scsi: Avoid deadlock on rescan after device resume + +From: Damien Le Moal + +commit 6aa0365a3c8512587fffd42fe438768709ddef8e upstream. + +When an ATA port is resumed from sleep, the port is reset and a power +management request issued to libata EH to reset the port and rescanning +the device(s) attached to the port. Device rescanning is done by +scheduling an ata_scsi_dev_rescan() work, which will execute +scsi_rescan_device(). + +However, scsi_rescan_device() takes the generic device lock, which is +also taken by dpm_resume() when the SCSI device is resumed as well. If +a device rescan execution starts before the completion of the SCSI +device resume, the rcu locking used to refresh the cached VPD pages of +the device, combined with the generic device locking from +scsi_rescan_device() and from dpm_resume() can cause a deadlock. + +Avoid this situation by changing struct ata_port scsi_rescan_task to be +a delayed work instead of a simple work_struct. ata_scsi_dev_rescan() is +modified to check if the SCSI device associated with the ATA device that +must be rescanned is not suspended. If the SCSI device is still +suspended, ata_scsi_dev_rescan() returns early and reschedule itself for +execution after an arbitrary delay of 5ms. + +Reported-by: Kai-Heng Feng +Reported-by: Joe Breuer +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217530 +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Tested-by: Kai-Heng Feng +Tested-by: Joe Breuer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-core.c | 3 ++- + drivers/ata/libata-eh.c | 2 +- + drivers/ata/libata-scsi.c | 22 +++++++++++++++++++++- + include/linux/libata.h | 2 +- + 4 files changed, 25 insertions(+), 4 deletions(-) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5340,7 +5340,7 @@ struct ata_port *ata_port_alloc(struct a + + mutex_init(&ap->scsi_scan_mutex); + INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); +- INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); ++ INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); + INIT_LIST_HEAD(&ap->eh_done_q); + init_waitqueue_head(&ap->eh_wait_q); + init_completion(&ap->park_req_pending); +@@ -5974,6 +5974,7 @@ static void ata_port_detach(struct ata_p + WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); + + cancel_delayed_work_sync(&ap->hotplug_task); ++ cancel_delayed_work_sync(&ap->scsi_rescan_task); + + skip_eh: + /* clean up zpodd on port removal */ +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2957,7 +2957,7 @@ static int ata_eh_revalidate_and_attach( + ehc->i.flags |= ATA_EHI_SETMODE; + + /* schedule the scsi_rescan_device() here */ +- schedule_work(&(ap->scsi_rescan_task)); ++ schedule_delayed_work(&ap->scsi_rescan_task, 0); + } else if (dev->class == ATA_DEV_UNKNOWN && + ehc->tries[dev->devno] && + ata_class_enabled(ehc->classes[dev->devno])) { +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -4598,10 +4598,11 @@ int ata_scsi_user_scan(struct Scsi_Host + void ata_scsi_dev_rescan(struct work_struct *work) + { + struct ata_port *ap = +- container_of(work, struct ata_port, scsi_rescan_task); ++ container_of(work, struct ata_port, scsi_rescan_task.work); + struct ata_link *link; + struct ata_device *dev; + unsigned long flags; ++ bool delay_rescan = false; + + mutex_lock(&ap->scsi_scan_mutex); + spin_lock_irqsave(ap->lock, flags); +@@ -4615,6 +4616,21 @@ void ata_scsi_dev_rescan(struct work_str + if (scsi_device_get(sdev)) + continue; + ++ /* ++ * If the rescan work was scheduled because of a resume ++ * event, the port is already fully resumed, but the ++ * SCSI device may not yet be fully resumed. In such ++ * case, executing scsi_rescan_device() may cause a ++ * deadlock with the PM code on device_lock(). Prevent ++ * this by giving up and retrying rescan after a short ++ * delay. ++ */ ++ delay_rescan = sdev->sdev_gendev.power.is_suspended; ++ if (delay_rescan) { ++ scsi_device_put(sdev); ++ break; ++ } ++ + spin_unlock_irqrestore(ap->lock, flags); + scsi_rescan_device(&(sdev->sdev_gendev)); + scsi_device_put(sdev); +@@ -4624,4 +4640,8 @@ void ata_scsi_dev_rescan(struct work_str + + spin_unlock_irqrestore(ap->lock, flags); + mutex_unlock(&ap->scsi_scan_mutex); ++ ++ if (delay_rescan) ++ schedule_delayed_work(&ap->scsi_rescan_task, ++ msecs_to_jiffies(5)); + } +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -874,7 +874,7 @@ struct ata_port { + + struct mutex scsi_scan_mutex; + struct delayed_work hotplug_task; +- struct work_struct scsi_rescan_task; ++ struct delayed_work scsi_rescan_task; + + unsigned int hsm_task_state; + diff --git a/queue-5.15/ata-libata-scsi-link-ata-port-and-scsi-device.patch b/queue-5.15/ata-libata-scsi-link-ata-port-and-scsi-device.patch new file mode 100644 index 0000000000..b0f04cd47b --- /dev/null +++ b/queue-5.15/ata-libata-scsi-link-ata-port-and-scsi-device.patch @@ -0,0 +1,129 @@ +From fb99ef17865035a6657786d4b2af11a27ba23f9b Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Fri, 25 Aug 2023 15:41:14 +0900 +Subject: ata: libata-scsi: link ata port and scsi device + +From: Damien Le Moal + +commit fb99ef17865035a6657786d4b2af11a27ba23f9b upstream. + +There is no direct device ancestry defined between an ata_device and +its scsi device which prevents the power management code from correctly +ordering suspend and resume operations. Create such ancestry with the +ata device as the parent to ensure that the scsi device (child) is +suspended before the ata device and that resume handles the ata device +before the scsi device. + +The parent-child (supplier-consumer) relationship is established between +the ata_port (parent) and the scsi device (child) with the function +device_add_link(). The parent used is not the ata_device as the PM +operations are defined per port and the status of all devices connected +through that port is controlled from the port operations. + +The device link is established with the new function +ata_scsi_slave_alloc(), and this function is used to define the +->slave_alloc callback of the scsi host template of all ata drivers. + +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Reviewed-by: Niklas Cassel +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Reviewed-by: John Garry +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-scsi.c | 45 ++++++++++++++++++++++++++++++++++++++++----- + include/linux/libata.h | 2 ++ + 2 files changed, 42 insertions(+), 5 deletions(-) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -1104,6 +1104,42 @@ int ata_scsi_dev_config(struct scsi_devi + } + + /** ++ * ata_scsi_slave_alloc - Early setup of SCSI device ++ * @sdev: SCSI device to examine ++ * ++ * This is called from scsi_alloc_sdev() when the scsi device ++ * associated with an ATA device is scanned on a port. ++ * ++ * LOCKING: ++ * Defined by SCSI layer. We don't really care. ++ */ ++ ++int ata_scsi_slave_alloc(struct scsi_device *sdev) ++{ ++ struct ata_port *ap = ata_shost_to_port(sdev->host); ++ struct device_link *link; ++ ++ ata_scsi_sdev_config(sdev); ++ ++ /* ++ * Create a link from the ata_port device to the scsi device to ensure ++ * that PM does suspend/resume in the correct order: the scsi device is ++ * consumer (child) and the ata port the supplier (parent). ++ */ ++ link = device_link_add(&sdev->sdev_gendev, &ap->tdev, ++ DL_FLAG_STATELESS | ++ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); ++ if (!link) { ++ ata_port_err(ap, "Failed to create link to scsi device %s\n", ++ dev_name(&sdev->sdev_gendev)); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); ++ ++/** + * ata_scsi_slave_config - Set SCSI device attributes + * @sdev: SCSI device to examine + * +@@ -1119,14 +1155,11 @@ int ata_scsi_slave_config(struct scsi_de + { + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); +- int rc = 0; +- +- ata_scsi_sdev_config(sdev); + + if (dev) +- rc = ata_scsi_dev_config(sdev, dev); ++ return ata_scsi_dev_config(sdev, dev); + +- return rc; ++ return 0; + } + EXPORT_SYMBOL_GPL(ata_scsi_slave_config); + +@@ -1153,6 +1186,8 @@ void ata_scsi_slave_destroy(struct scsi_ + if (!ap->ops->error_handler) + return; + ++ device_link_remove(&sdev->sdev_gendev, &ap->tdev); ++ + spin_lock_irqsave(ap->lock, flags); + dev = __ata_scsi_find_dev(ap, sdev); + if (dev && dev->sdev) { +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -1168,6 +1168,7 @@ extern int ata_std_bios_param(struct scs + struct block_device *bdev, + sector_t capacity, int geom[]); + extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); ++extern int ata_scsi_slave_alloc(struct scsi_device *sdev); + extern int ata_scsi_slave_config(struct scsi_device *sdev); + extern void ata_scsi_slave_destroy(struct scsi_device *sdev); + extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, +@@ -1416,6 +1417,7 @@ extern struct device_attribute *ata_comm + .this_id = ATA_SHT_THIS_ID, \ + .emulated = ATA_SHT_EMULATED, \ + .proc_name = drv_name, \ ++ .slave_alloc = ata_scsi_slave_alloc, \ + .slave_destroy = ata_scsi_slave_destroy, \ + .bios_param = ata_std_bios_param, \ + .unlock_native_capacity = ata_scsi_unlock_native_capacity diff --git a/queue-5.15/ata-scsi-do-not-issue-start-stop-unit-on-resume.patch b/queue-5.15/ata-scsi-do-not-issue-start-stop-unit-on-resume.patch new file mode 100644 index 0000000000..f6aeaac8c0 --- /dev/null +++ b/queue-5.15/ata-scsi-do-not-issue-start-stop-unit-on-resume.patch @@ -0,0 +1,113 @@ +From 0a8589055936d8feb56477123a8373ac634018fa Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Mon, 24 Jul 2023 13:23:14 +0900 +Subject: ata,scsi: do not issue START STOP UNIT on resume + +From: Damien Le Moal + +commit 0a8589055936d8feb56477123a8373ac634018fa upstream. + +During system resume, ata_port_pm_resume() triggers ata EH to +1) Resume the controller +2) Reset and rescan the ports +3) Revalidate devices +This EH execution is started asynchronously from ata_port_pm_resume(), +which means that when sd_resume() is executed, none or only part of the +above processing may have been executed. However, sd_resume() issues a +START STOP UNIT to wake up the drive from sleep mode. This command is +translated to ATA with ata_scsi_start_stop_xlat() and issued to the +device. However, depending on the state of execution of the EH process +and revalidation triggerred by ata_port_pm_resume(), two things may +happen: +1) The START STOP UNIT fails if it is received before the controller has + been reenabled at the beginning of the EH execution. This is visible + with error messages like: + +ata10.00: device reported invalid CHS sector 0 +sd 9:0:0:0: [sdc] Start/Stop Unit failed: Result: hostbyte=DID_OK driverbyte=DRIVER_OK +sd 9:0:0:0: [sdc] Sense Key : Illegal Request [current] +sd 9:0:0:0: [sdc] Add. Sense: Unaligned write command +sd 9:0:0:0: PM: dpm_run_callback(): scsi_bus_resume+0x0/0x90 returns -5 +sd 9:0:0:0: PM: failed to resume async: error -5 + +2) The START STOP UNIT command is received while the EH process is + on-going, which mean that it is stopped and must wait for its + completion, at which point the command is rather useless as the drive + is already fully spun up already. This case results also in a + significant delay in sd_resume() which is observable by users as + the entire system resume completion is delayed. + +Given that ATA devices will be woken up by libata activity on resume, +sd_resume() has no need to issue a START STOP UNIT command, which solves +the above mentioned problems. Do not issue this command by introducing +the new scsi_device flag no_start_on_resume and setting this flag to 1 +in ata_scsi_dev_config(). sd_resume() is modified to issue a START STOP +UNIT command only if this flag is not set. + +Reported-by: Paul Ausbeck +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215880 +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Signed-off-by: Damien Le Moal +Tested-by: Tanner Watkins +Tested-by: Paul Ausbeck +Reviewed-by: Hannes Reinecke +Reviewed-by: Bart Van Assche +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-scsi.c | 7 +++++++ + drivers/scsi/sd.c | 9 ++++++--- + include/scsi/scsi_device.h | 1 + + 3 files changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -1061,7 +1061,14 @@ int ata_scsi_dev_config(struct scsi_devi + } + } else { + sdev->sector_size = ata_id_logical_sector_size(dev->id); ++ /* ++ * Stop the drive on suspend but do not issue START STOP UNIT ++ * on resume as this is not necessary and may fail: the device ++ * will be woken up by ata_port_pm_resume() with a port reset ++ * and device revalidation. ++ */ + sdev->manage_start_stop = 1; ++ sdev->no_start_on_resume = 1; + } + + /* +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3729,7 +3729,7 @@ static int sd_suspend_runtime(struct dev + static int sd_resume(struct device *dev) + { + struct scsi_disk *sdkp = dev_get_drvdata(dev); +- int ret; ++ int ret = 0; + + if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ + return 0; +@@ -3737,8 +3737,11 @@ static int sd_resume(struct device *dev) + if (!sdkp->device->manage_start_stop) + return 0; + +- sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); +- ret = sd_start_stop_device(sdkp, 1); ++ if (!sdkp->device->no_start_on_resume) { ++ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); ++ ret = sd_start_stop_device(sdkp, 1); ++ } ++ + if (!ret) + opal_unlock_from_suspend(sdkp->opal_dev); + return ret; +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -185,6 +185,7 @@ struct scsi_device { + unsigned no_start_on_add:1; /* do not issue start on add */ + unsigned allow_restart:1; /* issue START_UNIT in error handler */ + unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ ++ unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ + unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ + unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ + unsigned select_no_atn:1; diff --git a/queue-5.15/batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch b/queue-5.15/batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch new file mode 100644 index 0000000000..aff70cdc99 --- /dev/null +++ b/queue-5.15/batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch @@ -0,0 +1,91 @@ +From 77098e4bea37af51d3962efa88a5af2ea5e1ac57 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sun, 10 May 2026 11:31:03 +0200 +Subject: batman-adv: tp_meter: fix tp_vars reference leak in receiver shutdown + +From: Sven Eckelmann + +commit 77098e4bea37af51d3962efa88a5af2ea5e1ac57 upstream. + +The receiver shutdown timer handler, batadv_tp_receiver_shutdown(), is +responsible for releasing the tp_vars reference it holds. However, the +existing logic for coordinating this release with batadv_tp_stop_all() was +flawed. + +timer_shutdown_sync() guarantees the timer will not fire again after it +returns, but it returns non-zero only when the timer was pending at the +time of the call. If the timer had already expired (and +batadv_tp_stop_all() would unsucessfully try to rearm itself), +batadv_tp_stop_all() skips its batadv_tp_vars_put(), and +batadv_tp_receiver_shutdown() fails to put its own reference as well. + +Fix this by introducing a new atomic variable receiving that is set to 1 +when the receiver is initialized and cleared atomically with atomic_xchg() +by whichever side claims it first. Only the side that observes the +transition from 1 to 0 is responsible for releasing the tp_vars timer +reference, eliminating the uncertainty. + +Cc: stable@kernel.org +Fixes: 3d3cf6a7314a ("batman-adv: stop tp_meter sessions during mesh teardown") +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + net/batman-adv/tp_meter.c | 13 +++++++++++-- + net/batman-adv/types.h | 3 +++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/net/batman-adv/tp_meter.c ++++ b/net/batman-adv/tp_meter.c +@@ -8,6 +8,7 @@ + #include "main.h" + + #include ++#include + #include + #include + #include +@@ -1157,6 +1158,9 @@ static void batadv_tp_receiver_shutdown( + spin_unlock_bh(&tp_vars->unacked_lock); + + /* drop reference of timer */ ++ if (WARN_ON(atomic_xchg(&tp_vars->receiving, 0) != 1)) ++ return; ++ + batadv_tp_vars_put(tp_vars); + } + +@@ -1375,6 +1379,7 @@ batadv_tp_init_recv(struct batadv_priv * + + ether_addr_copy(tp_vars->other_end, icmp->orig); + tp_vars->role = BATADV_TP_RECEIVER; ++ atomic_set(&tp_vars->receiving, 1); + memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session)); + tp_vars->last_recv = BATADV_TP_FIRST_SEQ; + tp_vars->bat_priv = bat_priv; +@@ -1547,8 +1552,12 @@ void batadv_tp_stop_all(struct batadv_pr + break; + case BATADV_TP_RECEIVER: + batadv_tp_list_detach(tp_var); +- if (timer_shutdown_sync(&tp_var->timer)) +- batadv_tp_vars_put(tp_var); ++ timer_shutdown_sync(&tp_var->timer); ++ ++ if (atomic_xchg(&tp_var->receiving, 0) != 1) ++ break; ++ ++ batadv_tp_vars_put(tp_var); + break; + } + +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -1400,6 +1400,9 @@ struct batadv_tp_vars { + /** @sending: sending binary semaphore: 1 if sending, 0 is not */ + atomic_t sending; + ++ /** @receiving: receiving binary semaphore: 1 if receiving, 0 is not */ ++ atomic_t receiving; ++ + /** @reason: reason for a stopped session */ + enum batadv_tp_meter_reason reason; + diff --git a/queue-5.15/crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.patch b/queue-5.15/crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.patch new file mode 100644 index 0000000000..8068a81239 --- /dev/null +++ b/queue-5.15/crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.patch @@ -0,0 +1,46 @@ +From 344e6a4f7ff4756b9b3f75e0eb7eaec297e35540 Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +Date: Wed, 11 Mar 2026 16:56:49 +0100 +Subject: crypto: nx - fix context leak in nx842_crypto_free_ctx + +From: Thorsten Blum + +commit 344e6a4f7ff4756b9b3f75e0eb7eaec297e35540 upstream. + +Since the scomp conversion, nx842_crypto_alloc_ctx() allocates the +context separately, but nx842_crypto_free_ctx() never releases it. Add +the missing kfree(ctx) to nx842_crypto_free_ctx(), and reuse +nx842_crypto_free_ctx() in the allocation error path. + +Fixes: 980b5705f4e7 ("crypto: nx - Migrate to scomp API") +Cc: stable@vger.kernel.org +Signed-off-by: Thorsten Blum +Reviewed-by: Ard Biesheuvel +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/nx/nx-842.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/crypto/nx/nx-842.c ++++ b/drivers/crypto/nx/nx-842.c +@@ -115,10 +115,7 @@ void *nx842_crypto_alloc_ctx(struct nx84 + ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); + ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); + if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) { +- kfree(ctx->wmem); +- free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER); +- free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER); +- kfree(ctx); ++ nx842_crypto_free_ctx(ctx); + return ERR_PTR(-ENOMEM); + } + +@@ -133,6 +130,7 @@ void nx842_crypto_free_ctx(void *p) + kfree(ctx->wmem); + free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER); + free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER); ++ kfree(ctx); + } + EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx); + diff --git a/queue-5.15/media-rc-igorplugusb-fix-control-request-setup-packet.patch b/queue-5.15/media-rc-igorplugusb-fix-control-request-setup-packet.patch new file mode 100644 index 0000000000..20c67af4ca --- /dev/null +++ b/queue-5.15/media-rc-igorplugusb-fix-control-request-setup-packet.patch @@ -0,0 +1,50 @@ +From 171022c7d594c133a45f92357a2a91475edabe20 Mon Sep 17 00:00:00 2001 +From: Henri A +Date: Wed, 20 May 2026 10:25:44 -0400 +Subject: media: rc: igorplugusb: fix control request setup packet + +From: Henri A + +commit 171022c7d594c133a45f92357a2a91475edabe20 upstream. + +Commit eac69475b01f ("media: rc: igorplugusb: heed coherency +rules") changed the control request storage from an embedded struct to +an allocated pointer so it can obey DMA coherency rules. + +However, the driver still passes &ir->request to usb_fill_control_urb(). +That points the URB setup packet at the pointer field itself rather than +at the allocated struct usb_ctrlrequest. + +USB core then interprets pointer bytes as the setup packet. This can +produce an invalid bRequestType and trigger the control direction warning +reported by syzbot: + + usb 2-1: BOGUS control dir, pipe 80003580 doesn't match bRequestType 0 + +Pass ir->request itself as the setup packet. + +Fixes: eac69475b01f ("media: rc: igorplugusb: heed coherency rules") +Reported-by: syzbot+11f0e4f957c7c3bf3d51@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=11f0e4f957c7c3bf3d51 +Tested-by: syzbot+11f0e4f957c7c3bf3d51@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Assisted-by: Codex:GPT-5.5 +Signed-off-by: Henri A +Signed-off-by: Sean Young +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/igorplugusb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/rc/igorplugusb.c ++++ b/drivers/media/rc/igorplugusb.c +@@ -183,7 +183,7 @@ static int igorplugusb_probe(struct usb_ + goto fail; + + usb_fill_control_urb(ir->urb, udev, +- usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request, ++ usb_rcvctrlpipe(udev, 0), (uint8_t *)ir->request, + ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir); + + usb_make_path(udev, ir->phys, sizeof(ir->phys)); diff --git a/queue-5.15/media-rc-ttusbir-fix-inverted-error-logic.patch b/queue-5.15/media-rc-ttusbir-fix-inverted-error-logic.patch new file mode 100644 index 0000000000..50ee584bc6 --- /dev/null +++ b/queue-5.15/media-rc-ttusbir-fix-inverted-error-logic.patch @@ -0,0 +1,33 @@ +From 646ebdd3105809d84ed04aa9e92e47e89cc44502 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Fri, 10 Apr 2026 23:03:09 +0200 +Subject: media: rc: ttusbir: fix inverted error logic + +From: Oliver Neukum + +commit 646ebdd3105809d84ed04aa9e92e47e89cc44502 upstream. + +We have to report ENOMEM if no buffer is allocated. +Typo dropped a "!". Restore it. + +Fixes: 50acaad3d202 ("media: rc: ttusbir: respect DMA coherency rules") +Cc: stable@vger.kernel.org +Signed-off-by: Oliver Neukum +Signed-off-by: Sean Young +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/ttusbir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/rc/ttusbir.c ++++ b/drivers/media/rc/ttusbir.c +@@ -193,7 +193,7 @@ static int ttusbir_probe(struct usb_inte + tt = kzalloc(sizeof(*tt), GFP_KERNEL); + buffer = kzalloc(5, GFP_KERNEL); + rc = rc_allocate_device(RC_DRIVER_IR_RAW); +- if (!tt || !rc || buffer) { ++ if (!tt || !rc || !buffer) { + ret = -ENOMEM; + goto out; + } diff --git a/queue-5.15/nvme-fix-discard-support-without-oncs.patch b/queue-5.15/nvme-fix-discard-support-without-oncs.patch new file mode 100644 index 0000000000..d2859425a1 --- /dev/null +++ b/queue-5.15/nvme-fix-discard-support-without-oncs.patch @@ -0,0 +1,52 @@ +From d3205ab75e99a47539ec91ef85ba488f4ddfeaa9 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Mon, 3 Apr 2023 13:09:25 -0700 +Subject: nvme: fix discard support without oncs + +From: Keith Busch + +commit d3205ab75e99a47539ec91ef85ba488f4ddfeaa9 upstream. + +The device can report discard support without setting the ONCS DSM bit. +When not set, the driver clears max_discard_size expecting it to be set +later. We don't know the size until we have the namespace format, +though, so setting it is deferred until configuring one, but the driver +was abandoning the discard settings due to that initial clearing. + +Move the max_discard_size calculation above the check for a '0' discard +size. + +Fixes: 1a86924e4f46475 ("nvme: fix interpretation of DMRSL") +Reported-by: Laurence Oberman +Signed-off-by: Keith Busch +Reviewed-by: Niklas Cassel +Reviewed-by: Sagi Grimberg +Tested-by: Laurence Oberman +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1718,6 +1718,9 @@ static void nvme_config_discard(struct g + struct request_queue *queue = disk->queue; + u32 size = queue_logical_block_size(queue); + ++ if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX)) ++ ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl); ++ + if (ctrl->max_discard_sectors == 0) { + blk_queue_flag_clear(QUEUE_FLAG_DISCARD, queue); + return; +@@ -1736,9 +1739,6 @@ static void nvme_config_discard(struct g + if (blk_queue_flag_test_and_set(QUEUE_FLAG_DISCARD, queue)) + return; + +- if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX)) +- ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl); +- + blk_queue_max_discard_sectors(queue, ctrl->max_discard_sectors); + blk_queue_max_discard_segments(queue, ctrl->max_discard_segments); + diff --git a/queue-5.15/scsi-core-declare-scsi_scan_type-static.patch b/queue-5.15/scsi-core-declare-scsi_scan_type-static.patch new file mode 100644 index 0000000000..6ca149e62d --- /dev/null +++ b/queue-5.15/scsi-core-declare-scsi_scan_type-static.patch @@ -0,0 +1,32 @@ +From 7cc5aad6c98e0b7e9ab744d1ac7e385e886bb869 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Mon, 29 Nov 2021 11:45:59 -0800 +Subject: scsi: core: Declare 'scsi_scan_type' static + +From: Bart Van Assche + +commit 7cc5aad6c98e0b7e9ab744d1ac7e385e886bb869 upstream. + +'scsi_scan_type' is only used in one source file. Hence declare it static. + +Link: https://lore.kernel.org/r/20211129194609.3466071-3-bvanassche@acm.org +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Reported-by: kernel test robot +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_scan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -97,7 +97,7 @@ MODULE_PARM_DESC(max_luns, + #define SCSI_SCAN_TYPE_DEFAULT "sync" + #endif + +-char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT; ++static char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT; + + module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), + S_IRUGO|S_IWUSR); diff --git a/queue-5.15/scsi-core-suppress-a-kernel-doc-warning.patch b/queue-5.15/scsi-core-suppress-a-kernel-doc-warning.patch new file mode 100644 index 0000000000..d89372fc54 --- /dev/null +++ b/queue-5.15/scsi-core-suppress-a-kernel-doc-warning.patch @@ -0,0 +1,34 @@ +From 776141dda77f153379a2eea0887f76cb3e6c8062 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Mon, 29 Nov 2021 11:45:58 -0800 +Subject: scsi: core: Suppress a kernel-doc warning + +From: Bart Van Assche + +commit 776141dda77f153379a2eea0887f76cb3e6c8062 upstream. + +Suppress the following kernel-doc warning: + +drivers/scsi/scsi_scan.c:129: warning: Function parameter or member 'dev' not described in 'scsi_enable_async_suspend' + +Link: https://lore.kernel.org/r/20211129194609.3466071-2-bvanassche@acm.org +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Reported-by: Stephen Rothwell +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_scan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -122,7 +122,7 @@ struct async_scan_data { + struct completion prev_finished; + }; + +-/** ++/* + * scsi_enable_async_suspend - Enable async suspend and resume + */ + void scsi_enable_async_suspend(struct device *dev) diff --git a/queue-5.15/scsi-sd-rework-asynchronous-resume-support.patch b/queue-5.15/scsi-sd-rework-asynchronous-resume-support.patch new file mode 100644 index 0000000000..9c42796946 --- /dev/null +++ b/queue-5.15/scsi-sd-rework-asynchronous-resume-support.patch @@ -0,0 +1,175 @@ +From 88f1669019bd62b3009a3cebf772fbaaa21b9f38 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 30 Jun 2022 12:57:03 -0700 +Subject: scsi: sd: Rework asynchronous resume support + +From: Bart Van Assche + +commit 88f1669019bd62b3009a3cebf772fbaaa21b9f38 upstream. + +For some technologies, e.g. an ATA bus, resuming can take multiple +seconds. Waiting for resume to finish can cause a very noticeable delay. +Hence this commit that restores the behavior from before "scsi: core: pm: +Rely on the device driver core for async power management" for most SCSI +devices. + +This commit introduces a behavior change: if the START command fails, do +not consider this as a SCSI disk resume failure. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215880 +Link: https://lore.kernel.org/r/20220630195703.10155-3-bvanassche@acm.org +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Cc: Ming Lei +Cc: Hannes Reinecke +Cc: John Garry +Cc: ericspero@icloud.com +Cc: jason600.groome@gmail.com +Tested-by: jason600.groome@gmail.com +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sd.c | 84 ++++++++++++++++++++++++++++++++++++++++++------------ + drivers/scsi/sd.h | 5 +++ + 2 files changed, 71 insertions(+), 18 deletions(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -105,6 +105,7 @@ static void sd_config_discard(struct scs + static void sd_config_write_same(struct scsi_disk *); + static int sd_revalidate_disk(struct gendisk *); + static void sd_unlock_native_capacity(struct gendisk *disk); ++static void sd_start_done_work(struct work_struct *work); + static int sd_probe(struct device *); + static int sd_remove(struct device *); + static void sd_shutdown(struct device *); +@@ -3403,6 +3404,7 @@ static int sd_probe(struct device *dev) + sdkp->max_retries = SD_MAX_RETRIES; + atomic_set(&sdkp->openers, 0); + atomic_set(&sdkp->device->ioerr_cnt, 0); ++ INIT_WORK(&sdkp->start_done_work, sd_start_done_work); + + if (!sdp->request_queue->rq_timeout) { + if (sdp->type != TYPE_MOD) +@@ -3563,12 +3565,69 @@ static void scsi_disk_release(struct dev + kfree(sdkp); + } + ++/* Process sense data after a START command finished. */ ++static void sd_start_done_work(struct work_struct *work) ++{ ++ struct scsi_disk *sdkp = container_of(work, typeof(*sdkp), ++ start_done_work); ++ struct scsi_sense_hdr sshdr; ++ int res = sdkp->start_result; ++ ++ if (res == 0) ++ return; ++ ++ sd_print_result(sdkp, "Start/Stop Unit failed", res); ++ ++ if (res < 0) ++ return; ++ ++ if (scsi_normalize_sense(sdkp->start_sense_buffer, ++ sdkp->start_sense_len, &sshdr)) ++ sd_print_sense_hdr(sdkp, &sshdr); ++} ++ ++/* A START command finished. May be called from interrupt context. */ ++static void sd_start_done(struct request *req, blk_status_t status) ++{ ++ const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); ++ struct scsi_disk *sdkp = scsi_disk(req->q->disk); ++ ++ sdkp->start_result = scmd->result; ++ WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE); ++ sdkp->start_sense_len = scmd->sense_len; ++ memcpy(sdkp->start_sense_buffer, scmd->sense_buffer, ++ ARRAY_SIZE(sdkp->start_sense_buffer)); ++ WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work)); ++} ++ ++/* Submit a START command asynchronously. */ ++static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len) ++{ ++ struct scsi_device *sdev = sdkp->device; ++ struct request_queue *q = sdev->request_queue; ++ struct request *req; ++ struct scsi_cmnd *scmd; ++ ++ req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM); ++ if (IS_ERR(req)) ++ return PTR_ERR(req); ++ ++ scmd = blk_mq_rq_to_pdu(req); ++ scmd->cmd_len = cmd_len; ++ memcpy(scmd->cmnd, cmd, cmd_len); ++ scmd->allowed = sdkp->max_retries; ++ req->timeout = SD_TIMEOUT; ++ req->rq_flags |= RQF_PM | RQF_QUIET; ++ req->end_io = sd_start_done; ++ blk_execute_rq_nowait(req, /*at_head=*/true); ++ ++ return 0; ++} ++ + static int sd_start_stop_device(struct scsi_disk *sdkp, int start) + { + unsigned char cmd[6] = { START_STOP }; /* START_VALID */ +- struct scsi_sense_hdr sshdr; + struct scsi_device *sdp = sdkp->device; +- int res; + + if (start) + cmd[4] |= 1; /* START */ +@@ -3579,23 +3638,10 @@ static int sd_start_stop_device(struct s + if (!scsi_device_online(sdp)) + return -ENODEV; + +- res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, +- SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL); +- if (res) { +- sd_print_result(sdkp, "Start/Stop Unit failed", res); +- if (res > 0 && scsi_sense_valid(&sshdr)) { +- sd_print_sense_hdr(sdkp, &sshdr); +- /* 0x3a is medium not present */ +- if (sshdr.asc == 0x3a) +- res = 0; +- } +- } ++ /* Wait until processing of sense data has finished. */ ++ flush_work(&sdkp->start_done_work); + +- /* SCSI error codes must not go to the generic layer */ +- if (res) +- return -EIO; +- +- return 0; ++ return sd_submit_start(sdkp, cmd, sizeof(cmd)); + } + + /* +@@ -3622,6 +3668,8 @@ static void sd_shutdown(struct device *d + sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_start_stop_device(sdkp, 0); + } ++ ++ flush_work(&sdkp->start_done_work); + } + + static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -130,6 +130,11 @@ struct scsi_disk { + unsigned urswrz : 1; + unsigned security : 1; + unsigned ignore_medium_access_errors : 1; ++ ++ int start_result; ++ u32 start_sense_len; ++ u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE]; ++ struct work_struct start_done_work; + }; + #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev) + diff --git a/queue-5.15/scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch b/queue-5.15/scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch new file mode 100644 index 0000000000..f8afb1529a --- /dev/null +++ b/queue-5.15/scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch @@ -0,0 +1,38 @@ +From 0296bea01cfa6526be6bd2d16dc83b4e7f1af91f Mon Sep 17 00:00:00 2001 +From: Li Nan +Date: Fri, 8 Dec 2023 16:23:35 +0800 +Subject: scsi: sd: Unregister device if device_add_disk() failed in sd_probe() + +From: Li Nan + +commit 0296bea01cfa6526be6bd2d16dc83b4e7f1af91f upstream. + +"if device_add() succeeds, you should call device_del() when you want to +get rid of it." + +In sd_probe(), device_add_disk() fails when device_add() has already +succeeded, so change put_device() to device_unregister() to ensure device +resources are released. + +Fixes: 2a7a891f4c40 ("scsi: sd: Add error handling support for add_disk()") +Signed-off-by: Li Nan +Link: https://lore.kernel.org/r/20231208082335.1754205-1-linan666@huaweicloud.com +Reviewed-by: Bart Van Assche +Reviewed-by: Yu Kuai +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3421,7 +3421,7 @@ static int sd_probe(struct device *dev) + + error = device_add(&sdkp->disk_dev); + if (error) { +- put_device(&sdkp->disk_dev); ++ device_unregister(&sdkp->disk_dev); + put_disk(gd); + goto out; + } diff --git a/queue-5.15/series b/queue-5.15/series index 901704aa91..f0249eba7b 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -409,3 +409,15 @@ mptcp-close-toctou-race-while-computing-rcv_wnd.patch fbdev-vt8500lcdfb-fix-dma_free_coherent-cpu_addr-parameter.patch apparmor-validate-default-dfa-states-are-in-bounds.patch x86-cpu-amd-move-the-zen3-btc_no-detection-to-the-zen3-init-function.patch +crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.patch +media-rc-ttusbir-fix-inverted-error-logic.patch +batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch +media-rc-igorplugusb-fix-control-request-setup-packet.patch +scsi-core-suppress-a-kernel-doc-warning.patch +scsi-core-declare-scsi_scan_type-static.patch +scsi-sd-rework-asynchronous-resume-support.patch +nvme-fix-discard-support-without-oncs.patch +ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch +ata-scsi-do-not-issue-start-stop-unit-on-resume.patch +ata-libata-scsi-link-ata-port-and-scsi-device.patch +scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch