]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Aug 2025 12:13:55 +0000 (14:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Aug 2025 12:13:55 +0000 (14:13 +0200)
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

queue-6.12/ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch [new file with mode: 0644]
queue-6.12/dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch [new file with mode: 0644]
queue-6.12/drm-amd-display-allow-dcn301-to-clear-update-flags.patch [new file with mode: 0644]
queue-6.12/firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch [new file with mode: 0644]
queue-6.12/io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch [new file with mode: 0644]
queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch [new file with mode: 0644]
queue-6.12/pci-honor-max-link-speed-when-determining-supported-speeds.patch [new file with mode: 0644]
queue-6.12/rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch [new file with mode: 0644]
queue-6.12/series

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 (file)
index 0000000..f097b14
--- /dev/null
@@ -0,0 +1,148 @@
+From 0060beec0bfa647c4b510df188b1c4673a197839 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Mon, 28 Jul 2025 13:04:29 +0900
+Subject: ata: libata-sata: Add link_power_management_supported sysfs attribute
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+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 <chaitanya.kumar.borah@intel.com>
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202507251014.a5becc3b-lkp@intel.com
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..44a6ba4
--- /dev/null
@@ -0,0 +1,85 @@
+From 675f940576351bb049f5677615140b9d0a7712d0 Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+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 <shinichiro.kawasaki@wdc.com>
+
+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 <shinichiro.kawasaki@wdc.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
+Link: https://lore.kernel.org/r/20250717103539.37279-1-shinichiro.kawasaki@wdc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..0453a18
--- /dev/null
@@ -0,0 +1,37 @@
+From 2d418e4fd9f1eca7dfce80de86dd702d36a06a25 Mon Sep 17 00:00:00 2001
+From: Ivan Lipski <ivan.lipski@amd.com>
+Date: Thu, 17 Jul 2025 13:58:35 -0400
+Subject: drm/amd/display: Allow DCN301 to clear update flags
+
+From: Ivan Lipski <ivan.lipski@amd.com>
+
+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 <mario.limonciello@amd.com>
+Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..18956e5
--- /dev/null
@@ -0,0 +1,49 @@
+From 62d6b81e8bd207ad44eff39d1a0fe17f0df510a5 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 9 Jul 2025 09:01:01 +0200
+Subject: firmware: arm_scmi: Convert to SYSTEM_SLEEP_PM_OPS
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+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 <arnd@arndb.de>
+Acked-by: Peng Fan <peng.fan@nxp.com>
+Message-Id: <20250709070107.1388512-1-arnd@kernel.org>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f6cdb98
--- /dev/null
@@ -0,0 +1,38 @@
+From 825aea662b492571877b32aeeae13689fd9fbee4 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 7 Jul 2025 16:46:30 -0600
+Subject: io_uring/rw: cast rw->flags assignment to rwf_t
+
+From: Jens Axboe <axboe@kernel.dk>
+
+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 <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202507032211.PwSNPNSP-lkp@intel.com/
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..14ab850
--- /dev/null
@@ -0,0 +1,79 @@
+From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001
+From: Yu Kuai <yukuai3@huawei.com>
+Date: Wed, 30 Jul 2025 15:33:21 +0800
+Subject: md: fix create on open mddev lifetime regression
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+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 <yukuai3@huawei.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..96dc86e
--- /dev/null
@@ -0,0 +1,84 @@
+From 3202ca221578850f34e0fea39dc6cfa745ed7aac Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+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 <lukas@wunner.de>
+
+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 <niks@kernel.org>
+Tested-by: Niklas Schnelle <niks@kernel.org>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..cc21ffe
--- /dev/null
@@ -0,0 +1,104 @@
+From 61399e0c5410567ef60cb1cda34cca42903842e3 Mon Sep 17 00:00:00 2001
+From: Frederic Weisbecker <frederic@kernel.org>
+Date: Fri, 8 Aug 2025 19:03:22 +0200
+Subject: rcu: Fix racy re-initialization of irq_work causing hangs
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+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 <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202508071303.c1134cce-lkp@intel.com
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
+Signed-off-by: Neeraj Upadhyay (AMD) <neeraj.upadhyay@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 */
+ /*
index 4b7cf78d2c321477c3376dfb27bdb4d4af57be2a..2dd92b79970bc4fc2f785193bded9d590791f964 100644 (file)
@@ -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