From f2ca7b92146e7a4aaba0809adc7522ddd64bee2c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 Aug 2025 14:13:55 +0200 Subject: [PATCH] 6.12-stable patches added patches: ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch drm-amd-display-allow-dcn301-to-clear-update-flags.patch firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch md-fix-create-on-open-mddev-lifetime-regression.patch pci-honor-max-link-speed-when-determining-supported-speeds.patch rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch --- ...management_supported-sysfs-attribute.patch | 148 ++++++++++++++++++ ...ies-when-zone-append-is-not-emulated.patch | 85 ++++++++++ ...y-allow-dcn301-to-clear-update-flags.patch | 37 +++++ ..._scmi-convert-to-system_sleep_pm_ops.patch | 49 ++++++ ...rw-cast-rw-flags-assignment-to-rwf_t.patch | 38 +++++ ...te-on-open-mddev-lifetime-regression.patch | 79 ++++++++++ ...ed-when-determining-supported-speeds.patch | 84 ++++++++++ ...ialization-of-irq_work-causing-hangs.patch | 104 ++++++++++++ queue-6.12/series | 8 + 9 files changed, 632 insertions(+) create mode 100644 queue-6.12/ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch create mode 100644 queue-6.12/dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch create mode 100644 queue-6.12/drm-amd-display-allow-dcn301-to-clear-update-flags.patch create mode 100644 queue-6.12/firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch create mode 100644 queue-6.12/io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch create mode 100644 queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch create mode 100644 queue-6.12/pci-honor-max-link-speed-when-determining-supported-speeds.patch create mode 100644 queue-6.12/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch diff --git a/queue-6.12/ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch b/queue-6.12/ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch new file mode 100644 index 0000000000..f097b14123 --- /dev/null +++ b/queue-6.12/ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch @@ -0,0 +1,148 @@ +From 0060beec0bfa647c4b510df188b1c4673a197839 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Mon, 28 Jul 2025 13:04:29 +0900 +Subject: ata: libata-sata: Add link_power_management_supported sysfs attribute + +From: Damien Le Moal + +commit 0060beec0bfa647c4b510df188b1c4673a197839 upstream. + +A port link power management (LPM) policy can be controlled using the +link_power_management_policy sysfs host attribute. However, this +attribute exists also for hosts that do not support LPM and in such +case, attempting to change the LPM policy for the host (port) will fail +with -EOPNOTSUPP. + +Introduce the new sysfs link_power_management_supported host attribute +to indicate to the user if a the port and the devices connected to the +port for the host support LPM, which implies that the +link_power_management_policy attribute can be used. + +Since checking that a port and its devices support LPM is common between +the new ata_scsi_lpm_supported_show() function and the existing +ata_scsi_lpm_store() function, the new helper ata_scsi_lpm_supported() +is introduced. + +Fixes: 413e800cadbf ("ata: libata-sata: Disallow changing LPM state if not supported") +Reported-by: Borah, Chaitanya Kumar +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202507251014.a5becc3b-lkp@intel.com +Signed-off-by: Damien Le Moal +Reviewed-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/ata_piix.c | 1 + drivers/ata/libahci.c | 1 + drivers/ata/libata-sata.c | 53 +++++++++++++++++++++++++++++++++++----------- + include/linux/libata.h | 1 + 4 files changed, 44 insertions(+), 12 deletions(-) + +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -1089,6 +1089,7 @@ static struct ata_port_operations ich_pa + }; + + static struct attribute *piix_sidpr_shost_attrs[] = { ++ &dev_attr_link_power_management_supported.attr, + &dev_attr_link_power_management_policy.attr, + NULL + }; +--- a/drivers/ata/libahci.c ++++ b/drivers/ata/libahci.c +@@ -111,6 +111,7 @@ static DEVICE_ATTR(em_buffer, S_IWUSR | + static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); + + static struct attribute *ahci_shost_attrs[] = { ++ &dev_attr_link_power_management_supported.attr, + &dev_attr_link_power_management_policy.attr, + &dev_attr_em_message_type.attr, + &dev_attr_em_message.attr, +--- a/drivers/ata/libata-sata.c ++++ b/drivers/ata/libata-sata.c +@@ -900,14 +900,52 @@ static const char *ata_lpm_policy_names[ + [ATA_LPM_MIN_POWER] = "min_power", + }; + ++/* ++ * Check if a port supports link power management. ++ * Must be called with the port locked. ++ */ ++static bool ata_scsi_lpm_supported(struct ata_port *ap) ++{ ++ struct ata_link *link; ++ struct ata_device *dev; ++ ++ if (ap->flags & ATA_FLAG_NO_LPM) ++ return false; ++ ++ ata_for_each_link(link, ap, EDGE) { ++ ata_for_each_dev(dev, &ap->link, ENABLED) { ++ if (dev->quirks & ATA_QUIRK_NOLPM) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static ssize_t ata_scsi_lpm_supported_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct ata_port *ap = ata_shost_to_port(shost); ++ unsigned long flags; ++ bool supported; ++ ++ spin_lock_irqsave(ap->lock, flags); ++ supported = ata_scsi_lpm_supported(ap); ++ spin_unlock_irqrestore(ap->lock, flags); ++ ++ return sysfs_emit(buf, "%d\n", supported); ++} ++DEVICE_ATTR(link_power_management_supported, S_IRUGO, ++ ata_scsi_lpm_supported_show, NULL); ++EXPORT_SYMBOL_GPL(dev_attr_link_power_management_supported); ++ + static ssize_t ata_scsi_lpm_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) + { + struct Scsi_Host *shost = class_to_shost(device); + struct ata_port *ap = ata_shost_to_port(shost); +- struct ata_link *link; +- struct ata_device *dev; + enum ata_lpm_policy policy; + unsigned long flags; + +@@ -924,20 +962,11 @@ static ssize_t ata_scsi_lpm_store(struct + + spin_lock_irqsave(ap->lock, flags); + +- if (ap->flags & ATA_FLAG_NO_LPM) { ++ if (!ata_scsi_lpm_supported(ap)) { + count = -EOPNOTSUPP; + goto out_unlock; + } + +- ata_for_each_link(link, ap, EDGE) { +- ata_for_each_dev(dev, &ap->link, ENABLED) { +- if (dev->quirks & ATA_QUIRK_NOLPM) { +- count = -EOPNOTSUPP; +- goto out_unlock; +- } +- } +- } +- + ap->target_lpm_policy = policy; + ata_port_schedule_eh(ap); + out_unlock: +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -547,6 +547,7 @@ typedef void (*ata_postreset_fn_t)(struc + + extern struct device_attribute dev_attr_unload_heads; + #ifdef CONFIG_SATA_HOST ++extern struct device_attribute dev_attr_link_power_management_supported; + extern struct device_attribute dev_attr_link_power_management_policy; + extern struct device_attribute dev_attr_ncq_prio_supported; + extern struct device_attribute dev_attr_ncq_prio_enable; diff --git a/queue-6.12/dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch b/queue-6.12/dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch new file mode 100644 index 0000000000..44a6ba4b72 --- /dev/null +++ b/queue-6.12/dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch @@ -0,0 +1,85 @@ +From 675f940576351bb049f5677615140b9d0a7712d0 Mon Sep 17 00:00:00 2001 +From: Shin'ichiro Kawasaki +Date: Thu, 17 Jul 2025 19:35:39 +0900 +Subject: dm: split write BIOs on zone boundaries when zone append is not emulated + +From: Shin'ichiro Kawasaki + +commit 675f940576351bb049f5677615140b9d0a7712d0 upstream. + +Commit 2df7168717b7 ("dm: Always split write BIOs to zoned device +limits") updates the device-mapper driver to perform splits for the +write BIOs. However, it did not address the cases where DM targets do +not emulate zone append, such as in the cases of dm-linear or dm-flakey. +For these targets, when the write BIOs span across zone boundaries, they +trigger WARN_ON_ONCE(bio_straddles_zones(bio)) in +blk_zone_wplug_handle_write(). This results in I/O errors. The errors +are reproduced by running blktests test case zbd/004 using zoned +dm-linear or dm-flakey devices. + +To avoid the I/O errors, handle the write BIOs regardless whether DM +targets emulate zone append or not, so that all write BIOs are split at +zone boundaries. For that purpose, drop the check for zone append +emulation in dm_zone_bio_needs_split(). Its argument 'md' is no longer +used then drop it also. + +Fixes: 2df7168717b7 ("dm: Always split write BIOs to zoned device limits") +Signed-off-by: Shin'ichiro Kawasaki +Reviewed-by: Damien Le Moal +Reviewed-by: Mikulas Patocka +Link: https://lore.kernel.org/r/20250717103539.37279-1-shinichiro.kawasaki@wdc.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm.c | 18 +++++++----------- + 1 file changed, 7 insertions(+), 11 deletions(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1788,8 +1788,7 @@ static void init_clone_info(struct clone + } + + #ifdef CONFIG_BLK_DEV_ZONED +-static inline bool dm_zone_bio_needs_split(struct mapped_device *md, +- struct bio *bio) ++static inline bool dm_zone_bio_needs_split(struct bio *bio) + { + /* + * Special case the zone operations that cannot or should not be split. +@@ -1805,13 +1804,11 @@ static inline bool dm_zone_bio_needs_spl + } + + /* +- * Mapped devices that require zone append emulation will use the block +- * layer zone write plugging. In such case, we must split any large BIO +- * to the mapped device limits to avoid potential deadlocks with queue +- * freeze operations. ++ * When mapped devices use the block layer zone write plugging, we must ++ * split any large BIO to the mapped device limits to not submit BIOs ++ * that span zone boundaries and to avoid potential deadlocks with ++ * queue freeze operations. + */ +- if (!dm_emulate_zone_append(md)) +- return false; + return bio_needs_zone_write_plugging(bio) || bio_straddles_zones(bio); + } + +@@ -1935,8 +1932,7 @@ static blk_status_t __send_zone_reset_al + } + + #else +-static inline bool dm_zone_bio_needs_split(struct mapped_device *md, +- struct bio *bio) ++static inline bool dm_zone_bio_needs_split(struct bio *bio) + { + return false; + } +@@ -1963,7 +1959,7 @@ static void dm_split_and_process_bio(str + + is_abnormal = is_abnormal_io(bio); + if (static_branch_unlikely(&zoned_enabled)) { +- need_split = is_abnormal || dm_zone_bio_needs_split(md, bio); ++ need_split = is_abnormal || dm_zone_bio_needs_split(bio); + } else { + need_split = is_abnormal; + } diff --git a/queue-6.12/drm-amd-display-allow-dcn301-to-clear-update-flags.patch b/queue-6.12/drm-amd-display-allow-dcn301-to-clear-update-flags.patch new file mode 100644 index 0000000000..0453a187ed --- /dev/null +++ b/queue-6.12/drm-amd-display-allow-dcn301-to-clear-update-flags.patch @@ -0,0 +1,37 @@ +From 2d418e4fd9f1eca7dfce80de86dd702d36a06a25 Mon Sep 17 00:00:00 2001 +From: Ivan Lipski +Date: Thu, 17 Jul 2025 13:58:35 -0400 +Subject: drm/amd/display: Allow DCN301 to clear update flags + +From: Ivan Lipski + +commit 2d418e4fd9f1eca7dfce80de86dd702d36a06a25 upstream. + +[Why & How] +Not letting DCN301 to clear after surface/stream update results +in artifacts when switching between active overlay planes. The issue +is known and has been solved initially. See below: +(https://gitlab.freedesktop.org/drm/amd/-/issues/3441) + +Fixes: f354556e29f4 ("drm/amd/display: limit clear_update_flags t dcn32 and above") +Reviewed-by: Mario Limonciello +Signed-off-by: Ivan Lipski +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -5121,7 +5121,8 @@ bool dc_update_planes_and_stream(struct + else + ret = update_planes_and_stream_v2(dc, srf_updates, + surface_count, stream, stream_update); +- if (ret && dc->ctx->dce_version >= DCN_VERSION_3_2) ++ if (ret && (dc->ctx->dce_version >= DCN_VERSION_3_2 || ++ dc->ctx->dce_version == DCN_VERSION_3_01)) + clear_update_flags(srf_updates, surface_count, stream); + + return ret; diff --git a/queue-6.12/firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch b/queue-6.12/firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch new file mode 100644 index 0000000000..18956e5873 --- /dev/null +++ b/queue-6.12/firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch @@ -0,0 +1,49 @@ +From 62d6b81e8bd207ad44eff39d1a0fe17f0df510a5 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 9 Jul 2025 09:01:01 +0200 +Subject: firmware: arm_scmi: Convert to SYSTEM_SLEEP_PM_OPS + +From: Arnd Bergmann + +commit 62d6b81e8bd207ad44eff39d1a0fe17f0df510a5 upstream. + +The old SET_SYSTEM_SLEEP_PM_OPS() macro leads to a warning about an +unused function: + + | drivers/firmware/arm_scmi/scmi_power_control.c:363:12: error: + | 'scmi_system_power_resume' defined but not used [-Werror=unused-function] + | static int scmi_system_power_resume(struct device *dev) + +The proper way to do this these days is to use SYSTEM_SLEEP_PM_OPS() +and pm_sleep_ptr(). + +Fixes: 9a0658d3991e ("firmware: arm_scmi: power_control: Ensure SCMI_SYSPOWER_IDLE is set early during resume") +Signed-off-by: Arnd Bergmann +Acked-by: Peng Fan +Message-Id: <20250709070107.1388512-1-arnd@kernel.org> +Signed-off-by: Sudeep Holla +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/arm_scmi/scmi_power_control.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/firmware/arm_scmi/scmi_power_control.c ++++ b/drivers/firmware/arm_scmi/scmi_power_control.c +@@ -369,7 +369,7 @@ static int scmi_system_power_resume(stru + } + + static const struct dev_pm_ops scmi_system_power_pmops = { +- SET_SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume) ++ SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume) + }; + + static const struct scmi_device_id scmi_id_table[] = { +@@ -380,7 +380,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table) + + static struct scmi_driver scmi_system_power_driver = { + .driver = { +- .pm = &scmi_system_power_pmops, ++ .pm = pm_sleep_ptr(&scmi_system_power_pmops), + }, + .name = "scmi-system-power", + .probe = scmi_syspower_probe, diff --git a/queue-6.12/io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch b/queue-6.12/io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch new file mode 100644 index 0000000000..f6cdb98c32 --- /dev/null +++ b/queue-6.12/io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch @@ -0,0 +1,38 @@ +From 825aea662b492571877b32aeeae13689fd9fbee4 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Mon, 7 Jul 2025 16:46:30 -0600 +Subject: io_uring/rw: cast rw->flags assignment to rwf_t + +From: Jens Axboe + +commit 825aea662b492571877b32aeeae13689fd9fbee4 upstream. + +kernel test robot reports that a recent change of the sqe->rw_flags +field throws a sparse warning on 32-bit archs: + +>> io_uring/rw.c:291:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __kernel_rwf_t [usertype] flags @@ got unsigned int @@ + io_uring/rw.c:291:19: sparse: expected restricted __kernel_rwf_t [usertype] flags + io_uring/rw.c:291:19: sparse: got unsigned int + +Force cast it to rwf_t to silence that new sparse warning. + +Fixes: cf73d9970ea4 ("io_uring: don't use int for ABI") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202507032211.PwSNPNSP-lkp@intel.com/ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/rw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/io_uring/rw.c ++++ b/io_uring/rw.c +@@ -282,7 +282,7 @@ static int io_prep_rw(struct io_kiocb *r + + rw->addr = READ_ONCE(sqe->addr); + rw->len = READ_ONCE(sqe->len); +- rw->flags = READ_ONCE(sqe->rw_flags); ++ rw->flags = (__force rwf_t) READ_ONCE(sqe->rw_flags); + return io_prep_rw_setup(req, ddir, do_import); + } + diff --git a/queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch new file mode 100644 index 0000000000..14ab8500ea --- /dev/null +++ b/queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch @@ -0,0 +1,79 @@ +From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Wed, 30 Jul 2025 15:33:21 +0800 +Subject: md: fix create on open mddev lifetime regression + +From: Yu Kuai + +commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream. + +Commit 9e59d609763f ("md: call del_gendisk in control path") moves +setting MD_DELETED from __mddev_put() to do_md_stop(), however, for the +case create on open, mddev can be freed without do_md_stop(): + +1) open + +md_probe + md_alloc_and_put + md_alloc + mddev_alloc + atomic_set(&mddev->active, 1); + mddev->hold_active = UNTIL_IOCTL + mddev_put + atomic_dec_and_test(&mddev->active) + if (mddev->hold_active) + -> active is 0, hold_active is set +md_open + mddev_get + atomic_inc(&mddev->active); + +2) ioctl that is not STOP_ARRAY, for example, GET_ARRAY_INFO: + +md_ioctl + mddev->hold_active = 0 + +3) close + +md_release + mddev_put(mddev); + atomic_dec_and_lock(&mddev->active, &all_mddevs_lock) + __mddev_put + -> hold_active is cleared, mddev will be freed + queue_work(md_misc_wq, &mddev->del_work) + +Now that MD_DELETED is not set, before mddev is freed by +mddev_delayed_delete(), md_open can still succeed and break mddev +lifetime, causing mddev->kobj refcount underflow or mddev uaf +problem. + +Fix this problem by setting MD_DELETED before queuing del_work. + +Reported-by: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/ +Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/ +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com +Signed-off-by: Yu Kuai +Reviewed-by: Paul Menzel +Reviewed-by: Xiao Ni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/md.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -620,6 +620,12 @@ static void __mddev_put(struct mddev *md + return; + + /* ++ * If array is freed by stopping array, MD_DELETED is set by ++ * do_md_stop(), MD_DELETED is still set here in case mddev is freed ++ * directly by closing a mddev that is created by create_on_open. ++ */ ++ set_bit(MD_DELETED, &mddev->flags); ++ /* + * Call queue_work inside the spinlock so that flush_workqueue() after + * mddev_find will succeed in waiting for the work to be done. + */ diff --git a/queue-6.12/pci-honor-max-link-speed-when-determining-supported-speeds.patch b/queue-6.12/pci-honor-max-link-speed-when-determining-supported-speeds.patch new file mode 100644 index 0000000000..96dc86e845 --- /dev/null +++ b/queue-6.12/pci-honor-max-link-speed-when-determining-supported-speeds.patch @@ -0,0 +1,84 @@ +From 3202ca221578850f34e0fea39dc6cfa745ed7aac Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Tue, 17 Dec 2024 10:51:01 +0100 +Subject: PCI: Honor Max Link Speed when determining supported speeds +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Wunner + +commit 3202ca221578850f34e0fea39dc6cfa745ed7aac upstream. + +The Supported Link Speeds Vector in the Link Capabilities 2 Register +indicates the *supported* link speeds. The Max Link Speed field in the +Link Capabilities Register indicates the *maximum* of those speeds. + +pcie_get_supported_speeds() neglects to honor the Max Link Speed field and +will thus incorrectly deem higher speeds as supported. Fix it. + +One user-visible issue addressed here is an incorrect value in the sysfs +attribute "max_link_speed". + +But the main motivation is a boot hang reported by Niklas: Intel JHL7540 +"Titan Ridge 2018" Thunderbolt controllers supports 2.5-8 GT/s speeds, +but indicate 2.5 GT/s as maximum. Ilpo recalls seeing this on more +devices. It can be explained by the controller's Downstream Ports +supporting 8 GT/s if an Endpoint is attached, but limiting to 2.5 GT/s +if the port interfaces to a PCIe Adapter, in accordance with USB4 v2 +sec 11.2.1: + + "This section defines the functionality of an Internal PCIe Port that + interfaces to a PCIe Adapter. [...] + The Logical sub-block shall update the PCIe configuration registers + with the following characteristics: [...] + Max Link Speed field in the Link Capabilities Register set to 0001b + (data rate of 2.5 GT/s only). + Note: These settings do not represent actual throughput. Throughput + is implementation specific and based on the USB4 Fabric performance." + +The present commit is not sufficient on its own to fix Niklas' boot hang, +but it is a prerequisite: A subsequent commit will fix the boot hang by +enabling bandwidth control only if more than one speed is supported. + +The GENMASK() macro used herein specifies 0 as lowest bit, even though +the Supported Link Speeds Vector ends at bit 1. This is done on purpose +to avoid a GENMASK(0, 1) macro if Max Link Speed is zero. That macro +would be invalid as the lowest bit is greater than the highest bit. +Ilpo has witnessed a zero Max Link Speed on Root Complex Integrated +Endpoints in particular, so it does occur in practice. (The Link +Capabilities Register is optional on RCiEPs per PCIe r6.2 sec 7.5.3.) + +Fixes: d2bd39c0456b ("PCI: Store all PCIe Supported Link Speeds") +Closes: https://lore.kernel.org/r/70829798889c6d779ca0f6cd3260a765780d1369.camel@kernel.org +Link: https://lore.kernel.org/r/fe03941e3e1cc42fb9bf4395e302bff53ee2198b.1734428762.git.lukas@wunner.de +Reported-by: Niklas Schnelle +Tested-by: Niklas Schnelle +Signed-off-by: Lukas Wunner +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: Jonathan Cameron +Reviewed-by: Ilpo Järvinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -6235,12 +6235,14 @@ u8 pcie_get_supported_speeds(struct pci_ + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); + speeds = lnkcap2 & PCI_EXP_LNKCAP2_SLS; + ++ /* Ignore speeds higher than Max Link Speed */ ++ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); ++ speeds &= GENMASK(lnkcap & PCI_EXP_LNKCAP_SLS, 0); ++ + /* PCIe r3.0-compliant */ + if (speeds) + return speeds; + +- pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); +- + /* Synthesize from the Max Link Speed field */ + if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB) + speeds = PCI_EXP_LNKCAP2_SLS_5_0GB | PCI_EXP_LNKCAP2_SLS_2_5GB; diff --git a/queue-6.12/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch b/queue-6.12/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch new file mode 100644 index 0000000000..cc21ffe121 --- /dev/null +++ b/queue-6.12/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch @@ -0,0 +1,104 @@ +From 61399e0c5410567ef60cb1cda34cca42903842e3 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Fri, 8 Aug 2025 19:03:22 +0200 +Subject: rcu: Fix racy re-initialization of irq_work causing hangs + +From: Frederic Weisbecker + +commit 61399e0c5410567ef60cb1cda34cca42903842e3 upstream. + +RCU re-initializes the deferred QS irq work everytime before attempting +to queue it. However there are situations where the irq work is +attempted to be queued even though it is already queued. In that case +re-initializing messes-up with the irq work queue that is about to be +handled. + +The chances for that to happen are higher when the architecture doesn't +support self-IPIs and irq work are then all lazy, such as with the +following sequence: + +1) rcu_read_unlock() is called when IRQs are disabled and there is a + grace period involving blocked tasks on the node. The irq work + is then initialized and queued. + +2) The related tasks are unblocked and the CPU quiescent state + is reported. rdp->defer_qs_iw_pending is reset to DEFER_QS_IDLE, + allowing the irq work to be requeued in the future (note the previous + one hasn't fired yet). + +3) A new grace period starts and the node has blocked tasks. + +4) rcu_read_unlock() is called when IRQs are disabled again. The irq work + is re-initialized (but it's queued! and its node is cleared) and + requeued. Which means it's requeued to itself. + +5) The irq work finally fires with the tick. But since it was requeued + to itself, it loops and hangs. + +Fix this with initializing the irq work only once before the CPU boots. + +Fixes: b41642c87716 ("rcu: Fix rcu_read_unlock() deadloop due to IRQ work") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202508071303.c1134cce-lkp@intel.com +Signed-off-by: Frederic Weisbecker +Reviewed-by: Joel Fernandes +Signed-off-by: Neeraj Upadhyay (AMD) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/rcu/tree.c | 2 ++ + kernel/rcu/tree.h | 1 + + kernel/rcu/tree_plugin.h | 8 ++++++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -5027,6 +5027,8 @@ int rcutree_prepare_cpu(unsigned int cpu + rdp->rcu_iw_gp_seq = rdp->gp_seq - 1; + trace_rcu_grace_period(rcu_state.name, rdp->gp_seq, TPS("cpuonl")); + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); ++ ++ rcu_preempt_deferred_qs_init(rdp); + rcu_spawn_rnp_kthreads(rnp); + rcu_spawn_cpu_nocb_kthread(cpu); + ASSERT_EXCLUSIVE_WRITER(rcu_state.n_online_cpus); +--- a/kernel/rcu/tree.h ++++ b/kernel/rcu/tree.h +@@ -487,6 +487,7 @@ static int rcu_print_task_exp_stall(stru + static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); + static void rcu_flavor_sched_clock_irq(int user); + static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck); ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp); + static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); + static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); + static bool rcu_is_callbacks_kthread(struct rcu_data *rdp); +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -698,8 +698,6 @@ static void rcu_read_unlock_special(stru + cpu_online(rdp->cpu)) { + // Get scheduler to re-evaluate and call hooks. + // If !IRQ_WORK, FQS scan will eventually IPI. +- rdp->defer_qs_iw = +- IRQ_WORK_INIT_HARD(rcu_preempt_deferred_qs_handler); + rdp->defer_qs_iw_pending = DEFER_QS_PENDING; + irq_work_queue_on(&rdp->defer_qs_iw, rdp->cpu); + } +@@ -839,6 +837,10 @@ dump_blkd_tasks(struct rcu_node *rnp, in + } + } + ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp) ++{ ++ rdp->defer_qs_iw = IRQ_WORK_INIT_HARD(rcu_preempt_deferred_qs_handler); ++} + #else /* #ifdef CONFIG_PREEMPT_RCU */ + + /* +@@ -1038,6 +1040,8 @@ dump_blkd_tasks(struct rcu_node *rnp, in + WARN_ON_ONCE(!list_empty(&rnp->blkd_tasks)); + } + ++static void rcu_preempt_deferred_qs_init(struct rcu_data *rdp) { } ++ + #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ + + /* diff --git a/queue-6.12/series b/queue-6.12/series index 4b7cf78d2c..2dd92b7997 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -434,3 +434,11 @@ arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch rust-kbuild-clean-output-before-running-rustdoc.patch rust-workaround-rustdoc-target-modifiers-bug.patch +ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch +io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch +firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch +drm-amd-display-allow-dcn301-to-clear-update-flags.patch +md-fix-create-on-open-mddev-lifetime-regression.patch +rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch +dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch +pci-honor-max-link-speed-when-determining-supported-speeds.patch -- 2.47.3