From: Greg Kroah-Hartman Date: Mon, 1 Apr 2024 08:54:55 +0000 (+0200) Subject: 6.7-stable patches X-Git-Tag: v6.7.12~76 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=34befc83be0b638db93929a5498eed620d4e723b;p=thirdparty%2Fkernel%2Fstable-queue.git 6.7-stable patches added patches: scsi-core-fix-unremoved-procfs-host-directory-regression.patch scsi-sd-fix-tcg-opal-unlock-on-system-resume.patch scsi-sg-avoid-sg-device-teardown-race.patch scsi-ufs-qcom-provide-default-cycles_in_1us-value.patch --- diff --git a/queue-6.7/scsi-core-fix-unremoved-procfs-host-directory-regression.patch b/queue-6.7/scsi-core-fix-unremoved-procfs-host-directory-regression.patch new file mode 100644 index 00000000000..376c384c64b --- /dev/null +++ b/queue-6.7/scsi-core-fix-unremoved-procfs-host-directory-regression.patch @@ -0,0 +1,80 @@ +From f23a4d6e07570826fe95023ca1aa96a011fa9f84 Mon Sep 17 00:00:00 2001 +From: "Guilherme G. Piccoli" +Date: Wed, 13 Mar 2024 08:21:20 -0300 +Subject: scsi: core: Fix unremoved procfs host directory regression + +From: Guilherme G. Piccoli + +commit f23a4d6e07570826fe95023ca1aa96a011fa9f84 upstream. + +Commit fc663711b944 ("scsi: core: Remove the /proc/scsi/${proc_name} +directory earlier") fixed a bug related to modules loading/unloading, by +adding a call to scsi_proc_hostdir_rm() on scsi_remove_host(). But that led +to a potential duplicate call to the hostdir_rm() routine, since it's also +called from scsi_host_dev_release(). That triggered a regression report, +which was then fixed by commit be03df3d4bfe ("scsi: core: Fix a procfs host +directory removal regression"). The fix just dropped the hostdir_rm() call +from dev_release(). + +But it happens that this proc directory is created on scsi_host_alloc(), +and that function "pairs" with scsi_host_dev_release(), while +scsi_remove_host() pairs with scsi_add_host(). In other words, it seems the +reason for removing the proc directory on dev_release() was meant to cover +cases in which a SCSI host structure was allocated, but the call to +scsi_add_host() didn't happen. And that pattern happens to exist in some +error paths, for example. + +Syzkaller causes that by using USB raw gadget device, error'ing on +usb-storage driver, at usb_stor_probe2(). By checking that path, we can see +that the BadDevice label leads to a scsi_host_put() after a SCSI host +allocation, but there's no call to scsi_add_host() in such path. That leads +to messages like this in dmesg (and a leak of the SCSI host proc +structure): + +usb-storage 4-1:87.51: USB Mass Storage device detected +proc_dir_entry 'scsi/usb-storage' already registered +WARNING: CPU: 1 PID: 3519 at fs/proc/generic.c:377 proc_register+0x347/0x4e0 fs/proc/generic.c:376 + +The proper fix seems to still call scsi_proc_hostdir_rm() on dev_release(), +but guard that with the state check for SHOST_CREATED; there is even a +comment in scsi_host_dev_release() detailing that: such conditional is +meant for cases where the SCSI host was allocated but there was no calls to +{add,remove}_host(), like the usb-storage case. + +This is what we propose here and with that, the error path of usb-storage +does not trigger the warning anymore. + +Reported-by: syzbot+c645abf505ed21f931b5@syzkaller.appspotmail.com +Fixes: be03df3d4bfe ("scsi: core: Fix a procfs host directory removal regression") +Cc: stable@vger.kernel.org +Cc: Bart Van Assche +Cc: John Garry +Cc: Shin'ichiro Kawasaki +Signed-off-by: Guilherme G. Piccoli +Link: https://lore.kernel.org/r/20240313113006.2834799-1-gpiccoli@igalia.com +Reviewed-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/hosts.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/hosts.c ++++ b/drivers/scsi/hosts.c +@@ -353,12 +353,13 @@ static void scsi_host_dev_release(struct + + if (shost->shost_state == SHOST_CREATED) { + /* +- * Free the shost_dev device name here if scsi_host_alloc() +- * and scsi_host_put() have been called but neither ++ * Free the shost_dev device name and remove the proc host dir ++ * here if scsi_host_{alloc,put}() have been called but neither + * scsi_host_add() nor scsi_remove_host() has been called. + * This avoids that the memory allocated for the shost_dev +- * name is leaked. ++ * name as well as the proc dir structure are leaked. + */ ++ scsi_proc_hostdir_rm(shost->hostt); + kfree(dev_name(&shost->shost_dev)); + } + diff --git a/queue-6.7/scsi-sd-fix-tcg-opal-unlock-on-system-resume.patch b/queue-6.7/scsi-sd-fix-tcg-opal-unlock-on-system-resume.patch new file mode 100644 index 00000000000..7d727ac9293 --- /dev/null +++ b/queue-6.7/scsi-sd-fix-tcg-opal-unlock-on-system-resume.patch @@ -0,0 +1,230 @@ +From 0c76106cb97548810214def8ee22700bbbb90543 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Tue, 19 Mar 2024 16:12:09 +0900 +Subject: scsi: sd: Fix TCG OPAL unlock on system resume + +From: Damien Le Moal + +commit 0c76106cb97548810214def8ee22700bbbb90543 upstream. + +Commit 3cc2ffe5c16d ("scsi: sd: Differentiate system and runtime start/stop +management") introduced the manage_system_start_stop scsi_device flag to +allow libata to indicate to the SCSI disk driver that nothing should be +done when resuming a disk on system resume. This change turned the +execution of sd_resume() into a no-op for ATA devices on system +resume. While this solved deadlock issues during device resume, this change +also wrongly removed the execution of opal_unlock_from_suspend(). As a +result, devices with TCG OPAL locking enabled remain locked and +inaccessible after a system resume from sleep. + +To fix this issue, introduce the SCSI driver resume method and implement it +with the sd_resume() function calling opal_unlock_from_suspend(). The +former sd_resume() function is renamed to sd_resume_common() and modified +to call the new sd_resume() function. For non-ATA devices, this result in +no functional changes. + +In order for libata to explicitly execute sd_resume() when a device is +resumed during system restart, the function scsi_resume_device() is +introduced. libata calls this function from the revalidation work executed +on devie resume, a state that is indicated with the new device flag +ATA_DFLAG_RESUMING. Doing so, locked TCG OPAL enabled devices are unlocked +on resume, allowing normal operation. + +Fixes: 3cc2ffe5c16d ("scsi: sd: Differentiate system and runtime start/stop management") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218538 +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Link: https://lore.kernel.org/r/20240319071209.1179257-1-dlemoal@kernel.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-eh.c | 5 ++++- + drivers/ata/libata-scsi.c | 9 +++++++++ + drivers/scsi/scsi_scan.c | 34 ++++++++++++++++++++++++++++++++++ + drivers/scsi/sd.c | 23 +++++++++++++++++++---- + include/linux/libata.h | 1 + + include/scsi/scsi_driver.h | 1 + + include/scsi/scsi_host.h | 1 + + 7 files changed, 69 insertions(+), 5 deletions(-) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -712,8 +712,10 @@ void ata_scsi_port_error_handler(struct + ehc->saved_ncq_enabled |= 1 << devno; + + /* If we are resuming, wake up the device */ +- if (ap->pflags & ATA_PFLAG_RESUMING) ++ if (ap->pflags & ATA_PFLAG_RESUMING) { ++ dev->flags |= ATA_DFLAG_RESUMING; + ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; ++ } + } + } + +@@ -3169,6 +3171,7 @@ static int ata_eh_revalidate_and_attach( + return 0; + + err: ++ dev->flags &= ~ATA_DFLAG_RESUMING; + *r_failed_dev = dev; + return rc; + } +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -4730,6 +4730,7 @@ void ata_scsi_dev_rescan(struct work_str + struct ata_link *link; + struct ata_device *dev; + unsigned long flags; ++ bool do_resume; + int ret = 0; + + mutex_lock(&ap->scsi_scan_mutex); +@@ -4751,7 +4752,15 @@ void ata_scsi_dev_rescan(struct work_str + if (scsi_device_get(sdev)) + continue; + ++ do_resume = dev->flags & ATA_DFLAG_RESUMING; ++ + spin_unlock_irqrestore(ap->lock, flags); ++ if (do_resume) { ++ ret = scsi_resume_device(sdev); ++ if (ret == -EWOULDBLOCK) ++ goto unlock; ++ dev->flags &= ~ATA_DFLAG_RESUMING; ++ } + ret = scsi_rescan_device(sdev); + scsi_device_put(sdev); + spin_lock_irqsave(ap->lock, flags); +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -1619,6 +1619,40 @@ int scsi_add_device(struct Scsi_Host *ho + } + EXPORT_SYMBOL(scsi_add_device); + ++int scsi_resume_device(struct scsi_device *sdev) ++{ ++ struct device *dev = &sdev->sdev_gendev; ++ int ret = 0; ++ ++ device_lock(dev); ++ ++ /* ++ * Bail out if the device or its queue are not running. Otherwise, ++ * the rescan may block waiting for commands to be executed, with us ++ * holding the device lock. This can result in a potential deadlock ++ * in the power management core code when system resume is on-going. ++ */ ++ if (sdev->sdev_state != SDEV_RUNNING || ++ blk_queue_pm_only(sdev->request_queue)) { ++ ret = -EWOULDBLOCK; ++ goto unlock; ++ } ++ ++ if (dev->driver && try_module_get(dev->driver->owner)) { ++ struct scsi_driver *drv = to_scsi_driver(dev->driver); ++ ++ if (drv->resume) ++ ret = drv->resume(dev); ++ module_put(dev->driver->owner); ++ } ++ ++unlock: ++ device_unlock(dev); ++ ++ return ret; ++} ++EXPORT_SYMBOL(scsi_resume_device); ++ + int scsi_rescan_device(struct scsi_device *sdev) + { + struct device *dev = &sdev->sdev_gendev; +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3948,7 +3948,21 @@ static int sd_suspend_runtime(struct dev + return sd_suspend_common(dev, true); + } + +-static int sd_resume(struct device *dev, bool runtime) ++static int sd_resume(struct device *dev) ++{ ++ struct scsi_disk *sdkp = dev_get_drvdata(dev); ++ ++ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); ++ ++ if (opal_unlock_from_suspend(sdkp->opal_dev)) { ++ sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int sd_resume_common(struct device *dev, bool runtime) + { + struct scsi_disk *sdkp = dev_get_drvdata(dev); + int ret; +@@ -3964,7 +3978,7 @@ static int sd_resume(struct device *dev, + sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + ret = sd_start_stop_device(sdkp, 1); + if (!ret) { +- opal_unlock_from_suspend(sdkp->opal_dev); ++ sd_resume(dev); + sdkp->suspended = false; + } + +@@ -3983,7 +3997,7 @@ static int sd_resume_system(struct devic + return 0; + } + +- return sd_resume(dev, false); ++ return sd_resume_common(dev, false); + } + + static int sd_resume_runtime(struct device *dev) +@@ -4010,7 +4024,7 @@ static int sd_resume_runtime(struct devi + "Failed to clear sense data\n"); + } + +- return sd_resume(dev, true); ++ return sd_resume_common(dev, true); + } + + static const struct dev_pm_ops sd_pm_ops = { +@@ -4033,6 +4047,7 @@ static struct scsi_driver sd_template = + .pm = &sd_pm_ops, + }, + .rescan = sd_rescan, ++ .resume = sd_resume, + .init_command = sd_init_command, + .uninit_command = sd_uninit_command, + .done = sd_done, +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -107,6 +107,7 @@ enum { + + ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 20), /* Priority cmds sent to dev */ + ATA_DFLAG_CDL_ENABLED = (1 << 21), /* cmd duration limits is enabled */ ++ ATA_DFLAG_RESUMING = (1 << 22), /* Device is resuming */ + ATA_DFLAG_DETACH = (1 << 24), + ATA_DFLAG_DETACHED = (1 << 25), + ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ +--- a/include/scsi/scsi_driver.h ++++ b/include/scsi/scsi_driver.h +@@ -12,6 +12,7 @@ struct request; + struct scsi_driver { + struct device_driver gendrv; + ++ int (*resume)(struct device *); + void (*rescan)(struct device *); + blk_status_t (*init_command)(struct scsi_cmnd *); + void (*uninit_command)(struct scsi_cmnd *); +--- a/include/scsi/scsi_host.h ++++ b/include/scsi/scsi_host.h +@@ -767,6 +767,7 @@ scsi_template_proc_dir(const struct scsi + #define scsi_template_proc_dir(sht) NULL + #endif + extern void scsi_scan_host(struct Scsi_Host *); ++extern int scsi_resume_device(struct scsi_device *sdev); + extern int scsi_rescan_device(struct scsi_device *sdev); + extern void scsi_remove_host(struct Scsi_Host *); + extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); diff --git a/queue-6.7/scsi-sg-avoid-sg-device-teardown-race.patch b/queue-6.7/scsi-sg-avoid-sg-device-teardown-race.patch new file mode 100644 index 00000000000..940437e82ea --- /dev/null +++ b/queue-6.7/scsi-sg-avoid-sg-device-teardown-race.patch @@ -0,0 +1,51 @@ +From 27f58c04a8f438078583041468ec60597841284d Mon Sep 17 00:00:00 2001 +From: Alexander Wetzel +Date: Wed, 20 Mar 2024 22:30:32 +0100 +Subject: scsi: sg: Avoid sg device teardown race + +From: Alexander Wetzel + +commit 27f58c04a8f438078583041468ec60597841284d upstream. + +sg_remove_sfp_usercontext() must not use sg_device_destroy() after calling +scsi_device_put(). + +sg_device_destroy() is accessing the parent scsi_device request_queue which +will already be set to NULL when the preceding call to scsi_device_put() +removed the last reference to the parent scsi_device. + +The resulting NULL pointer exception will then crash the kernel. + +Link: https://lore.kernel.org/r/20240305150509.23896-1-Alexander@wetzel-home.de +Fixes: db59133e9279 ("scsi: sg: fix blktrace debugfs entries leakage") +Cc: stable@vger.kernel.org +Signed-off-by: Alexander Wetzel +Link: https://lore.kernel.org/r/20240320213032.18221-1-Alexander@wetzel-home.de +Reviewed-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sg.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -2207,6 +2207,7 @@ sg_remove_sfp_usercontext(struct work_st + { + struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work); + struct sg_device *sdp = sfp->parentdp; ++ struct scsi_device *device = sdp->device; + Sg_request *srp; + unsigned long iflags; + +@@ -2232,8 +2233,9 @@ sg_remove_sfp_usercontext(struct work_st + "sg_remove_sfp: sfp=0x%p\n", sfp)); + kfree(sfp); + +- scsi_device_put(sdp->device); ++ WARN_ON_ONCE(kref_read(&sdp->d_ref) != 1); + kref_put(&sdp->d_ref, sg_device_destroy); ++ scsi_device_put(device); + module_put(THIS_MODULE); + } + diff --git a/queue-6.7/scsi-ufs-qcom-provide-default-cycles_in_1us-value.patch b/queue-6.7/scsi-ufs-qcom-provide-default-cycles_in_1us-value.patch new file mode 100644 index 00000000000..6d41f13b88b --- /dev/null +++ b/queue-6.7/scsi-ufs-qcom-provide-default-cycles_in_1us-value.patch @@ -0,0 +1,41 @@ +From 81e2c1a0f8d3f62f4c9e80b20270aa3481c40524 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov +Date: Sun, 18 Feb 2024 15:56:34 +0200 +Subject: scsi: ufs: qcom: Provide default cycles_in_1us value + +From: Dmitry Baryshkov + +commit 81e2c1a0f8d3f62f4c9e80b20270aa3481c40524 upstream. + +The MSM8996 DT doesn't provide frequency limits for the core_clk_unipro +clock, which results in miscalculation of the cycles_in_1us value. Provide +the backwards-compatible default to support existing MSM8996 DT files. + +Fixes: b4e13e1ae95e ("scsi: ufs: qcom: Add multiple frequency support for MAX_CORE_CLK_1US_CYCLES") +Cc: Nitin Rawat +Cc: stable@vger.kernel.org # 6.7.x +Reviewed-by: Konrad Dybcio +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20240218-msm8996-fix-ufs-v3-1-40aab49899a3@linaro.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ufs/host/ufs-qcom.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/ufs/host/ufs-qcom.c ++++ b/drivers/ufs/host/ufs-qcom.c +@@ -1397,8 +1397,10 @@ static int ufs_qcom_set_core_clk_ctrl(st + + list_for_each_entry(clki, head, list) { + if (!IS_ERR_OR_NULL(clki->clk) && +- !strcmp(clki->name, "core_clk_unipro")) { +- if (is_scale_up) ++ !strcmp(clki->name, "core_clk_unipro")) { ++ if (!clki->max_freq) ++ cycles_in_1us = 150; /* default for backwards compatibility */ ++ else if (is_scale_up) + cycles_in_1us = ceil(clki->max_freq, (1000 * 1000)); + else + cycles_in_1us = ceil(clk_get_rate(clki->clk), (1000 * 1000)); diff --git a/queue-6.7/series b/queue-6.7/series index 31c4c8c8ada..eef48421b80 100644 --- a/queue-6.7/series +++ b/queue-6.7/series @@ -386,3 +386,7 @@ drm-amdgpu-make-damage-clips-support-configurable.patch drm-amdgpu-display-address-kdoc-for-is_psr_su-in-fil.patch vfio-pds-make-sure-migration-file-isn-t-accessed-aft.patch alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch +scsi-ufs-qcom-provide-default-cycles_in_1us-value.patch +scsi-sd-fix-tcg-opal-unlock-on-system-resume.patch +scsi-sg-avoid-sg-device-teardown-race.patch +scsi-core-fix-unremoved-procfs-host-directory-regression.patch