]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Feb 2026 14:20:37 +0000 (15:20 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Feb 2026 14:20:37 +0000 (15:20 +0100)
added patches:
alsa-hda-realtek-fix-right-sounds-and-mute-micmute-leds-for-hp-machine.patch
asoc-amd-yc-add-dmi-quirk-for-acer-travelmate-p216-41-tco.patch
asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch
btrfs-do-not-strictly-require-dirty-metadata-threshold-for-metadata-writepages.patch
efivarfs-fix-error-propagation-in-efivar_entry_get.patch
firewire-core-fix-race-condition-against-transaction-list.patch
flex_proportions-make-fprop_new_period-hardirq-safe.patch
gpio-pca953x-mask-interrupts-in-irq-shutdown.patch
gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch
kbuild-rust-clean-libpin_init_internal-in-mrproper.patch
mm-kasan-fix-kasan-poisoning-in-vrealloc.patch
mm-kfence-randomize-the-freelist-on-initialization.patch
mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
mm-memory-failure-teach-kill_accessing_process-to-accept-hugetlb-tail-page-pfn.patch
mm-shmem-swap-fix-race-of-truncate-and-swap-entry-split.patch
mm-swap-restore-swap_space-attr-aviod-kernel-panic.patch
mptcp-only-reset-subflow-errors-when-propagated.patch
net-fix-segmentation-of-forwarding-fraglist-gro.patch
nvmet-fix-race-in-nvmet_bio_done-leading-to-null-pointer-dereference.patch
perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch
pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch
pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch
pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch
riscv-compat-fix-compat_uts_machine-definition.patch
rust-kbuild-give-config-path-to-rustfmt-in-.rsi-target.patch
rust-rbtree-fix-documentation-typo-in-cursormut-peek_next-method.patch
scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch
scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch
selftests-mptcp-check-no-dup-close-events-after-error.patch
selftests-mptcp-check-subflow-errors-in-close-events.patch
selftests-mptcp-join-fix-local-endp-not-being-tracked.patch
writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch

33 files changed:
queue-6.18/alsa-hda-realtek-fix-right-sounds-and-mute-micmute-leds-for-hp-machine.patch [new file with mode: 0644]
queue-6.18/asoc-amd-yc-add-dmi-quirk-for-acer-travelmate-p216-41-tco.patch [new file with mode: 0644]
queue-6.18/asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch [new file with mode: 0644]
queue-6.18/btrfs-do-not-strictly-require-dirty-metadata-threshold-for-metadata-writepages.patch [new file with mode: 0644]
queue-6.18/efivarfs-fix-error-propagation-in-efivar_entry_get.patch [new file with mode: 0644]
queue-6.18/firewire-core-fix-race-condition-against-transaction-list.patch [new file with mode: 0644]
queue-6.18/flex_proportions-make-fprop_new_period-hardirq-safe.patch [new file with mode: 0644]
queue-6.18/gpio-pca953x-mask-interrupts-in-irq-shutdown.patch [new file with mode: 0644]
queue-6.18/gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch [new file with mode: 0644]
queue-6.18/kbuild-rust-clean-libpin_init_internal-in-mrproper.patch [new file with mode: 0644]
queue-6.18/mm-kasan-fix-kasan-poisoning-in-vrealloc.patch [new file with mode: 0644]
queue-6.18/mm-kfence-randomize-the-freelist-on-initialization.patch [new file with mode: 0644]
queue-6.18/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch [new file with mode: 0644]
queue-6.18/mm-memory-failure-teach-kill_accessing_process-to-accept-hugetlb-tail-page-pfn.patch [new file with mode: 0644]
queue-6.18/mm-shmem-swap-fix-race-of-truncate-and-swap-entry-split.patch [new file with mode: 0644]
queue-6.18/mm-swap-restore-swap_space-attr-aviod-kernel-panic.patch [new file with mode: 0644]
queue-6.18/mptcp-only-reset-subflow-errors-when-propagated.patch [new file with mode: 0644]
queue-6.18/net-fix-segmentation-of-forwarding-fraglist-gro.patch [new file with mode: 0644]
queue-6.18/nvmet-fix-race-in-nvmet_bio_done-leading-to-null-pointer-dereference.patch [new file with mode: 0644]
queue-6.18/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch [new file with mode: 0644]
queue-6.18/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch [new file with mode: 0644]
queue-6.18/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch [new file with mode: 0644]
queue-6.18/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch [new file with mode: 0644]
queue-6.18/riscv-compat-fix-compat_uts_machine-definition.patch [new file with mode: 0644]
queue-6.18/rust-kbuild-give-config-path-to-rustfmt-in-.rsi-target.patch [new file with mode: 0644]
queue-6.18/rust-rbtree-fix-documentation-typo-in-cursormut-peek_next-method.patch [new file with mode: 0644]
queue-6.18/scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch [new file with mode: 0644]
queue-6.18/scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch [new file with mode: 0644]
queue-6.18/selftests-mptcp-check-no-dup-close-events-after-error.patch [new file with mode: 0644]
queue-6.18/selftests-mptcp-check-subflow-errors-in-close-events.patch [new file with mode: 0644]
queue-6.18/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch [new file with mode: 0644]

diff --git a/queue-6.18/alsa-hda-realtek-fix-right-sounds-and-mute-micmute-leds-for-hp-machine.patch b/queue-6.18/alsa-hda-realtek-fix-right-sounds-and-mute-micmute-leds-for-hp-machine.patch
new file mode 100644 (file)
index 0000000..f891829
--- /dev/null
@@ -0,0 +1,33 @@
+From 891b77d459d0ce993c68365d899134bc9fd47ac0 Mon Sep 17 00:00:00 2001
+From: Zhang Heng <zhangheng@kylinos.cn>
+Date: Mon, 26 Jan 2026 15:35:07 +0800
+Subject: ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP machine
+
+From: Zhang Heng <zhangheng@kylinos.cn>
+
+commit 891b77d459d0ce993c68365d899134bc9fd47ac0 upstream.
+
+The HP EliteBook 630 G11 (103c:8c8f) is using ALC236 codec which used 0x02
+to control mute LED and 0x01 to control micmute LED. Therefore, add a quirk
+to make it works.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220828
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
+Link: https://patch.msgid.link/20260126073508.3897461-1-zhangheng@kylinos.cn
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -6631,6 +6631,7 @@ static const struct hda_quirk alc269_fix
+       SND_PCI_QUIRK(0x103c, 0x8c8c, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c8d, "HP ProBook 440 G11", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c8e, "HP ProBook 460 G11", ALC236_FIXUP_HP_GPIO_LED),
++      SND_PCI_QUIRK(0x103c, 0x8c8f, "HP EliteBook 630 G11", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c90, "HP EliteBook 640", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c91, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
diff --git a/queue-6.18/asoc-amd-yc-add-dmi-quirk-for-acer-travelmate-p216-41-tco.patch b/queue-6.18/asoc-amd-yc-add-dmi-quirk-for-acer-travelmate-p216-41-tco.patch
new file mode 100644 (file)
index 0000000..2f1e985
--- /dev/null
@@ -0,0 +1,39 @@
+From 9502b7df5a3c7e174f74f20324ac1fe781fc5c2d Mon Sep 17 00:00:00 2001
+From: Zhang Heng <zhangheng@kylinos.cn>
+Date: Mon, 26 Jan 2026 09:49:52 +0800
+Subject: ASoC: amd: yc: Add DMI quirk for Acer TravelMate P216-41-TCO
+
+From: Zhang Heng <zhangheng@kylinos.cn>
+
+commit 9502b7df5a3c7e174f74f20324ac1fe781fc5c2d upstream.
+
+Add a DMI quirk for the Acer TravelMate P216-41-TCO fixing the
+issue where the internal microphone was not detected.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=220983
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
+Link: https://patch.msgid.link/20260126014952.3674450-1-zhangheng@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -668,6 +668,14 @@ static const struct dmi_system_id yc_acp
+                       DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"),
+               }
+       },
++      {
++              .driver_data = &acp6x_card,
++              .matches = {
++                      DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
++                      DMI_MATCH(DMI_BOARD_NAME, "XyloD5_RBU"),
++              }
++      },
++
+       {}
+ };
diff --git a/queue-6.18/asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch b/queue-6.18/asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch
new file mode 100644 (file)
index 0000000..d7fab94
--- /dev/null
@@ -0,0 +1,47 @@
+From 9210f5ff6318163835d9e42ee68006be4da0f531 Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@gmail.com>
+Date: Sun, 18 Jan 2026 17:50:30 -0300
+Subject: ASoC: fsl: imx-card: Do not force slot width to sample width
+
+From: Fabio Estevam <festevam@gmail.com>
+
+commit 9210f5ff6318163835d9e42ee68006be4da0f531 upstream.
+
+imx-card currently sets the slot width to the physical sample width
+for I2S links. This breaks controllers that use fixed-width slots
+(e.g. 32-bit FIFO words), causing the unused bits in the slot to
+contain undefined data when playing 16-bit streams.
+
+Do not override the slot width in the machine driver and let the CPU
+DAI select an appropriate default instead. This matches the behavior
+of simple-audio-card and avoids embedding controller-specific policy
+in the machine driver.
+
+On an i.MX8MP-based board using SAI as the I2S master with 32-bit slots,
+playing 16-bit audio resulted in spurious frequencies and an incorrect
+SAI data waveform, as the slot width was forced to 16 bits. After this
+change, audio artifacts are eliminated and the 16-bit samples correctly
+occupy the first half of the 32-bit slot, with the remaining bits padded
+with zeroes.
+
+Cc: stable@vger.kernel.org
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://patch.msgid.link/20260118205030.1532696-1-festevam@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/fsl/imx-card.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -346,7 +346,6 @@ static int imx_aif_hw_params(struct snd_
+                             SND_SOC_DAIFMT_PDM;
+               } else {
+                       slots = 2;
+-                      slot_width = params_physical_width(params);
+                       fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
+                             SND_SOC_DAIFMT_I2S;
+               }
diff --git a/queue-6.18/btrfs-do-not-strictly-require-dirty-metadata-threshold-for-metadata-writepages.patch b/queue-6.18/btrfs-do-not-strictly-require-dirty-metadata-threshold-for-metadata-writepages.patch
new file mode 100644 (file)
index 0000000..cd25489
--- /dev/null
@@ -0,0 +1,158 @@
+From 4e159150a9a56d66d247f4b5510bed46fe58aa1c Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Mon, 19 Jan 2026 17:31:19 +1030
+Subject: btrfs: do not strictly require dirty metadata threshold for metadata writepages
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 4e159150a9a56d66d247f4b5510bed46fe58aa1c upstream.
+
+[BUG]
+There is an internal report that over 1000 processes are
+waiting at the io_schedule_timeout() of balance_dirty_pages(), causing
+a system hang and trigger a kernel coredump.
+
+The kernel is v6.4 kernel based, but the root problem still applies to
+any upstream kernel before v6.18.
+
+[CAUSE]
+From Jan Kara for his wisdom on the dirty page balance behavior first.
+
+  This cgroup dirty limit was what was actually playing the role here
+  because the cgroup had only a small amount of memory and so the dirty
+  limit for it was something like 16MB.
+
+  Dirty throttling is responsible for enforcing that nobody can dirty
+  (significantly) more dirty memory than there's dirty limit. Thus when
+  a task is dirtying pages it periodically enters into balance_dirty_pages()
+  and we let it sleep there to slow down the dirtying.
+
+  When the system is over dirty limit already (either globally or within
+  a cgroup of the running task), we will not let the task exit from
+  balance_dirty_pages() until the number of dirty pages drops below the
+  limit.
+
+  So in this particular case, as I already mentioned, there was a cgroup
+  with relatively small amount of memory and as a result with dirty limit
+  set at 16MB. A task from that cgroup has dirtied about 28MB worth of
+  pages in btrfs btree inode and these were practically the only dirty
+  pages in that cgroup.
+
+So that means the only way to reduce the dirty pages of that cgroup is
+to writeback the dirty pages of btrfs btree inode, and only after that
+those processes can exit balance_dirty_pages().
+
+Now back to the btrfs part, btree_writepages() is responsible for
+writing back dirty btree inode pages.
+
+The problem here is, there is a btrfs internal threshold that if the
+btree inode's dirty bytes are below the 32M threshold, it will not
+do any writeback.
+
+This behavior is to batch as much metadata as possible so we won't write
+back those tree blocks and then later re-COW them again for another
+modification.
+
+This internal 32MiB is higher than the existing dirty page size (28MiB),
+meaning no writeback will happen, causing a deadlock between btrfs and
+cgroup:
+
+- Btrfs doesn't want to write back btree inode until more dirty pages
+
+- Cgroup/MM doesn't want more dirty pages for btrfs btree inode
+  Thus any process touching that btree inode is put into sleep until
+  the number of dirty pages is reduced.
+
+Thanks Jan Kara a lot for the analysis of the root cause.
+
+[ENHANCEMENT]
+Since kernel commit b55102826d7d ("btrfs: set AS_KERNEL_FILE on the
+btree_inode"), btrfs btree inode pages will only be charged to the root
+cgroup which should have a much larger limit than btrfs' 32MiB
+threshold.
+So it should not affect newer kernels.
+
+But for all current LTS kernels, they are all affected by this problem,
+and backporting the whole AS_KERNEL_FILE may not be a good idea.
+
+Even for newer kernels I still think it's a good idea to get
+rid of the internal threshold at btree_writepages(), since for most cases
+cgroup/MM has a better view of full system memory usage than btrfs' fixed
+threshold.
+
+For internal callers using btrfs_btree_balance_dirty() since that
+function is already doing internal threshold check, we don't need to
+bother them.
+
+But for external callers of btree_writepages(), just respect their
+requests and write back whatever they want, ignoring the internal
+btrfs threshold to avoid such deadlock on btree inode dirty page
+balancing.
+
+CC: stable@vger.kernel.org
+CC: Jan Kara <jack@suse.cz>
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/disk-io.c   |   22 ----------------------
+ fs/btrfs/extent_io.c |    3 +--
+ fs/btrfs/extent_io.h |    3 +--
+ 3 files changed, 2 insertions(+), 26 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -490,28 +490,6 @@ static int btree_migrate_folio(struct ad
+ #define btree_migrate_folio NULL
+ #endif
+-static int btree_writepages(struct address_space *mapping,
+-                          struct writeback_control *wbc)
+-{
+-      int ret;
+-
+-      if (wbc->sync_mode == WB_SYNC_NONE) {
+-              struct btrfs_fs_info *fs_info;
+-
+-              if (wbc->for_kupdate)
+-                      return 0;
+-
+-              fs_info = inode_to_fs_info(mapping->host);
+-              /* this is a bit racy, but that's ok */
+-              ret = __percpu_counter_compare(&fs_info->dirty_metadata_bytes,
+-                                           BTRFS_DIRTY_METADATA_THRESH,
+-                                           fs_info->dirty_metadata_batch);
+-              if (ret < 0)
+-                      return 0;
+-      }
+-      return btree_write_cache_pages(mapping, wbc);
+-}
+-
+ static bool btree_release_folio(struct folio *folio, gfp_t gfp_flags)
+ {
+       if (folio_test_writeback(folio) || folio_test_dirty(folio))
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -2289,8 +2289,7 @@ void btrfs_btree_wait_writeback_range(st
+       }
+ }
+-int btree_write_cache_pages(struct address_space *mapping,
+-                                 struct writeback_control *wbc)
++int btree_writepages(struct address_space *mapping, struct writeback_control *wbc)
+ {
+       struct btrfs_eb_write_context ctx = { .wbc = wbc };
+       struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host);
+--- a/fs/btrfs/extent_io.h
++++ b/fs/btrfs/extent_io.h
+@@ -238,8 +238,7 @@ void extent_write_locked_range(struct in
+                              u64 start, u64 end, struct writeback_control *wbc,
+                              bool pages_dirty);
+ int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc);
+-int btree_write_cache_pages(struct address_space *mapping,
+-                          struct writeback_control *wbc);
++int btree_writepages(struct address_space *mapping, struct writeback_control *wbc);
+ void btrfs_btree_wait_writeback_range(struct btrfs_fs_info *fs_info, u64 start, u64 end);
+ void btrfs_readahead(struct readahead_control *rac);
+ int set_folio_extent_mapped(struct folio *folio);
diff --git a/queue-6.18/efivarfs-fix-error-propagation-in-efivar_entry_get.patch b/queue-6.18/efivarfs-fix-error-propagation-in-efivar_entry_get.patch
new file mode 100644 (file)
index 0000000..77e4050
--- /dev/null
@@ -0,0 +1,37 @@
+From 4b22ec1685ce1fc0d862dcda3225d852fb107995 Mon Sep 17 00:00:00 2001
+From: Kohei Enju <kohei@enjuk.jp>
+Date: Sat, 17 Jan 2026 16:00:45 +0000
+Subject: efivarfs: fix error propagation in efivar_entry_get()
+
+From: Kohei Enju <kohei@enjuk.jp>
+
+commit 4b22ec1685ce1fc0d862dcda3225d852fb107995 upstream.
+
+efivar_entry_get() always returns success even if the underlying
+__efivar_entry_get() fails, masking errors.
+
+This may result in uninitialized heap memory being copied to userspace
+in the efivarfs_file_read() path.
+
+Fix it by returning the error from __efivar_entry_get().
+
+Fixes: 2d82e6227ea1 ("efi: vars: Move efivar caching layer into efivarfs")
+Cc: <stable@vger.kernel.org> # v6.1+
+Signed-off-by: Kohei Enju <kohei@enjuk.jp>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/efivarfs/vars.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/efivarfs/vars.c
++++ b/fs/efivarfs/vars.c
+@@ -552,7 +552,7 @@ int efivar_entry_get(struct efivar_entry
+       err = __efivar_entry_get(entry, attributes, size, data);
+       efivar_unlock();
+-      return 0;
++      return err;
+ }
+ /**
diff --git a/queue-6.18/firewire-core-fix-race-condition-against-transaction-list.patch b/queue-6.18/firewire-core-fix-race-condition-against-transaction-list.patch
new file mode 100644 (file)
index 0000000..0f0e34f
--- /dev/null
@@ -0,0 +1,76 @@
+From 20e01bba2ae4898ce65cdcacd1bd6bec5111abd9 Mon Sep 17 00:00:00 2001
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Date: Wed, 28 Jan 2026 07:34:13 +0900
+Subject: firewire: core: fix race condition against transaction list
+
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+
+commit 20e01bba2ae4898ce65cdcacd1bd6bec5111abd9 upstream.
+
+The list of transaction is enumerated without acquiring card lock when
+processing AR response event. This causes a race condition bug when
+processing AT request completion event concurrently.
+
+This commit fixes the bug by put timer start for split transaction
+expiration into the scope of lock. The value of jiffies in card structure
+is referred before acquiring the lock.
+
+Cc: stable@vger.kernel.org # v6.18
+Fixes: b5725cfa4120 ("firewire: core: use spin lock specific to timer for split transaction")
+Reported-by: Andreas Persson <andreasp56@outlook.com>
+Closes: https://github.com/alsa-project/snd-firewire-ctl-services/issues/209
+Tested-by: Andreas Persson <andreasp56@outlook.com>
+Link: https://lore.kernel.org/r/20260127223413.22265-1-o-takashi@sakamocchi.jp
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firewire/core-transaction.c |   19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/firewire/core-transaction.c
++++ b/drivers/firewire/core-transaction.c
+@@ -134,20 +134,14 @@ static void split_transaction_timeout_ca
+       }
+ }
+-static void start_split_transaction_timeout(struct fw_transaction *t,
+-                                          struct fw_card *card)
++// card->transactions.lock should be acquired in advance for the linked list.
++static void start_split_transaction_timeout(struct fw_transaction *t, unsigned int delta)
+ {
+-      unsigned long delta;
+-
+       if (list_empty(&t->link) || WARN_ON(t->is_split_transaction))
+               return;
+       t->is_split_transaction = true;
+-      // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
+-      // local destination never runs in any type of IRQ context.
+-      scoped_guard(spinlock_irqsave, &card->split_timeout.lock)
+-              delta = card->split_timeout.jiffies;
+       mod_timer(&t->split_timeout_timer, jiffies + delta);
+ }
+@@ -168,13 +162,20 @@ static void transmit_complete_callback(s
+               break;
+       case ACK_PENDING:
+       {
++              unsigned int delta;
++
+               // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
+               // local destination never runs in any type of IRQ context.
+               scoped_guard(spinlock_irqsave, &card->split_timeout.lock) {
+                       t->split_timeout_cycle =
+                               compute_split_timeout_timestamp(card, packet->timestamp) & 0xffff;
++                      delta = card->split_timeout.jiffies;
+               }
+-              start_split_transaction_timeout(t, card);
++
++              // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
++              // local destination never runs in any type of IRQ context.
++              scoped_guard(spinlock_irqsave, &card->transactions.lock)
++                      start_split_transaction_timeout(t, delta);
+               break;
+       }
+       case ACK_BUSY_X:
diff --git a/queue-6.18/flex_proportions-make-fprop_new_period-hardirq-safe.patch b/queue-6.18/flex_proportions-make-fprop_new_period-hardirq-safe.patch
new file mode 100644 (file)
index 0000000..9c7b262
--- /dev/null
@@ -0,0 +1,79 @@
+From dd9e2f5b38f1fdd49b1ab6d3a85f81c14369eacc Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 21 Jan 2026 12:27:30 +0100
+Subject: flex_proportions: make fprop_new_period() hardirq safe
+
+From: Jan Kara <jack@suse.cz>
+
+commit dd9e2f5b38f1fdd49b1ab6d3a85f81c14369eacc upstream.
+
+Bernd has reported a lockdep splat from flexible proportions code that is
+essentially complaining about the following race:
+
+<timer fires>
+run_timer_softirq - we are in softirq context
+  call_timer_fn
+    writeout_period
+      fprop_new_period
+        write_seqcount_begin(&p->sequence);
+
+        <hardirq is raised>
+        ...
+        blk_mq_end_request()
+         blk_update_request()
+           ext4_end_bio()
+             folio_end_writeback()
+               __wb_writeout_add()
+                 __fprop_add_percpu_max()
+                   if (unlikely(max_frac < FPROP_FRAC_BASE)) {
+                     fprop_fraction_percpu()
+                       seq = read_seqcount_begin(&p->sequence);
+                         - sees odd sequence so loops indefinitely
+
+Note that a deadlock like this is only possible if the bdi has configured
+maximum fraction of writeout throughput which is very rare in general but
+frequent for example for FUSE bdis.  To fix this problem we have to make
+sure write section of the sequence counter is irqsafe.
+
+Link: https://lkml.kernel.org/r/20260121112729.24463-2-jack@suse.cz
+Fixes: a91befde3503 ("lib/flex_proportions.c: remove local_irq_ops in fprop_new_period()")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reported-by: Bernd Schubert <bernd@bsbernd.com>
+Link: https://lore.kernel.org/all/9b845a47-9aee-43dd-99bc-1a82bea00442@bsbernd.com/
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Joanne Koong <joannelkoong@gmail.com>
+Cc: Miklos Szeredi <miklos@szeredi.hu>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/flex_proportions.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/lib/flex_proportions.c
++++ b/lib/flex_proportions.c
+@@ -64,13 +64,14 @@ void fprop_global_destroy(struct fprop_g
+ bool fprop_new_period(struct fprop_global *p, int periods)
+ {
+       s64 events = percpu_counter_sum(&p->events);
++      unsigned long flags;
+       /*
+        * Don't do anything if there are no events.
+        */
+       if (events <= 1)
+               return false;
+-      preempt_disable_nested();
++      local_irq_save(flags);
+       write_seqcount_begin(&p->sequence);
+       if (periods < 64)
+               events -= events >> periods;
+@@ -78,7 +79,7 @@ bool fprop_new_period(struct fprop_globa
+       percpu_counter_add(&p->events, -events);
+       p->period += periods;
+       write_seqcount_end(&p->sequence);
+-      preempt_enable_nested();
++      local_irq_restore(flags);
+       return true;
+ }
diff --git a/queue-6.18/gpio-pca953x-mask-interrupts-in-irq-shutdown.patch b/queue-6.18/gpio-pca953x-mask-interrupts-in-irq-shutdown.patch
new file mode 100644 (file)
index 0000000..1d9205e
--- /dev/null
@@ -0,0 +1,34 @@
+From d02f20a4de0c498fbba2b0e3c1496e72c630a91e Mon Sep 17 00:00:00 2001
+From: Martin Larsson <martin.larsson@actia.se>
+Date: Wed, 21 Jan 2026 12:57:22 +0000
+Subject: gpio: pca953x: mask interrupts in irq shutdown
+
+From: Martin Larsson <martin.larsson@actia.se>
+
+commit d02f20a4de0c498fbba2b0e3c1496e72c630a91e upstream.
+
+In the existing implementation irq_shutdown does not mask the interrupts
+in hardware. This can cause spurious interrupts from the IO expander.
+Add masking to irq_shutdown to prevent spurious interrupts.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Larsson <martin.larsson@actia.se>
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://lore.kernel.org/r/20260121125631.2758346-1-martin.larsson@actia.se
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpio-pca953x.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -911,6 +911,8 @@ static void pca953x_irq_shutdown(struct
+       clear_bit(hwirq, chip->irq_trig_fall);
+       clear_bit(hwirq, chip->irq_trig_level_low);
+       clear_bit(hwirq, chip->irq_trig_level_high);
++
++      pca953x_irq_mask(d);
+ }
+ static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p)
diff --git a/queue-6.18/gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch b/queue-6.18/gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch
new file mode 100644 (file)
index 0000000..e501ac1
--- /dev/null
@@ -0,0 +1,89 @@
+From 7ca497be00163610afb663867db24ac408752f13 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Mon, 26 Jan 2026 12:12:26 +0000
+Subject: gpio: rockchip: Stop calling pinctrl for set_direction
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+commit 7ca497be00163610afb663867db24ac408752f13 upstream.
+
+Marking the whole controller as sleeping due to the pinctrl calls in the
+.direction_{input,output} callbacks has the unfortunate side effect that
+legitimate invocations of .get and .set, which cannot themselves sleep,
+in atomic context now spew WARN()s from gpiolib.
+
+However, as Heiko points out, the driver doing this is a bit silly to
+begin with, as the pinctrl .gpio_set_direction hook doesn't even care
+about the direction, the hook is only used to claim the mux. And sure
+enough, the .gpio_request_enable hook exists to serve this very purpose,
+so switch to that and remove the problematic business entirely.
+
+Cc: stable@vger.kernel.org
+Fixes: 20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping")
+Suggested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/bddc0469f25843ca5ae0cf578ab3671435ae98a7.1769429546.git.robin.murphy@arm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpio-rockchip.c       |    8 --------
+ drivers/pinctrl/pinctrl-rockchip.c |    9 ++++-----
+ 2 files changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -18,7 +18,6 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+-#include <linux/pinctrl/consumer.h>
+ #include <linux/pinctrl/pinconf-generic.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+@@ -164,12 +163,6 @@ static int rockchip_gpio_set_direction(s
+       unsigned long flags;
+       u32 data = input ? 0 : 1;
+-
+-      if (input)
+-              pinctrl_gpio_direction_input(chip, offset);
+-      else
+-              pinctrl_gpio_direction_output(chip, offset);
+-
+       raw_spin_lock_irqsave(&bank->slock, flags);
+       rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
+       raw_spin_unlock_irqrestore(&bank->slock, flags);
+@@ -593,7 +586,6 @@ static int rockchip_gpiolib_register(str
+       gc->ngpio = bank->nr_pins;
+       gc->label = bank->name;
+       gc->parent = bank->dev;
+-      gc->can_sleep = true;
+       ret = gpiochip_add_data(gc, bank);
+       if (ret) {
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -3184,10 +3184,9 @@ static int rockchip_pmx_set(struct pinct
+       return 0;
+ }
+-static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+-                                         struct pinctrl_gpio_range *range,
+-                                         unsigned offset,
+-                                         bool input)
++static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
++                                          struct pinctrl_gpio_range *range,
++                                          unsigned int offset)
+ {
+       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+       struct rockchip_pin_bank *bank;
+@@ -3201,7 +3200,7 @@ static const struct pinmux_ops rockchip_
+       .get_function_name      = rockchip_pmx_get_func_name,
+       .get_function_groups    = rockchip_pmx_get_groups,
+       .set_mux                = rockchip_pmx_set,
+-      .gpio_set_direction     = rockchip_pmx_gpio_set_direction,
++      .gpio_request_enable    = rockchip_pmx_gpio_request_enable,
+ };
+ /*
diff --git a/queue-6.18/kbuild-rust-clean-libpin_init_internal-in-mrproper.patch b/queue-6.18/kbuild-rust-clean-libpin_init_internal-in-mrproper.patch
new file mode 100644 (file)
index 0000000..fea146c
--- /dev/null
@@ -0,0 +1,42 @@
+From a44bfed9df8a514962e2cb076d9c0b594caeff36 Mon Sep 17 00:00:00 2001
+From: Chen Miao <chenmiao@openatom.club>
+Date: Fri, 31 Oct 2025 02:32:39 +0000
+Subject: kbuild: rust: clean libpin_init_internal in mrproper
+
+From: Chen Miao <chenmiao@openatom.club>
+
+commit a44bfed9df8a514962e2cb076d9c0b594caeff36 upstream.
+
+When I enabled Rust compilation, I wanted to clean up its output, so I
+used make mrproper. However, I was still able to find that
+libpin_init_internal.so in the rust directory was not deleted, while
+all other corresponding outputs were cleared.
+
+Thus add it to the `MRPROPER_FILES` list.
+
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Chen Miao <chenmiao@openatom.club>
+Fixes: d7659acca7a3 ("rust: add pin-init crate build infrastructure")
+Cc: stable@vger.kernel.org
+Acked-by: Nicolas Schier <nsc@kernel.org>
+Acked-by: Benno Lossin <lossin@kernel.org>
+Link: https://patch.msgid.link/71ff222b8731e63e06059c5d8566434e508baf2b.1761876365.git.chenmiao@openatom.club
+[ Fixed tags and Git author as discussed. Reworded slightly. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Makefile |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1590,7 +1590,8 @@ MRPROPER_FILES += include/config include
+                 certs/x509.genkey \
+                 vmlinux-gdb.py \
+                 rpmbuild \
+-                rust/libmacros.so rust/libmacros.dylib
++                rust/libmacros.so rust/libmacros.dylib \
++                rust/libpin_init_internal.so rust/libpin_init_internal.dylib
+ # clean - Delete most, but leave enough to build external modules
+ #
diff --git a/queue-6.18/mm-kasan-fix-kasan-poisoning-in-vrealloc.patch b/queue-6.18/mm-kasan-fix-kasan-poisoning-in-vrealloc.patch
new file mode 100644 (file)
index 0000000..d767bc2
--- /dev/null
@@ -0,0 +1,149 @@
+From 9b47d4eea3f7c1f620e95bda1d6221660bde7d7b Mon Sep 17 00:00:00 2001
+From: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Date: Tue, 13 Jan 2026 20:15:15 +0100
+Subject: mm/kasan: fix KASAN poisoning in vrealloc()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+
+commit 9b47d4eea3f7c1f620e95bda1d6221660bde7d7b upstream.
+
+A KASAN warning can be triggered when vrealloc() changes the requested
+size to a value that is not aligned to KASAN_GRANULE_SIZE.
+
+    ------------[ cut here ]------------
+    WARNING: CPU: 2 PID: 1 at mm/kasan/shadow.c:174 kasan_unpoison+0x40/0x48
+    ...
+    pc : kasan_unpoison+0x40/0x48
+    lr : __kasan_unpoison_vmalloc+0x40/0x68
+    Call trace:
+     kasan_unpoison+0x40/0x48 (P)
+     vrealloc_node_align_noprof+0x200/0x320
+     bpf_patch_insn_data+0x90/0x2f0
+     convert_ctx_accesses+0x8c0/0x1158
+     bpf_check+0x1488/0x1900
+     bpf_prog_load+0xd20/0x1258
+     __sys_bpf+0x96c/0xdf0
+     __arm64_sys_bpf+0x50/0xa0
+     invoke_syscall+0x90/0x160
+
+Introduce a dedicated kasan_vrealloc() helper that centralizes KASAN
+handling for vmalloc reallocations.  The helper accounts for KASAN granule
+alignment when growing or shrinking an allocation and ensures that partial
+granules are handled correctly.
+
+Use this helper from vrealloc_node_align_noprof() to fix poisoning logic.
+
+[ryabinin.a.a@gmail.com: move kasan_enabled() check, fix build]
+  Link: https://lkml.kernel.org/r/20260119144509.32767-1-ryabinin.a.a@gmail.com
+Link: https://lkml.kernel.org/r/20260113191516.31015-1-ryabinin.a.a@gmail.com
+Fixes: d699440f58ce ("mm: fix vrealloc()'s KASAN poisoning logic")
+Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Reported-by: Maciej Å»enczykowski <maze@google.com>
+Reported-by: <joonki.min@samsung-slsi.corp-partner.google.com>
+Closes: https://lkml.kernel.org/r/CANP3RGeuRW53vukDy7WDO3FiVgu34-xVJYkfpm08oLO3odYFrA@mail.gmail.com
+Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
+Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Uladzislau Rezki <urezki@gmail.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/kasan.h |   14 ++++++++++++++
+ mm/kasan/common.c     |   21 +++++++++++++++++++++
+ mm/vmalloc.c          |    7 ++-----
+ 3 files changed, 37 insertions(+), 5 deletions(-)
+
+--- a/include/linux/kasan.h
++++ b/include/linux/kasan.h
+@@ -625,6 +625,17 @@ kasan_unpoison_vmap_areas(struct vm_stru
+               __kasan_unpoison_vmap_areas(vms, nr_vms, flags);
+ }
++void __kasan_vrealloc(const void *start, unsigned long old_size,
++              unsigned long new_size);
++
++static __always_inline void kasan_vrealloc(const void *start,
++                                      unsigned long old_size,
++                                      unsigned long new_size)
++{
++      if (kasan_enabled())
++              __kasan_vrealloc(start, old_size, new_size);
++}
++
+ #else /* CONFIG_KASAN_VMALLOC */
+ static inline void kasan_populate_early_vm_area_shadow(void *start,
+@@ -654,6 +665,9 @@ kasan_unpoison_vmap_areas(struct vm_stru
+                         kasan_vmalloc_flags_t flags)
+ { }
++static inline void kasan_vrealloc(const void *start, unsigned long old_size,
++                              unsigned long new_size) { }
++
+ #endif /* CONFIG_KASAN_VMALLOC */
+ #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
+--- a/mm/kasan/common.c
++++ b/mm/kasan/common.c
+@@ -613,4 +613,25 @@ void __kasan_unpoison_vmap_areas(struct
+                       __kasan_unpoison_vmalloc(addr, size, flags | KASAN_VMALLOC_KEEP_TAG);
+       }
+ }
++
++void __kasan_vrealloc(const void *addr, unsigned long old_size,
++              unsigned long new_size)
++{
++      if (new_size < old_size) {
++              kasan_poison_last_granule(addr, new_size);
++
++              new_size = round_up(new_size, KASAN_GRANULE_SIZE);
++              old_size = round_up(old_size, KASAN_GRANULE_SIZE);
++              if (new_size < old_size)
++                      __kasan_poison_vmalloc(addr + new_size,
++                                      old_size - new_size);
++      } else if (new_size > old_size) {
++              old_size = round_down(old_size, KASAN_GRANULE_SIZE);
++              __kasan_unpoison_vmalloc(addr + old_size,
++                                      new_size - old_size,
++                                      KASAN_VMALLOC_PROT_NORMAL |
++                                      KASAN_VMALLOC_VM_ALLOC |
++                                      KASAN_VMALLOC_KEEP_TAG);
++      }
++}
+ #endif
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -4167,7 +4167,7 @@ void *vrealloc_node_align_noprof(const v
+               if (want_init_on_free() || want_init_on_alloc(flags))
+                       memset((void *)p + size, 0, old_size - size);
+               vm->requested_size = size;
+-              kasan_poison_vmalloc(p + size, old_size - size);
++              kasan_vrealloc(p, old_size, size);
+               return (void *)p;
+       }
+@@ -4175,16 +4175,13 @@ void *vrealloc_node_align_noprof(const v
+        * We already have the bytes available in the allocation; use them.
+        */
+       if (size <= alloced_size) {
+-              kasan_unpoison_vmalloc(p + old_size, size - old_size,
+-                                     KASAN_VMALLOC_PROT_NORMAL |
+-                                     KASAN_VMALLOC_VM_ALLOC |
+-                                     KASAN_VMALLOC_KEEP_TAG);
+               /*
+                * No need to zero memory here, as unused memory will have
+                * already been zeroed at initial allocation time or during
+                * realloc shrink time.
+                */
+               vm->requested_size = size;
++              kasan_vrealloc(p, old_size, size);
+               return (void *)p;
+       }
diff --git a/queue-6.18/mm-kfence-randomize-the-freelist-on-initialization.patch b/queue-6.18/mm-kfence-randomize-the-freelist-on-initialization.patch
new file mode 100644 (file)
index 0000000..6481eac
--- /dev/null
@@ -0,0 +1,84 @@
+From 870ff19251bf3910dda7a7245da826924045fedd Mon Sep 17 00:00:00 2001
+From: Pimyn Girgis <pimyn@google.com>
+Date: Tue, 20 Jan 2026 17:15:10 +0100
+Subject: mm/kfence: randomize the freelist on initialization
+
+From: Pimyn Girgis <pimyn@google.com>
+
+commit 870ff19251bf3910dda7a7245da826924045fedd upstream.
+
+Randomize the KFENCE freelist during pool initialization to make
+allocation patterns less predictable.  This is achieved by shuffling the
+order in which metadata objects are added to the freelist using
+get_random_u32_below().
+
+Additionally, ensure the error path correctly calculates the address range
+to be reset if initialization fails, as the address increment logic has
+been moved to a separate loop.
+
+Link: https://lkml.kernel.org/r/20260120161510.3289089-1-pimyn@google.com
+Fixes: 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure")
+Signed-off-by: Pimyn Girgis <pimyn@google.com>
+Reviewed-by: Alexander Potapenko <glider@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Marco Elver <elver@google.com>
+Cc: Ernesto Martnez Garca <ernesto.martinezgarcia@tugraz.at>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Kees Cook <kees@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kfence/core.c |   23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+--- a/mm/kfence/core.c
++++ b/mm/kfence/core.c
+@@ -595,7 +595,7 @@ static void rcu_guarded_free(struct rcu_
+ static unsigned long kfence_init_pool(void)
+ {
+       unsigned long addr, start_pfn;
+-      int i;
++      int i, rand;
+       if (!arch_kfence_init_pool())
+               return (unsigned long)__kfence_pool;
+@@ -645,13 +645,27 @@ static unsigned long kfence_init_pool(vo
+               INIT_LIST_HEAD(&meta->list);
+               raw_spin_lock_init(&meta->lock);
+               meta->state = KFENCE_OBJECT_UNUSED;
+-              meta->addr = addr; /* Initialize for validation in metadata_to_pageaddr(). */
+-              list_add_tail(&meta->list, &kfence_freelist);
++              /* Use addr to randomize the freelist. */
++              meta->addr = i;
+               /* Protect the right redzone. */
+-              if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
++              if (unlikely(!kfence_protect(addr + 2 * i * PAGE_SIZE + PAGE_SIZE)))
+                       goto reset_slab;
++      }
++
++      for (i = CONFIG_KFENCE_NUM_OBJECTS; i > 0; i--) {
++              rand = get_random_u32_below(i);
++              swap(kfence_metadata_init[i - 1].addr, kfence_metadata_init[rand].addr);
++      }
++      for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
++              struct kfence_metadata *meta_1 = &kfence_metadata_init[i];
++              struct kfence_metadata *meta_2 = &kfence_metadata_init[meta_1->addr];
++
++              list_add_tail(&meta_2->list, &kfence_freelist);
++      }
++      for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
++              kfence_metadata_init[i].addr = addr;
+               addr += 2 * PAGE_SIZE;
+       }
+@@ -664,6 +678,7 @@ static unsigned long kfence_init_pool(vo
+       return 0;
+ reset_slab:
++      addr += 2 * i * PAGE_SIZE;
+       for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
+               struct slab *slab;
diff --git a/queue-6.18/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch b/queue-6.18/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
new file mode 100644 (file)
index 0000000..34c3638
--- /dev/null
@@ -0,0 +1,230 @@
+From a148a2040191b12b45b82cb29c281cb3036baf90 Mon Sep 17 00:00:00 2001
+From: Jane Chu <jane.chu@oracle.com>
+Date: Tue, 20 Jan 2026 16:22:33 -0700
+Subject: mm/memory-failure: fix missing ->mf_stats count in hugetlb poison
+
+From: Jane Chu <jane.chu@oracle.com>
+
+commit a148a2040191b12b45b82cb29c281cb3036baf90 upstream.
+
+When a newly poisoned subpage ends up in an already poisoned hugetlb
+folio, 'num_poisoned_pages' is incremented, but the per node ->mf_stats is
+not.  Fix the inconsistency by designating action_result() to update them
+both.
+
+While at it, define __get_huge_page_for_hwpoison() return values in terms
+of symbol names for better readibility.  Also rename
+folio_set_hugetlb_hwpoison() to hugetlb_update_hwpoison() since the
+function does more than the conventional bit setting and the fact three
+possible return values are expected.
+
+Link: https://lkml.kernel.org/r/20260120232234.3462258-1-jane.chu@oracle.com
+Fixes: 18f41fa616ee ("mm: memory-failure: bump memory failure stats to pglist_data")
+Signed-off-by: Jane Chu <jane.chu@oracle.com>
+Acked-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Chris Mason <clm@meta.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Jiaqi Yan <jiaqiyan@google.com>
+Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: William Roche <william.roche@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory-failure.c |   93 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 56 insertions(+), 37 deletions(-)
+
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1873,12 +1873,22 @@ static unsigned long __folio_free_raw_hw
+       return count;
+ }
+-static int folio_set_hugetlb_hwpoison(struct folio *folio, struct page *page)
++#define       MF_HUGETLB_FREED                0       /* freed hugepage */
++#define       MF_HUGETLB_IN_USED              1       /* in-use hugepage */
++#define       MF_HUGETLB_NON_HUGEPAGE         2       /* not a hugepage */
++#define       MF_HUGETLB_FOLIO_PRE_POISONED   3       /* folio already poisoned */
++#define       MF_HUGETLB_PAGE_PRE_POISONED    4       /* exact page already poisoned */
++#define       MF_HUGETLB_RETRY                5       /* hugepage is busy, retry */
++/*
++ * Set hugetlb folio as hwpoisoned, update folio private raw hwpoison list
++ * to keep track of the poisoned pages.
++ */
++static int hugetlb_update_hwpoison(struct folio *folio, struct page *page)
+ {
+       struct llist_head *head;
+       struct raw_hwp_page *raw_hwp;
+       struct raw_hwp_page *p;
+-      int ret = folio_test_set_hwpoison(folio) ? -EHWPOISON : 0;
++      int ret = folio_test_set_hwpoison(folio) ? MF_HUGETLB_FOLIO_PRE_POISONED : 0;
+       /*
+        * Once the hwpoison hugepage has lost reliable raw error info,
+@@ -1886,20 +1896,17 @@ static int folio_set_hugetlb_hwpoison(st
+        * so skip to add additional raw error info.
+        */
+       if (folio_test_hugetlb_raw_hwp_unreliable(folio))
+-              return -EHWPOISON;
++              return MF_HUGETLB_FOLIO_PRE_POISONED;
+       head = raw_hwp_list_head(folio);
+       llist_for_each_entry(p, head->first, node) {
+               if (p->page == page)
+-                      return -EHWPOISON;
++                      return MF_HUGETLB_PAGE_PRE_POISONED;
+       }
+       raw_hwp = kmalloc(sizeof(struct raw_hwp_page), GFP_ATOMIC);
+       if (raw_hwp) {
+               raw_hwp->page = page;
+               llist_add(&raw_hwp->node, head);
+-              /* the first error event will be counted in action_result(). */
+-              if (ret)
+-                      num_poisoned_pages_inc(page_to_pfn(page));
+       } else {
+               /*
+                * Failed to save raw error info.  We no longer trace all
+@@ -1947,42 +1954,39 @@ void folio_clear_hugetlb_hwpoison(struct
+ /*
+  * Called from hugetlb code with hugetlb_lock held.
+- *
+- * Return values:
+- *   0             - free hugepage
+- *   1             - in-use hugepage
+- *   2             - not a hugepage
+- *   -EBUSY        - the hugepage is busy (try to retry)
+- *   -EHWPOISON    - the hugepage is already hwpoisoned
+  */
+ int __get_huge_page_for_hwpoison(unsigned long pfn, int flags,
+                                bool *migratable_cleared)
+ {
+       struct page *page = pfn_to_page(pfn);
+       struct folio *folio = page_folio(page);
+-      int ret = 2;    /* fallback to normal page handling */
+       bool count_increased = false;
++      int ret, rc;
+-      if (!folio_test_hugetlb(folio))
++      if (!folio_test_hugetlb(folio)) {
++              ret = MF_HUGETLB_NON_HUGEPAGE;
+               goto out;
+-
+-      if (flags & MF_COUNT_INCREASED) {
+-              ret = 1;
++      } else if (flags & MF_COUNT_INCREASED) {
++              ret = MF_HUGETLB_IN_USED;
+               count_increased = true;
+       } else if (folio_test_hugetlb_freed(folio)) {
+-              ret = 0;
++              ret = MF_HUGETLB_FREED;
+       } else if (folio_test_hugetlb_migratable(folio)) {
+-              ret = folio_try_get(folio);
+-              if (ret)
++              if (folio_try_get(folio)) {
++                      ret = MF_HUGETLB_IN_USED;
+                       count_increased = true;
++              } else {
++                      ret = MF_HUGETLB_FREED;
++              }
+       } else {
+-              ret = -EBUSY;
++              ret = MF_HUGETLB_RETRY;
+               if (!(flags & MF_NO_RETRY))
+                       goto out;
+       }
+-      if (folio_set_hugetlb_hwpoison(folio, page)) {
+-              ret = -EHWPOISON;
++      rc = hugetlb_update_hwpoison(folio, page);
++      if (rc >= MF_HUGETLB_FOLIO_PRE_POISONED) {
++              ret = rc;
+               goto out;
+       }
+@@ -2007,10 +2011,16 @@ out:
+  * with basic operations like hugepage allocation/free/demotion.
+  * So some of prechecks for hwpoison (pinning, and testing/setting
+  * PageHWPoison) should be done in single hugetlb_lock range.
++ * Returns:
++ *    0               - not hugetlb, or recovered
++ *    -EBUSY          - not recovered
++ *    -EOPNOTSUPP     - hwpoison_filter'ed
++ *    -EHWPOISON      - folio or exact page already poisoned
++ *    -EFAULT         - kill_accessing_process finds current->mm null
+  */
+ static int try_memory_failure_hugetlb(unsigned long pfn, int flags, int *hugetlb)
+ {
+-      int res;
++      int res, rv;
+       struct page *p = pfn_to_page(pfn);
+       struct folio *folio;
+       unsigned long page_flags;
+@@ -2019,22 +2029,31 @@ static int try_memory_failure_hugetlb(un
+       *hugetlb = 1;
+ retry:
+       res = get_huge_page_for_hwpoison(pfn, flags, &migratable_cleared);
+-      if (res == 2) { /* fallback to normal page handling */
++      switch (res) {
++      case MF_HUGETLB_NON_HUGEPAGE:   /* fallback to normal page handling */
+               *hugetlb = 0;
+               return 0;
+-      } else if (res == -EHWPOISON) {
+-              if (flags & MF_ACTION_REQUIRED) {
+-                      folio = page_folio(p);
+-                      res = kill_accessing_process(current, folio_pfn(folio), flags);
+-              }
+-              action_result(pfn, MF_MSG_ALREADY_POISONED, MF_FAILED);
+-              return res;
+-      } else if (res == -EBUSY) {
++      case MF_HUGETLB_RETRY:
+               if (!(flags & MF_NO_RETRY)) {
+                       flags |= MF_NO_RETRY;
+                       goto retry;
+               }
+               return action_result(pfn, MF_MSG_GET_HWPOISON, MF_IGNORED);
++      case MF_HUGETLB_FOLIO_PRE_POISONED:
++      case MF_HUGETLB_PAGE_PRE_POISONED:
++              rv = -EHWPOISON;
++              if (flags & MF_ACTION_REQUIRED) {
++                      folio = page_folio(p);
++                      rv = kill_accessing_process(current, folio_pfn(folio), flags);
++              }
++              if (res == MF_HUGETLB_PAGE_PRE_POISONED)
++                      action_result(pfn, MF_MSG_ALREADY_POISONED, MF_FAILED);
++              else
++                      action_result(pfn, MF_MSG_HUGE, MF_FAILED);
++              return rv;
++      default:
++              WARN_ON((res != MF_HUGETLB_FREED) && (res != MF_HUGETLB_IN_USED));
++              break;
+       }
+       folio = page_folio(p);
+@@ -2045,7 +2064,7 @@ retry:
+               if (migratable_cleared)
+                       folio_set_hugetlb_migratable(folio);
+               folio_unlock(folio);
+-              if (res == 1)
++              if (res == MF_HUGETLB_IN_USED)
+                       folio_put(folio);
+               return -EOPNOTSUPP;
+       }
+@@ -2054,7 +2073,7 @@ retry:
+        * Handling free hugepage.  The possible race with hugepage allocation
+        * or demotion can be prevented by PageHWPoison flag.
+        */
+-      if (res == 0) {
++      if (res == MF_HUGETLB_FREED) {
+               folio_unlock(folio);
+               if (__page_handle_poison(p) > 0) {
+                       page_ref_inc(p);
diff --git a/queue-6.18/mm-memory-failure-teach-kill_accessing_process-to-accept-hugetlb-tail-page-pfn.patch b/queue-6.18/mm-memory-failure-teach-kill_accessing_process-to-accept-hugetlb-tail-page-pfn.patch
new file mode 100644 (file)
index 0000000..cd80c01
--- /dev/null
@@ -0,0 +1,86 @@
+From 057a6f2632c956483e2b2628477f0fcd1cd8a844 Mon Sep 17 00:00:00 2001
+From: Jane Chu <jane.chu@oracle.com>
+Date: Tue, 20 Jan 2026 16:22:34 -0700
+Subject: mm/memory-failure: teach kill_accessing_process to accept hugetlb tail page pfn
+
+From: Jane Chu <jane.chu@oracle.com>
+
+commit 057a6f2632c956483e2b2628477f0fcd1cd8a844 upstream.
+
+When a hugetlb folio is being poisoned again, try_memory_failure_hugetlb()
+passed head pfn to kill_accessing_process(), that is not right.  The
+precise pfn of the poisoned page should be used in order to determine the
+precise vaddr as the SIGBUS payload.
+
+This issue has already been taken care of in the normal path, that is,
+hwpoison_user_mappings(), see [1][2].  Further more, for [3] to work
+correctly in the hugetlb repoisoning case, it's essential to inform VM the
+precise poisoned page, not the head page.
+
+[1] https://lkml.kernel.org/r/20231218135837.3310403-1-willy@infradead.org
+[2] https://lkml.kernel.org/r/20250224211445.2663312-1-jane.chu@oracle.com
+[3] https://lore.kernel.org/lkml/20251116013223.1557158-1-jiaqiyan@google.com/
+
+Link: https://lkml.kernel.org/r/20260120232234.3462258-2-jane.chu@oracle.com
+Signed-off-by: Jane Chu <jane.chu@oracle.com>
+Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Acked-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Chris Mason <clm@meta.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Jiaqi Yan <jiaqiyan@google.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: William Roche <william.roche@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory-failure.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -684,6 +684,8 @@ static int check_hwpoisoned_entry(pte_t
+                               unsigned long poisoned_pfn, struct to_kill *tk)
+ {
+       unsigned long pfn = 0;
++      unsigned long hwpoison_vaddr;
++      unsigned long mask;
+       if (pte_present(pte)) {
+               pfn = pte_pfn(pte);
+@@ -694,10 +696,12 @@ static int check_hwpoisoned_entry(pte_t
+                       pfn = swp_offset_pfn(swp);
+       }
+-      if (!pfn || pfn != poisoned_pfn)
++      mask = ~((1UL << (shift - PAGE_SHIFT)) - 1);
++      if (!pfn || pfn != (poisoned_pfn & mask))
+               return 0;
+-      set_to_kill(tk, addr, shift);
++      hwpoison_vaddr = addr + ((poisoned_pfn - pfn) << PAGE_SHIFT);
++      set_to_kill(tk, hwpoison_vaddr, shift);
+       return 1;
+ }
+@@ -2042,10 +2046,8 @@ retry:
+       case MF_HUGETLB_FOLIO_PRE_POISONED:
+       case MF_HUGETLB_PAGE_PRE_POISONED:
+               rv = -EHWPOISON;
+-              if (flags & MF_ACTION_REQUIRED) {
+-                      folio = page_folio(p);
+-                      rv = kill_accessing_process(current, folio_pfn(folio), flags);
+-              }
++              if (flags & MF_ACTION_REQUIRED)
++                      rv = kill_accessing_process(current, pfn, flags);
+               if (res == MF_HUGETLB_PAGE_PRE_POISONED)
+                       action_result(pfn, MF_MSG_ALREADY_POISONED, MF_FAILED);
+               else
diff --git a/queue-6.18/mm-shmem-swap-fix-race-of-truncate-and-swap-entry-split.patch b/queue-6.18/mm-shmem-swap-fix-race-of-truncate-and-swap-entry-split.patch
new file mode 100644 (file)
index 0000000..ec0fb3a
--- /dev/null
@@ -0,0 +1,130 @@
+From 8a1968bd997f45a9b11aefeabdd1232e1b6c7184 Mon Sep 17 00:00:00 2001
+From: Kairui Song <kasong@tencent.com>
+Date: Tue, 20 Jan 2026 00:11:21 +0800
+Subject: mm/shmem, swap: fix race of truncate and swap entry split
+
+From: Kairui Song <kasong@tencent.com>
+
+commit 8a1968bd997f45a9b11aefeabdd1232e1b6c7184 upstream.
+
+The helper for shmem swap freeing is not handling the order of swap
+entries correctly.  It uses xa_cmpxchg_irq to erase the swap entry, but it
+gets the entry order before that using xa_get_order without lock
+protection, and it may get an outdated order value if the entry is split
+or changed in other ways after the xa_get_order and before the
+xa_cmpxchg_irq.
+
+And besides, the order could grow and be larger than expected, and cause
+truncation to erase data beyond the end border.  For example, if the
+target entry and following entries are swapped in or freed, then a large
+folio was added in place and swapped out, using the same entry, the
+xa_cmpxchg_irq will still succeed, it's very unlikely to happen though.
+
+To fix that, open code the Xarray cmpxchg and put the order retrieval and
+value checking in the same critical section.  Also, ensure the order won't
+exceed the end border, skip it if the entry goes across the border.
+
+Skipping large swap entries crosses the end border is safe here.  Shmem
+truncate iterates the range twice, in the first iteration,
+find_lock_entries already filtered such entries, and shmem will swapin the
+entries that cross the end border and partially truncate the folio (split
+the folio or at least zero part of it).  So in the second loop here, if we
+see a swap entry that crosses the end order, it must at least have its
+content erased already.
+
+I observed random swapoff hangs and kernel panics when stress testing
+ZSWAP with shmem.  After applying this patch, all problems are gone.
+
+Link: https://lkml.kernel.org/r/20260120-shmem-swap-fix-v3-1-3d33ebfbc057@tencent.com
+Fixes: 809bc86517cc ("mm: shmem: support large folio swap out")
+Signed-off-by: Kairui Song <kasong@tencent.com>
+Reviewed-by: Nhat Pham <nphamcs@gmail.com>
+Acked-by: Chris Li <chrisl@kernel.org>
+Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Kemeng Shi <shikemeng@huaweicloud.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/shmem.c |   45 ++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 34 insertions(+), 11 deletions(-)
+
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -944,17 +944,29 @@ static void shmem_delete_from_page_cache
+  * being freed).
+  */
+ static long shmem_free_swap(struct address_space *mapping,
+-                          pgoff_t index, void *radswap)
++                          pgoff_t index, pgoff_t end, void *radswap)
+ {
+-      int order = xa_get_order(&mapping->i_pages, index);
+-      void *old;
++      XA_STATE(xas, &mapping->i_pages, index);
++      unsigned int nr_pages = 0;
++      pgoff_t base;
++      void *entry;
++
++      xas_lock_irq(&xas);
++      entry = xas_load(&xas);
++      if (entry == radswap) {
++              nr_pages = 1 << xas_get_order(&xas);
++              base = round_down(xas.xa_index, nr_pages);
++              if (base < index || base + nr_pages - 1 > end)
++                      nr_pages = 0;
++              else
++                      xas_store(&xas, NULL);
++      }
++      xas_unlock_irq(&xas);
+-      old = xa_cmpxchg_irq(&mapping->i_pages, index, radswap, NULL, 0);
+-      if (old != radswap)
+-              return 0;
+-      free_swap_and_cache_nr(radix_to_swp_entry(radswap), 1 << order);
++      if (nr_pages)
++              free_swap_and_cache_nr(radix_to_swp_entry(radswap), nr_pages);
+-      return 1 << order;
++      return nr_pages;
+ }
+ /*
+@@ -1106,8 +1118,8 @@ static void shmem_undo_range(struct inod
+                       if (xa_is_value(folio)) {
+                               if (unfalloc)
+                                       continue;
+-                              nr_swaps_freed += shmem_free_swap(mapping,
+-                                                      indices[i], folio);
++                              nr_swaps_freed += shmem_free_swap(mapping, indices[i],
++                                                                end - 1, folio);
+                               continue;
+                       }
+@@ -1173,12 +1185,23 @@ whole_folios:
+                       folio = fbatch.folios[i];
+                       if (xa_is_value(folio)) {
++                              int order;
+                               long swaps_freed;
+                               if (unfalloc)
+                                       continue;
+-                              swaps_freed = shmem_free_swap(mapping, indices[i], folio);
++                              swaps_freed = shmem_free_swap(mapping, indices[i],
++                                                            end - 1, folio);
+                               if (!swaps_freed) {
++                                      /*
++                                       * If found a large swap entry cross the end border,
++                                       * skip it as the truncate_inode_partial_folio above
++                                       * should have at least zerod its content once.
++                                       */
++                                      order = shmem_confirm_swap(mapping, indices[i],
++                                                                 radix_to_swp_entry(folio));
++                                      if (order > 0 && indices[i] + (1 << order) > end)
++                                              continue;
+                                       /* Swap was replaced by page: retry */
+                                       index = indices[i];
+                                       break;
diff --git a/queue-6.18/mm-swap-restore-swap_space-attr-aviod-kernel-panic.patch b/queue-6.18/mm-swap-restore-swap_space-attr-aviod-kernel-panic.patch
new file mode 100644 (file)
index 0000000..455f9b6
--- /dev/null
@@ -0,0 +1,93 @@
+From a0f3c0845a4ff68d403c568266d17e9cc553e561 Mon Sep 17 00:00:00 2001
+From: "robin.kuo" <robin.kuo@mediatek.com>
+Date: Fri, 16 Jan 2026 14:25:00 +0800
+Subject: mm, swap: restore swap_space attr aviod kernel panic
+
+From: robin.kuo <robin.kuo@mediatek.com>
+
+commit a0f3c0845a4ff68d403c568266d17e9cc553e561 upstream.
+
+commit 8b47299a411a ("mm, swap: mark swap address space ro and add context
+debug check") made the swap address space read-only.  It may lead to
+kernel panic if arch_prepare_to_swap returns a failure under heavy memory
+pressure as follows,
+
+el1_abort+0x40/0x64
+el1h_64_sync_handler+0x48/0xcc
+el1h_64_sync+0x84/0x88
+errseq_set+0x4c/0xb8 (P)
+__filemap_set_wb_err+0x20/0xd0
+shrink_folio_list+0xc20/0x11cc
+evict_folios+0x1520/0x1be4
+try_to_shrink_lruvec+0x27c/0x3dc
+shrink_one+0x9c/0x228
+shrink_node+0xb3c/0xeac
+do_try_to_free_pages+0x170/0x4f0
+try_to_free_pages+0x334/0x534
+__alloc_pages_direct_reclaim+0x90/0x158
+__alloc_pages_slowpath+0x334/0x588
+__alloc_frozen_pages_noprof+0x224/0x2fc
+__folio_alloc_noprof+0x14/0x64
+vma_alloc_zeroed_movable_folio+0x34/0x44
+do_pte_missing+0xad4/0x1040
+handle_mm_fault+0x4a4/0x790
+do_page_fault+0x288/0x5f8
+do_translation_fault+0x38/0x54
+do_mem_abort+0x54/0xa8
+
+Restore swap address space as not ro to avoid the panic.
+
+Link: https://lkml.kernel.org/r/20260116062535.306453-2-robin.kuo@mediatek.com
+Fixes: 8b47299a411a ("mm, swap: mark swap address space ro and add context debug check")
+Signed-off-by: robin.kuo <robin.kuo@mediatek.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: andrew.yang <andrew.yang@mediatek.com>
+Cc: AngeloGiaocchino Del Regno <angelogioacchino.delregno@collabora.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Chinwen Chang <chinwen.chang@mediatek.com>
+Cc: Chris Li <chrisl@kernel.org>
+Cc: Kairui Song <kasong@tencent.com>
+Cc: Kairui Song <ryncsn@gmail.com>
+Cc: Kemeng Shi <shikemeng@huaweicloud.com>
+Cc: Mathias Brugger <matthias.bgg@gmail.com>
+Cc: Nhat Pham <nphamcs@gmail.com>
+Cc: Qun-wei Lin <Qun-wei.Lin@mediatek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/swap.h       | 2 +-
+ mm/swap_state.c | 3 +--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/mm/swap.h b/mm/swap.h
+index d034c13d8dd2..1bd466da3039 100644
+--- a/mm/swap.h
++++ b/mm/swap.h
+@@ -198,7 +198,7 @@ int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug);
+ void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug);
+ /* linux/mm/swap_state.c */
+-extern struct address_space swap_space __ro_after_init;
++extern struct address_space swap_space __read_mostly;
+ static inline struct address_space *swap_address_space(swp_entry_t entry)
+ {
+       return &swap_space;
+diff --git a/mm/swap_state.c b/mm/swap_state.c
+index 5f97c6ae70a2..44d228982521 100644
+--- a/mm/swap_state.c
++++ b/mm/swap_state.c
+@@ -37,8 +37,7 @@ static const struct address_space_operations swap_aops = {
+ #endif
+ };
+-/* Set swap_space as read only as swap cache is handled by swap table */
+-struct address_space swap_space __ro_after_init = {
++struct address_space swap_space __read_mostly = {
+       .a_ops = &swap_aops,
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.18/mptcp-only-reset-subflow-errors-when-propagated.patch b/queue-6.18/mptcp-only-reset-subflow-errors-when-propagated.patch
new file mode 100644 (file)
index 0000000..596a0e9
--- /dev/null
@@ -0,0 +1,57 @@
+From dccf46179ddd6c04c14be8ed584dc54665f53f0e Mon Sep 17 00:00:00 2001
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 27 Jan 2026 20:27:25 +0100
+Subject: mptcp: only reset subflow errors when propagated
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+commit dccf46179ddd6c04c14be8ed584dc54665f53f0e upstream.
+
+Some subflow socket errors need to be reported to the MPTCP socket: the
+initial subflow connect (MP_CAPABLE), and the ones from the fallback
+sockets. The others are not propagated.
+
+The issue is that sock_error() was used to retrieve the error, which was
+also resetting the sk_err field. Because of that, when notifying the
+userspace about subflow close events later on from the MPTCP worker, the
+ssk->sk_err field was always 0.
+
+Now, the error (sk_err) is only reset when propagating it to the msk.
+
+Fixes: 15cc10453398 ("mptcp: deliver ssk errors to msk")
+Cc: stable@vger.kernel.org
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-3-7f71e1bc4feb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -784,11 +784,8 @@ static bool __mptcp_ofo_queue(struct mpt
+ static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk)
+ {
+-      int err = sock_error(ssk);
+       int ssk_state;
+-
+-      if (!err)
+-              return false;
++      int err;
+       /* only propagate errors on fallen-back sockets or
+        * on MPC connect
+@@ -796,6 +793,10 @@ static bool __mptcp_subflow_error_report
+       if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk)))
+               return false;
++      err = sock_error(ssk);
++      if (!err)
++              return false;
++
+       /* We need to propagate only transition to CLOSE state.
+        * Orphaned socket will see such state change via
+        * subflow_sched_work_if_closed() and that path will properly
diff --git a/queue-6.18/net-fix-segmentation-of-forwarding-fraglist-gro.patch b/queue-6.18/net-fix-segmentation-of-forwarding-fraglist-gro.patch
new file mode 100644 (file)
index 0000000..fc8067b
--- /dev/null
@@ -0,0 +1,99 @@
+From 426ca15c7f6cb6562a081341ca88893a50c59fa2 Mon Sep 17 00:00:00 2001
+From: Jibin Zhang <jibin.zhang@mediatek.com>
+Date: Mon, 26 Jan 2026 23:21:11 +0800
+Subject: net: fix segmentation of forwarding fraglist GRO
+
+From: Jibin Zhang <jibin.zhang@mediatek.com>
+
+commit 426ca15c7f6cb6562a081341ca88893a50c59fa2 upstream.
+
+This patch enhances GSO segment handling by properly checking
+the SKB_GSO_DODGY flag for frag_list GSO packets, addressing
+low throughput issues observed when a station accesses IPv4
+servers via hotspots with an IPv6-only upstream interface.
+
+Specifically, it fixes a bug in GSO segmentation when forwarding
+GRO packets containing a frag_list. The function skb_segment_list
+cannot correctly process GRO skbs that have been converted by XLAT,
+since XLAT only translates the header of the head skb. Consequently,
+skbs in the frag_list may remain untranslated, resulting in protocol
+inconsistencies and reduced throughput.
+
+To address this, the patch explicitly sets the SKB_GSO_DODGY flag
+for GSO packets in XLAT's IPv4/IPv6 protocol translation helpers
+(bpf_skb_proto_4_to_6 and bpf_skb_proto_6_to_4). This marks GSO
+packets as potentially modified after protocol translation. As a
+result, GSO segmentation will avoid using skb_segment_list and
+instead falls back to skb_segment for packets with the SKB_GSO_DODGY
+flag. This ensures that only safe and fully translated frag_list
+packets are processed by skb_segment_list, resolving protocol
+inconsistencies and improving throughput when forwarding GRO packets
+converted by XLAT.
+
+Signed-off-by: Jibin Zhang <jibin.zhang@mediatek.com>
+Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260126152114.1211-1-jibin.zhang@mediatek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/filter.c        |    2 ++
+ net/ipv4/tcp_offload.c   |    3 ++-
+ net/ipv4/udp_offload.c   |    3 ++-
+ net/ipv6/tcpv6_offload.c |    3 ++-
+ 4 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3352,6 +3352,7 @@ static int bpf_skb_proto_4_to_6(struct s
+                       shinfo->gso_type &= ~SKB_GSO_TCPV4;
+                       shinfo->gso_type |=  SKB_GSO_TCPV6;
+               }
++              shinfo->gso_type |=  SKB_GSO_DODGY;
+       }
+       bpf_skb_change_protocol(skb, ETH_P_IPV6);
+@@ -3382,6 +3383,7 @@ static int bpf_skb_proto_6_to_4(struct s
+                       shinfo->gso_type &= ~SKB_GSO_TCPV6;
+                       shinfo->gso_type |=  SKB_GSO_TCPV4;
+               }
++              shinfo->gso_type |=  SKB_GSO_DODGY;
+       }
+       bpf_skb_change_protocol(skb, ETH_P_IP);
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -107,7 +107,8 @@ static struct sk_buff *tcp4_gso_segment(
+       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+               struct tcphdr *th = tcp_hdr(skb);
+-              if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
++              if ((skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size) &&
++                  !(skb_shinfo(skb)->gso_type & SKB_GSO_DODGY))
+                       return __tcp4_gso_segment_list(skb, features);
+               skb->ip_summed = CHECKSUM_NONE;
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -514,7 +514,8 @@ struct sk_buff *__udp_gso_segment(struct
+       if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) {
+                /* Detect modified geometry and pass those to skb_segment. */
+-              if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
++              if ((skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size) &&
++                  !(skb_shinfo(gso_skb)->gso_type & SKB_GSO_DODGY))
+                       return __udp_gso_segment_list(gso_skb, features, is_ipv6);
+               ret = __skb_linearize(gso_skb);
+--- a/net/ipv6/tcpv6_offload.c
++++ b/net/ipv6/tcpv6_offload.c
+@@ -170,7 +170,8 @@ static struct sk_buff *tcp6_gso_segment(
+       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+               struct tcphdr *th = tcp_hdr(skb);
+-              if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
++              if ((skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size) &&
++                  !(skb_shinfo(skb)->gso_type & SKB_GSO_DODGY))
+                       return __tcp6_gso_segment_list(skb, features);
+               skb->ip_summed = CHECKSUM_NONE;
diff --git a/queue-6.18/nvmet-fix-race-in-nvmet_bio_done-leading-to-null-pointer-dereference.patch b/queue-6.18/nvmet-fix-race-in-nvmet_bio_done-leading-to-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..f76871c
--- /dev/null
@@ -0,0 +1,61 @@
+From 0fcee2cfc4b2e16e62ff8e0cc2cd8dd24efad65e Mon Sep 17 00:00:00 2001
+From: Ming Lei <ming.lei@redhat.com>
+Date: Wed, 21 Jan 2026 17:38:54 +0800
+Subject: nvmet: fix race in nvmet_bio_done() leading to NULL pointer dereference
+
+From: Ming Lei <ming.lei@redhat.com>
+
+commit 0fcee2cfc4b2e16e62ff8e0cc2cd8dd24efad65e upstream.
+
+There is a race condition in nvmet_bio_done() that can cause a NULL
+pointer dereference in blk_cgroup_bio_start():
+
+1. nvmet_bio_done() is called when a bio completes
+2. nvmet_req_complete() is called, which invokes req->ops->queue_response(req)
+3. The queue_response callback can re-queue and re-submit the same request
+4. The re-submission reuses the same inline_bio from nvmet_req
+5. Meanwhile, nvmet_req_bio_put() (called after nvmet_req_complete)
+   invokes bio_uninit() for inline_bio, which sets bio->bi_blkg to NULL
+6. The re-submitted bio enters submit_bio_noacct_nocheck()
+7. blk_cgroup_bio_start() dereferences bio->bi_blkg, causing a crash:
+
+  BUG: kernel NULL pointer dereference, address: 0000000000000028
+  #PF: supervisor read access in kernel mode
+  RIP: 0010:blk_cgroup_bio_start+0x10/0xd0
+  Call Trace:
+   submit_bio_noacct_nocheck+0x44/0x250
+   nvmet_bdev_execute_rw+0x254/0x370 [nvmet]
+   process_one_work+0x193/0x3c0
+   worker_thread+0x281/0x3a0
+
+Fix this by reordering nvmet_bio_done() to call nvmet_req_bio_put()
+BEFORE nvmet_req_complete(). This ensures the bio is cleaned up before
+the request can be re-submitted, preventing the race condition.
+
+Fixes: 190f4c2c863a ("nvmet: fix memory leak of bio integrity")
+Cc: Dmitry Bogdanov <d.bogdanov@yadro.com>
+Cc: stable@vger.kernel.org
+Cc: Guangwu Zhang <guazhang@redhat.com>
+Link: http://www.mail-archive.com/debian-kernel@lists.debian.org/msg146238.html
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/target/io-cmd-bdev.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvme/target/io-cmd-bdev.c
++++ b/drivers/nvme/target/io-cmd-bdev.c
+@@ -180,9 +180,10 @@ u16 blk_to_nvme_status(struct nvmet_req
+ static void nvmet_bio_done(struct bio *bio)
+ {
+       struct nvmet_req *req = bio->bi_private;
++      blk_status_t blk_status = bio->bi_status;
+-      nvmet_req_complete(req, blk_to_nvme_status(req, bio->bi_status));
+       nvmet_req_bio_put(req, bio);
++      nvmet_req_complete(req, blk_to_nvme_status(req, blk_status));
+ }
+ #ifdef CONFIG_BLK_DEV_INTEGRITY
diff --git a/queue-6.18/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch b/queue-6.18/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch
new file mode 100644 (file)
index 0000000..080fe74
--- /dev/null
@@ -0,0 +1,111 @@
+From 76ed27608f7dd235b727ebbb12163438c2fbb617 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Thu, 29 Jan 2026 10:28:21 -0500
+Subject: perf: sched: Fix perf crash with new is_user_task() helper
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit 76ed27608f7dd235b727ebbb12163438c2fbb617 upstream.
+
+In order to do a user space stacktrace the current task needs to be a user
+task that has executed in user space. It use to be possible to test if a
+task is a user task or not by simply checking the task_struct mm field. If
+it was non NULL, it was a user task and if not it was a kernel task.
+
+But things have changed over time, and some kernel tasks now have their
+own mm field.
+
+An idea was made to instead test PF_KTHREAD and two functions were used to
+wrap this check in case it became more complex to test if a task was a
+user task or not[1]. But this was rejected and the C code simply checked
+the PF_KTHREAD directly.
+
+It was later found that not all kernel threads set PF_KTHREAD. The io-uring
+helpers instead set PF_USER_WORKER and this needed to be added as well.
+
+But checking the flags is still not enough. There's a very small window
+when a task exits that it frees its mm field and it is set back to NULL.
+If perf were to trigger at this moment, the flags test would say its a
+user space task but when perf would read the mm field it would crash with
+at NULL pointer dereference.
+
+Now there are flags that can be used to test if a task is exiting, but
+they are set in areas that perf may still want to profile the user space
+task (to see where it exited). The only real test is to check both the
+flags and the mm field.
+
+Instead of making this modification in every location, create a new
+is_user_task() helper function that does all the tests needed to know if
+it is safe to read the user space memory or not.
+
+[1] https://lore.kernel.org/all/20250425204120.639530125@goodmis.org/
+
+Fixes: 90942f9fac05 ("perf: Use current->flags & PF_KTHREAD|PF_USER_WORKER instead of current->mm == NULL")
+Closes: https://lore.kernel.org/all/0d877e6f-41a7-4724-875d-0b0a27b8a545@roeck-us.net/
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260129102821.46484722@gandalf.local.home
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/sched.h     |    5 +++++
+ kernel/events/callchain.c |    2 +-
+ kernel/events/core.c      |    6 +++---
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1798,6 +1798,11 @@ static __always_inline bool is_percpu_th
+               (current->nr_cpus_allowed  == 1);
+ }
++static __always_inline bool is_user_task(struct task_struct *task)
++{
++      return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER));
++}
++
+ /* Per-process atomic flags. */
+ #define PFA_NO_NEW_PRIVS              0       /* May not gain new privileges. */
+ #define PFA_SPREAD_PAGE                       1       /* Spread page cache over cpuset */
+--- a/kernel/events/callchain.c
++++ b/kernel/events/callchain.c
+@@ -246,7 +246,7 @@ get_perf_callchain(struct pt_regs *regs,
+       if (user && !crosstask) {
+               if (!user_mode(regs)) {
+-                      if (current->flags & (PF_KTHREAD | PF_USER_WORKER))
++                      if (!is_user_task(current))
+                               goto exit_put;
+                       regs = task_pt_regs(current);
+               }
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -7459,7 +7459,7 @@ static void perf_sample_regs_user(struct
+       if (user_mode(regs)) {
+               regs_user->abi = perf_reg_abi(current);
+               regs_user->regs = regs;
+-      } else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
++      } else if (is_user_task(current)) {
+               perf_get_regs_user(regs_user, regs);
+       } else {
+               regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
+@@ -8099,7 +8099,7 @@ static u64 perf_virt_to_phys(u64 virt)
+                * Try IRQ-safe get_user_page_fast_only first.
+                * If failed, leave phys_addr as 0.
+                */
+-              if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
++              if (is_user_task(current)) {
+                       struct page *p;
+                       pagefault_disable();
+@@ -8212,7 +8212,7 @@ perf_callchain(struct perf_event *event,
+ {
+       bool kernel = !event->attr.exclude_callchain_kernel;
+       bool user   = !event->attr.exclude_callchain_user &&
+-              !(current->flags & (PF_KTHREAD | PF_USER_WORKER));
++              is_user_task(current);
+       /* Disallow cross-task user callchains. */
+       bool crosstask = event->ctx->task && event->ctx->task != current;
+       const u32 max_stack = event->attr.sample_max_stack;
diff --git a/queue-6.18/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch b/queue-6.18/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch
new file mode 100644 (file)
index 0000000..4aab603
--- /dev/null
@@ -0,0 +1,59 @@
+From 4f0d22ec60cee420125f4055af76caa0f373a3fe Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Date: Mon, 26 Jan 2026 14:56:27 +0100
+Subject: pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+commit 4f0d22ec60cee420125f4055af76caa0f373a3fe upstream.
+
+GPIO controller driver should typically implement the .get_direction()
+callback as GPIOLIB internals may try to use it to determine the state
+of a pin. Add it for the LPASS LPI driver.
+
+Reported-by: Abel Vesa <abelvesa@kernel.org>
+Cc: stable@vger.kernel.org
+Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver")
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # X1E CRD
+Tested-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/qcom/pinctrl-lpass-lpi.c |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+@@ -312,6 +312,22 @@ static const struct pinconf_ops lpi_gpio
+       .pin_config_group_set           = lpi_config_set,
+ };
++static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++      unsigned long config = pinconf_to_config_packed(PIN_CONFIG_LEVEL, 0);
++      struct lpi_pinctrl *state = gpiochip_get_data(chip);
++      unsigned long arg;
++      int ret;
++
++      ret = lpi_config_get(state->ctrl, pin, &config);
++      if (ret)
++              return ret;
++
++      arg = pinconf_to_config_argument(config);
++
++      return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
++}
++
+ static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)
+ {
+       struct lpi_pinctrl *state = gpiochip_get_data(chip);
+@@ -409,6 +425,7 @@ static void lpi_gpio_dbg_show(struct seq
+ #endif
+ static const struct gpio_chip lpi_gpio_template = {
++      .get_direction          = lpi_gpio_get_direction,
+       .direction_input        = lpi_gpio_direction_input,
+       .direction_output       = lpi_gpio_direction_output,
+       .get                    = lpi_gpio_get,
diff --git a/queue-6.18/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch b/queue-6.18/pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch
new file mode 100644 (file)
index 0000000..088750d
--- /dev/null
@@ -0,0 +1,90 @@
+From 28f24068387169722b508bba6b5257cb68b86e74 Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Date: Mon, 5 Jan 2026 16:05:08 +0100
+Subject: pinctrl: meson: mark the GPIO controller as sleeping
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+commit 28f24068387169722b508bba6b5257cb68b86e74 upstream.
+
+The GPIO controller is configured as non-sleeping but it uses generic
+pinctrl helpers which use a mutex for synchronization.
+
+This can cause the following lockdep splat with shared GPIOs enabled on
+boards which have multiple devices using the same GPIO:
+
+BUG: sleeping function called from invalid context at
+kernel/locking/mutex.c:591
+in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 142, name:
+kworker/u25:3
+preempt_count: 1, expected: 0
+RCU nest depth: 0, expected: 0
+INFO: lockdep is turned off.
+irq event stamp: 46379
+hardirqs last  enabled at (46379): [<ffff8000813acb24>]
+_raw_spin_unlock_irqrestore+0x74/0x78
+hardirqs last disabled at (46378): [<ffff8000813abf38>]
+_raw_spin_lock_irqsave+0x84/0x88
+softirqs last  enabled at (46330): [<ffff8000800c71b4>]
+handle_softirqs+0x4c4/0x4dc
+softirqs last disabled at (46295): [<ffff800080010674>]
+__do_softirq+0x14/0x20
+CPU: 1 UID: 0 PID: 142 Comm: kworker/u25:3 Tainted: G C
+6.19.0-rc4-next-20260105+ #11963 PREEMPT
+Tainted: [C]=CRAP
+Hardware name: Khadas VIM3 (DT)
+Workqueue: events_unbound deferred_probe_work_func
+Call trace:
+  show_stack+0x18/0x24 (C)
+  dump_stack_lvl+0x90/0xd0
+  dump_stack+0x18/0x24
+  __might_resched+0x144/0x248
+  __might_sleep+0x48/0x98
+  __mutex_lock+0x5c/0x894
+  mutex_lock_nested+0x24/0x30
+  pinctrl_get_device_gpio_range+0x44/0x128
+  pinctrl_gpio_set_config+0x40/0xdc
+  gpiochip_generic_config+0x28/0x3c
+  gpio_do_set_config+0xa8/0x194
+  gpiod_set_config+0x34/0xfc
+  gpio_shared_proxy_set_config+0x6c/0xfc [gpio_shared_proxy]
+  gpio_do_set_config+0xa8/0x194
+  gpiod_set_transitory+0x4c/0xf0
+  gpiod_configure_flags+0xa4/0x480
+  gpiod_find_and_request+0x1a0/0x574
+  gpiod_get_index+0x58/0x84
+  devm_gpiod_get_index+0x20/0xb4
+  devm_gpiod_get+0x18/0x24
+  mmc_pwrseq_emmc_probe+0x40/0xb8
+  platform_probe+0x5c/0xac
+  really_probe+0xbc/0x298
+  __driver_probe_device+0x78/0x12c
+  driver_probe_device+0xdc/0x164
+  __device_attach_driver+0xb8/0x138
+  bus_for_each_drv+0x80/0xdc
+  __device_attach+0xa8/0x1b0
+
+Fixes: 6ac730951104 ("pinctrl: add driver for Amlogic Meson SoCs")
+Cc: stable@vger.kernel.org
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Closes: https://lore.kernel.org/all/00107523-7737-4b92-a785-14ce4e93b8cb@samsung.com/
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pinctrl/meson/pinctrl-meson.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pinctrl/meson/pinctrl-meson.c
++++ b/drivers/pinctrl/meson/pinctrl-meson.c
+@@ -619,7 +619,7 @@ static int meson_gpiolib_register(struct
+       pc->chip.set = meson_gpio_set;
+       pc->chip.base = -1;
+       pc->chip.ngpio = pc->data->num_pins;
+-      pc->chip.can_sleep = false;
++      pc->chip.can_sleep = true;
+       ret = gpiochip_add_data(&pc->chip, pc);
+       if (ret) {
diff --git a/queue-6.18/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch b/queue-6.18/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch
new file mode 100644 (file)
index 0000000..a793995
--- /dev/null
@@ -0,0 +1,260 @@
+From 1fbe3abb449c5ef2178e1c3e3e8b9a43a7a410ac Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Date: Thu, 8 Jan 2026 11:07:22 +0100
+Subject: pinctrl: qcom: sm8350-lpass-lpi: Merge with SC7280 to fix I2S2 and SWR TX pins
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+
+commit 1fbe3abb449c5ef2178e1c3e3e8b9a43a7a410ac upstream.
+
+Qualcomm SC7280 and SM8350 SoCs have slightly different LPASS audio
+blocks (v9.4.5 and v9.2), however the LPASS LPI pin controllers are
+exactly the same.  The driver for SM8350 has two issues, which can be
+fixed by simply moving over to SC7280 driver which has them correct:
+
+1. "i2s2_data_groups" listed twice GPIO12, but should have both GPIO12
+   and GPIO13,
+
+2. "swr_tx_data_groups" contained GPIO5 for "swr_tx_data2" function, but
+   that function is also available on GPIO14, thus listing it twice is
+   not necessary.  OTOH, GPIO5 has also "swr_rx_data1", so selecting
+   swr_rx_data function should not block  the TX one.
+
+Fixes: be9f6d56381d ("pinctrl: qcom: sm8350-lpass-lpi: add SM8350 LPASS TLMM")
+Cc: stable@vger.kernel.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/configs/defconfig                    |    1 
+ drivers/pinctrl/qcom/Kconfig                    |   15 --
+ drivers/pinctrl/qcom/Makefile                   |    1 
+ drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c |    3 
+ drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c |  151 ------------------------
+ 5 files changed, 6 insertions(+), 165 deletions(-)
+ delete mode 100644 drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c
+
+--- a/arch/arm64/configs/defconfig
++++ b/arch/arm64/configs/defconfig
+@@ -662,7 +662,6 @@ CONFIG_PINCTRL_LPASS_LPI=m
+ CONFIG_PINCTRL_SC7280_LPASS_LPI=m
+ CONFIG_PINCTRL_SM6115_LPASS_LPI=m
+ CONFIG_PINCTRL_SM8250_LPASS_LPI=m
+-CONFIG_PINCTRL_SM8350_LPASS_LPI=m
+ CONFIG_PINCTRL_SM8450_LPASS_LPI=m
+ CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
+ CONFIG_PINCTRL_SM8550_LPASS_LPI=m
+--- a/drivers/pinctrl/qcom/Kconfig
++++ b/drivers/pinctrl/qcom/Kconfig
+@@ -61,13 +61,14 @@ config PINCTRL_LPASS_LPI
+         (Low Power Island) found on the Qualcomm Technologies Inc SoCs.
+ config PINCTRL_SC7280_LPASS_LPI
+-      tristate "Qualcomm Technologies Inc SC7280 LPASS LPI pin controller driver"
++      tristate "Qualcomm Technologies Inc SC7280 and SM8350 LPASS LPI pin controller driver"
+       depends on ARM64 || COMPILE_TEST
+       depends on PINCTRL_LPASS_LPI
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+         Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
+-        (Low Power Island) found on the Qualcomm Technologies Inc SC7280 platform.
++        (Low Power Island) found on the Qualcomm Technologies Inc SC7280
++        and SM8350 platforms.
+ config PINCTRL_SDM660_LPASS_LPI
+       tristate "Qualcomm Technologies Inc SDM660 LPASS LPI pin controller driver"
+@@ -106,16 +107,6 @@ config PINCTRL_SM8250_LPASS_LPI
+         Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
+         (Low Power Island) found on the Qualcomm Technologies Inc SM8250 platform.
+-config PINCTRL_SM8350_LPASS_LPI
+-      tristate "Qualcomm Technologies Inc SM8350 LPASS LPI pin controller driver"
+-      depends on ARM64 || COMPILE_TEST
+-      depends on PINCTRL_LPASS_LPI
+-      help
+-        This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+-        Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
+-        (Low Power Island) found on the Qualcomm Technologies Inc SM8350
+-        platform.
+-
+ config PINCTRL_SM8450_LPASS_LPI
+       tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver"
+       depends on ARM64 || COMPILE_TEST
+--- a/drivers/pinctrl/qcom/Makefile
++++ b/drivers/pinctrl/qcom/Makefile
+@@ -63,7 +63,6 @@ obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-
+ obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o
+ obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o
+ obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o
+-obj-$(CONFIG_PINCTRL_SM8350_LPASS_LPI) += pinctrl-sm8350-lpass-lpi.o
+ obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o
+ obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o
+ obj-$(CONFIG_PINCTRL_SM8550) += pinctrl-sm8550.o
+--- a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c
++++ b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c
+@@ -131,6 +131,9 @@ static const struct of_device_id lpi_pin
+       {
+              .compatible = "qcom,sc7280-lpass-lpi-pinctrl",
+              .data = &sc7280_lpi_data,
++      }, {
++             .compatible = "qcom,sm8350-lpass-lpi-pinctrl",
++             .data = &sc7280_lpi_data,
+       },
+       { }
+ };
+--- a/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c
++++ /dev/null
+@@ -1,151 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
+-/*
+- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+- * Copyright (c) 2020-2023 Linaro Ltd.
+- */
+-
+-#include <linux/gpio/driver.h>
+-#include <linux/module.h>
+-#include <linux/platform_device.h>
+-
+-#include "pinctrl-lpass-lpi.h"
+-
+-enum lpass_lpi_functions {
+-      LPI_MUX_dmic1_clk,
+-      LPI_MUX_dmic1_data,
+-      LPI_MUX_dmic2_clk,
+-      LPI_MUX_dmic2_data,
+-      LPI_MUX_dmic3_clk,
+-      LPI_MUX_dmic3_data,
+-      LPI_MUX_i2s1_clk,
+-      LPI_MUX_i2s1_data,
+-      LPI_MUX_i2s1_ws,
+-      LPI_MUX_i2s2_clk,
+-      LPI_MUX_i2s2_data,
+-      LPI_MUX_i2s2_ws,
+-      LPI_MUX_qua_mi2s_data,
+-      LPI_MUX_qua_mi2s_sclk,
+-      LPI_MUX_qua_mi2s_ws,
+-      LPI_MUX_swr_rx_clk,
+-      LPI_MUX_swr_rx_data,
+-      LPI_MUX_swr_tx_clk,
+-      LPI_MUX_swr_tx_data,
+-      LPI_MUX_wsa_swr_clk,
+-      LPI_MUX_wsa_swr_data,
+-      LPI_MUX_gpio,
+-      LPI_MUX__,
+-};
+-
+-static const struct pinctrl_pin_desc sm8350_lpi_pins[] = {
+-      PINCTRL_PIN(0, "gpio0"),
+-      PINCTRL_PIN(1, "gpio1"),
+-      PINCTRL_PIN(2, "gpio2"),
+-      PINCTRL_PIN(3, "gpio3"),
+-      PINCTRL_PIN(4, "gpio4"),
+-      PINCTRL_PIN(5, "gpio5"),
+-      PINCTRL_PIN(6, "gpio6"),
+-      PINCTRL_PIN(7, "gpio7"),
+-      PINCTRL_PIN(8, "gpio8"),
+-      PINCTRL_PIN(9, "gpio9"),
+-      PINCTRL_PIN(10, "gpio10"),
+-      PINCTRL_PIN(11, "gpio11"),
+-      PINCTRL_PIN(12, "gpio12"),
+-      PINCTRL_PIN(13, "gpio13"),
+-      PINCTRL_PIN(14, "gpio14"),
+-};
+-
+-static const char * const swr_tx_clk_groups[] = { "gpio0" };
+-static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio5", "gpio14" };
+-static const char * const swr_rx_clk_groups[] = { "gpio3" };
+-static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" };
+-static const char * const dmic1_clk_groups[] = { "gpio6" };
+-static const char * const dmic1_data_groups[] = { "gpio7" };
+-static const char * const dmic2_clk_groups[] = { "gpio8" };
+-static const char * const dmic2_data_groups[] = { "gpio9" };
+-static const char * const i2s2_clk_groups[] = { "gpio10" };
+-static const char * const i2s2_ws_groups[] = { "gpio11" };
+-static const char * const dmic3_clk_groups[] = { "gpio12" };
+-static const char * const dmic3_data_groups[] = { "gpio13" };
+-static const char * const qua_mi2s_sclk_groups[] = { "gpio0" };
+-static const char * const qua_mi2s_ws_groups[] = { "gpio1" };
+-static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4" };
+-static const char * const i2s1_clk_groups[] = { "gpio6" };
+-static const char * const i2s1_ws_groups[] = { "gpio7" };
+-static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" };
+-static const char * const wsa_swr_clk_groups[] = { "gpio10" };
+-static const char * const wsa_swr_data_groups[] = { "gpio11" };
+-static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" };
+-
+-static const struct lpi_pingroup sm8350_groups[] = {
+-      LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _),
+-      LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _),
+-      LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _),
+-      LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _),
+-      LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _),
+-      LPI_PINGROUP(5, 12, swr_tx_data, swr_rx_data, _, _),
+-      LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _,  _),
+-      LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _),
+-      LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _),
+-      LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, _, _),
+-      LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _),
+-      LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _),
+-      LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _),
+-      LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, _, _),
+-      LPI_PINGROUP(14, 6, swr_tx_data, _, _, _),
+-};
+-
+-static const struct lpi_function sm8350_functions[] = {
+-      LPI_FUNCTION(dmic1_clk),
+-      LPI_FUNCTION(dmic1_data),
+-      LPI_FUNCTION(dmic2_clk),
+-      LPI_FUNCTION(dmic2_data),
+-      LPI_FUNCTION(dmic3_clk),
+-      LPI_FUNCTION(dmic3_data),
+-      LPI_FUNCTION(i2s1_clk),
+-      LPI_FUNCTION(i2s1_data),
+-      LPI_FUNCTION(i2s1_ws),
+-      LPI_FUNCTION(i2s2_clk),
+-      LPI_FUNCTION(i2s2_data),
+-      LPI_FUNCTION(i2s2_ws),
+-      LPI_FUNCTION(qua_mi2s_data),
+-      LPI_FUNCTION(qua_mi2s_sclk),
+-      LPI_FUNCTION(qua_mi2s_ws),
+-      LPI_FUNCTION(swr_rx_clk),
+-      LPI_FUNCTION(swr_rx_data),
+-      LPI_FUNCTION(swr_tx_clk),
+-      LPI_FUNCTION(swr_tx_data),
+-      LPI_FUNCTION(wsa_swr_clk),
+-      LPI_FUNCTION(wsa_swr_data),
+-};
+-
+-static const struct lpi_pinctrl_variant_data sm8350_lpi_data = {
+-      .pins = sm8350_lpi_pins,
+-      .npins = ARRAY_SIZE(sm8350_lpi_pins),
+-      .groups = sm8350_groups,
+-      .ngroups = ARRAY_SIZE(sm8350_groups),
+-      .functions = sm8350_functions,
+-      .nfunctions = ARRAY_SIZE(sm8350_functions),
+-};
+-
+-static const struct of_device_id lpi_pinctrl_of_match[] = {
+-      {
+-             .compatible = "qcom,sm8350-lpass-lpi-pinctrl",
+-             .data = &sm8350_lpi_data,
+-      },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);
+-
+-static struct platform_driver lpi_pinctrl_driver = {
+-      .driver = {
+-                 .name = "qcom-sm8350-lpass-lpi-pinctrl",
+-                 .of_match_table = lpi_pinctrl_of_match,
+-      },
+-      .probe = lpi_pinctrl_probe,
+-      .remove = lpi_pinctrl_remove,
+-};
+-module_platform_driver(lpi_pinctrl_driver);
+-
+-MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
+-MODULE_DESCRIPTION("QTI SM8350 LPI GPIO pin control driver");
+-MODULE_LICENSE("GPL");
diff --git a/queue-6.18/riscv-compat-fix-compat_uts_machine-definition.patch b/queue-6.18/riscv-compat-fix-compat_uts_machine-definition.patch
new file mode 100644 (file)
index 0000000..17d03e3
--- /dev/null
@@ -0,0 +1,34 @@
+From 0ea05c4f7527a98f5946f96c829733788934311d Mon Sep 17 00:00:00 2001
+From: Han Gao <gaohan@iscas.ac.cn>
+Date: Wed, 28 Jan 2026 03:07:11 +0800
+Subject: riscv: compat: fix COMPAT_UTS_MACHINE definition
+
+From: Han Gao <gaohan@iscas.ac.cn>
+
+commit 0ea05c4f7527a98f5946f96c829733788934311d upstream.
+
+The COMPAT_UTS_MACHINE for riscv was incorrectly defined as "riscv".
+Change it to "riscv32" to reflect the correct 32-bit compat name.
+
+Fixes: 06d0e3723647 ("riscv: compat: Add basic compat data type implementation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
+Reviewed-by: Guo Ren (Alibaba Damo Academy) <guoren@kernel.org>
+Link: https://patch.msgid.link/20260127190711.2264664-1-gaohan@iscas.ac.cn
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/include/asm/compat.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/riscv/include/asm/compat.h
++++ b/arch/riscv/include/asm/compat.h
+@@ -2,7 +2,7 @@
+ #ifndef __ASM_COMPAT_H
+ #define __ASM_COMPAT_H
+-#define COMPAT_UTS_MACHINE    "riscv\0\0"
++#define COMPAT_UTS_MACHINE    "riscv32\0\0"
+ /*
+  * Architecture specific compatibility types
diff --git a/queue-6.18/rust-kbuild-give-config-path-to-rustfmt-in-.rsi-target.patch b/queue-6.18/rust-kbuild-give-config-path-to-rustfmt-in-.rsi-target.patch
new file mode 100644 (file)
index 0000000..d1f0c4b
--- /dev/null
@@ -0,0 +1,66 @@
+From af20ae33e7dd949f2e770198e74ac8f058cb299d Mon Sep 17 00:00:00 2001
+From: Miguel Ojeda <ojeda@kernel.org>
+Date: Thu, 15 Jan 2026 19:38:32 +0100
+Subject: rust: kbuild: give `--config-path` to `rustfmt` in `.rsi` target
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+commit af20ae33e7dd949f2e770198e74ac8f058cb299d upstream.
+
+`rustfmt` is configured via the `.rustfmt.toml` file in the source tree,
+and we apply `rustfmt` to the macro expanded sources generated by the
+`.rsi` target.
+
+However, under an `O=` pointing to an external folder (i.e. not just
+a subdir), `rustfmt` will not find the file when checking the parent
+folders. Since the edition is configured in this file, this can lead to
+errors when it encounters newer syntax, e.g.
+
+    error: expected one of `!`, `.`, `::`, `;`, `?`, `where`, `{`, or an operator, found `"rust_minimal"`
+      --> samples/rust/rust_minimal.rsi:29:49
+       |
+    28 | impl ::kernel::ModuleMetadata for RustMinimal {
+       |                                               - while parsing this item list starting here
+    29 |     const NAME: &'static ::kernel::str::CStr = c"rust_minimal";
+       |                                                 ^^^^^^^^^^^^^^ expected one of 8 possible tokens
+    30 | }
+       | - the item list ends here
+       |
+       = note: you may be trying to write a c-string literal
+       = note: c-string literals require Rust 2021 or later
+       = help: pass `--edition 2024` to `rustc`
+       = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+A workaround is to use `RUSTFMT=n`, which is documented in the `Makefile`
+help for cases where macro expanded source may happen to break `rustfmt`
+for other reasons, but this is not one of those cases.
+
+One solution would be to pass `--edition`, but we want `rustfmt` to
+use the entire configuration, even if currently we essentially use the
+default configuration.
+
+Thus explicitly give the path to the config file to `rustfmt` instead.
+
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Fixes: 2f7ab1267dc9 ("Kbuild: add Rust support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://patch.msgid.link/20260115183832.46595-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/Makefile.build |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -356,7 +356,7 @@ $(obj)/%.o: $(obj)/%.rs FORCE
+ quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+       cmd_rustc_rsi_rs = \
+       $(rust_common_cmd) -Zunpretty=expanded $< >$@; \
+-      command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@
++      command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) --config-path $(srctree)/.rustfmt.toml $@
+ $(obj)/%.rsi: $(obj)/%.rs FORCE
+       +$(call if_changed_dep,rustc_rsi_rs)
diff --git a/queue-6.18/rust-rbtree-fix-documentation-typo-in-cursormut-peek_next-method.patch b/queue-6.18/rust-rbtree-fix-documentation-typo-in-cursormut-peek_next-method.patch
new file mode 100644 (file)
index 0000000..b1e0edc
--- /dev/null
@@ -0,0 +1,40 @@
+From 45f6aed8a835ee2bdd0a5d5ee626a91fe285014f Mon Sep 17 00:00:00 2001
+From: Hang Shu <m18080292938@163.com>
+Date: Fri, 7 Nov 2025 09:39:17 +0000
+Subject: rust: rbtree: fix documentation typo in CursorMut peek_next method
+
+From: Hang Shu <m18080292938@163.com>
+
+commit 45f6aed8a835ee2bdd0a5d5ee626a91fe285014f upstream.
+
+The peek_next method's doc comment incorrectly stated it accesses the
+"previous" node when it actually accesses the next node.
+
+Fix the documentation to accurately reflect the method's behavior.
+
+Fixes: 98c14e40e07a ("rust: rbtree: add cursor")
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Signed-off-by: Hang Shu <m18080292938@163.com>
+Reported-by: Miguel Ojeda <ojeda@kernel.org>
+Closes: https://github.com/Rust-for-Linux/linux/issues/1205
+Cc: stable@vger.kernel.org
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://patch.msgid.link/20251107093921.3379954-1-m18080292938@163.com
+[ Reworded slightly. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ rust/kernel/rbtree.rs |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/rust/kernel/rbtree.rs
++++ b/rust/kernel/rbtree.rs
+@@ -835,7 +835,7 @@ impl<'a, K, V> Cursor<'a, K, V> {
+         self.peek(Direction::Prev)
+     }
+-    /// Access the previous node without moving the cursor.
++    /// Access the next node without moving the cursor.
+     pub fn peek_next(&self) -> Option<(&K, &V)> {
+         self.peek(Direction::Next)
+     }
diff --git a/queue-6.18/scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch b/queue-6.18/scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch
new file mode 100644 (file)
index 0000000..fdc257f
--- /dev/null
@@ -0,0 +1,32 @@
+From 4747bafaa50115d9667ece446b1d2d4aba83dc7f Mon Sep 17 00:00:00 2001
+From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+Date: Sat, 13 Dec 2025 16:36:43 +0800
+Subject: scsi: be2iscsi: Fix a memory leak in beiscsi_boot_get_sinfo()
+
+From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+
+commit 4747bafaa50115d9667ece446b1d2d4aba83dc7f upstream.
+
+If nonemb_cmd->va fails to be allocated, free the allocation previously
+made by alloc_mcc_wrb().
+
+Fixes: 50a4b824be9e ("scsi: be2iscsi: Fix to make boot discovery non-blocking")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+Link: https://patch.msgid.link/20251213083643.301240-1-lihaoxiang@isrc.iscas.ac.cn
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/be2iscsi/be_mgmt.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/be2iscsi/be_mgmt.c
++++ b/drivers/scsi/be2iscsi/be_mgmt.c
+@@ -1025,6 +1025,7 @@ unsigned int beiscsi_boot_get_sinfo(stru
+                                             &nonemb_cmd->dma,
+                                             GFP_KERNEL);
+       if (!nonemb_cmd->va) {
++              free_mcc_wrb(ctrl, tag);
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
diff --git a/queue-6.18/scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch b/queue-6.18/scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch
new file mode 100644 (file)
index 0000000..a873422
--- /dev/null
@@ -0,0 +1,34 @@
+From 56bd3c0f749f45793d1eae1d0ddde4255c749bf6 Mon Sep 17 00:00:00 2001
+From: Thomas Fourier <fourier.thomas@gmail.com>
+Date: Mon, 12 Jan 2026 14:43:24 +0100
+Subject: scsi: qla2xxx: edif: Fix dma_free_coherent() size
+
+From: Thomas Fourier <fourier.thomas@gmail.com>
+
+commit 56bd3c0f749f45793d1eae1d0ddde4255c749bf6 upstream.
+
+Earlier in the function, the ha->flt buffer is allocated with size
+sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE but freed in the error
+path with size SFP_DEV_SIZE.
+
+Fixes: 84318a9f01ce ("scsi: qla2xxx: edif: Add send, receive, and accept for auth_els")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Fourier <fourier.thomas@gmail.com>
+Link: https://patch.msgid.link/20260112134326.55466-2-fourier.thomas@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -4488,7 +4488,7 @@ fail_lsrjt:
+ fail_elsrej:
+       dma_pool_destroy(ha->purex_dma_pool);
+ fail_flt:
+-      dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
++      dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
+           ha->flt, ha->flt_dma);
+ fail_flt_buffer:
diff --git a/queue-6.18/selftests-mptcp-check-no-dup-close-events-after-error.patch b/queue-6.18/selftests-mptcp-check-no-dup-close-events-after-error.patch
new file mode 100644 (file)
index 0000000..c6d5dbf
--- /dev/null
@@ -0,0 +1,110 @@
+From 8467458dfa61b37e259e3485a5d3e415d08193c1 Mon Sep 17 00:00:00 2001
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 27 Jan 2026 20:27:24 +0100
+Subject: selftests: mptcp: check no dup close events after error
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+commit 8467458dfa61b37e259e3485a5d3e415d08193c1 upstream.
+
+This validates the previous commit: subflow closed events are re-sent
+with less info when the initial subflow is disconnected after an error
+and each time a subflow is closed after that.
+
+In this new test, the userspace PM is involved because that's how it was
+discovered, but it is not specific to it. The initial subflow is
+terminated with a RESET, and that will cause the subflow disconnect.
+Then, a new subflow is initiated, but also got rejected, which cause a
+second subflow closed event, but not a third one.
+
+While at it, in case of failure to get the expected amount of events,
+the events are printed.
+
+The 'Fixes' tag here below is the same as the one from the previous
+commit: this patch here is not fixing anything wrong in the selftests,
+but it validates the previous fix for an issue introduced by this commit
+ID.
+
+Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events")
+Cc: stable@vger.kernel.org
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-2-7f71e1bc4feb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_join.sh |   51 ++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -3717,11 +3717,32 @@ chk_evt_nr()
+       count=$(grep -cw "type:${evt}" "${evts}")
+       if [ "${count}" != "${exp}" ]; then
+               fail_test "got ${count} events, expected ${exp}"
++              cat "${evts}"
+       else
+               print_ok
+       fi
+ }
++# $1: ns ; $2: event type ; $3: expected count
++wait_event()
++{
++      local ns="${1}"
++      local evt_name="${2}"
++      local exp="${3}"
++
++      local evt="${!evt_name}"
++      local evts="${evts_ns1}"
++      local count
++
++      [ "${ns}" == "ns2" ] && evts="${evts_ns2}"
++
++      for _ in $(seq 100); do
++              count=$(grep -cw "type:${evt}" "${evts}")
++              [ "${count}" -ge "${exp}" ] && break
++              sleep 0.1
++      done
++}
++
+ userspace_tests()
+ {
+       # userspace pm type prevents add_addr
+@@ -3930,6 +3951,36 @@ userspace_tests()
+               kill_events_pids
+               mptcp_lib_kill_group_wait $tests_pid
+       fi
++
++      # userspace pm no duplicated spurious close events after an error
++      if reset_with_events "userspace pm no dup close events after error" &&
++         continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
++              set_userspace_pm $ns2
++              pm_nl_set_limits $ns1 0 2
++              { timeout_test=120 test_linkfail=128 speed=slow \
++                      run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null
++              local tests_pid=$!
++              wait_event ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
++              userspace_pm_add_sf $ns2 10.0.3.2 20
++              chk_mptcp_info subflows 1 subflows 1
++              chk_subflows_total 2 2
++
++              # force quick loss
++              ip netns exec $ns2 sysctl -q net.ipv4.tcp_syn_retries=1
++              if ip netns exec "${ns1}" ${iptables} -A INPUT -s "10.0.1.2" \
++                    -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset &&
++                 ip netns exec "${ns2}" ${iptables} -A INPUT -d "10.0.1.2" \
++                    -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset; then
++                      wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 1
++                      wait_event ns1 MPTCP_LIB_EVENT_SUB_CLOSED 1
++                      chk_subflows_total 1 1
++                      userspace_pm_add_sf $ns2 10.0.1.2 0
++                      wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
++                      chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
++              fi
++              kill_events_pids
++              mptcp_lib_kill_group_wait $tests_pid
++      fi
+ }
+ endpoint_tests()
diff --git a/queue-6.18/selftests-mptcp-check-subflow-errors-in-close-events.patch b/queue-6.18/selftests-mptcp-check-subflow-errors-in-close-events.patch
new file mode 100644 (file)
index 0000000..7f75655
--- /dev/null
@@ -0,0 +1,93 @@
+From 2ef9e3a3845d0a20b62b01f5b731debd0364688d Mon Sep 17 00:00:00 2001
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 27 Jan 2026 20:27:26 +0100
+Subject: selftests: mptcp: check subflow errors in close events
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+commit 2ef9e3a3845d0a20b62b01f5b731debd0364688d upstream.
+
+This validates the previous commit: subflow closed events should contain
+an error field when a subflow got closed with an error, e.g. reset or
+timeout.
+
+For this test, the chk_evt_nr helper has been extended to check
+attributes in the matched events.
+
+In this test, the 2 subflow closed events should have an error.
+
+The 'Fixes' tag here below is the same as the one from the previous
+commit: this patch here is not fixing anything wrong in the selftests,
+but it validates the previous fix for an issue introduced by this commit
+ID.
+
+Fixes: 15cc10453398 ("mptcp: deliver ssk errors to msk")
+Cc: stable@vger.kernel.org
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-4-7f71e1bc4feb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_join.sh |   23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -3692,21 +3692,28 @@ userspace_pm_chk_get_addr()
+       fi
+ }
+-# $1: ns ; $2: event type ; $3: count
++# $1: ns ; $2: event type ; $3: count ; [ $4: attr ; $5: attr count ]
+ chk_evt_nr()
+ {
+       local ns=${1}
+       local evt_name="${2}"
+       local exp="${3}"
++      local attr="${4}"
++      local attr_exp="${5}"
+       local evts="${evts_ns1}"
+       local evt="${!evt_name}"
++      local attr_name
+       local count
++      if [ -n "${attr}" ]; then
++              attr_name=", ${attr}: ${attr_exp}"
++      fi
++
+       evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
+       [ "${ns}" == "ns2" ] && evts="${evts_ns2}"
+-      print_check "event ${ns} ${evt_name} (${exp})"
++      print_check "event ${ns} ${evt_name} (${exp}${attr_name})"
+       if [[ "${evt_name}" = "LISTENER_"* ]] &&
+          ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
+@@ -3718,6 +3725,16 @@ chk_evt_nr()
+       if [ "${count}" != "${exp}" ]; then
+               fail_test "got ${count} events, expected ${exp}"
+               cat "${evts}"
++              return
++      elif [ -z "${attr}" ]; then
++              print_ok
++              return
++      fi
++
++      count=$(grep -w "type:${evt}" "${evts}" | grep -c ",${attr}:")
++      if [ "${count}" != "${attr_exp}" ]; then
++              fail_test "got ${count} event attributes, expected ${attr_exp}"
++              grep -w "type:${evt}" "${evts}"
+       else
+               print_ok
+       fi
+@@ -3976,7 +3993,7 @@ userspace_tests()
+                       chk_subflows_total 1 1
+                       userspace_pm_add_sf $ns2 10.0.1.2 0
+                       wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+-                      chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
++                      chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 error 2
+               fi
+               kill_events_pids
+               mptcp_lib_kill_group_wait $tests_pid
diff --git a/queue-6.18/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch b/queue-6.18/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch
new file mode 100644 (file)
index 0000000..6494095
--- /dev/null
@@ -0,0 +1,60 @@
+From c5d5ecf21fdd9ce91e6116feb3aa83cee73352cc Mon Sep 17 00:00:00 2001
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 27 Jan 2026 20:27:27 +0100
+Subject: selftests: mptcp: join: fix local endp not being tracked
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+commit c5d5ecf21fdd9ce91e6116feb3aa83cee73352cc upstream.
+
+When running this mptcp_join.sh selftest on older kernel versions not
+supporting local endpoints tracking, this test fails because 3 MP_JOIN
+ACKs have been received, while only 2 were expected.
+
+It is not clear why only 2 MP_JOIN ACKs were expected on old kernel
+versions, while 3 MP_JOIN SYN and SYN+ACK were expected. When testing on
+the v5.15.197 kernel, 3 MP_JOIN ACKs are seen, which is also what is
+expected in the selftests included in this kernel version, see commit
+f4480eaad489 ("selftests: mptcp: add missing join check").
+
+Switch the expected MP_JOIN ACKs to 3. While at it, move this
+chk_join_nr helper out of the special condition for older kernel
+versions as it is now the same as with more recent ones. Also, invert
+the condition to be more logical: what's expected on newer kernel
+versions having such helper first.
+
+Fixes: d4c81bbb8600 ("selftests: mptcp: join: support local endpoint being tracked or not")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-5-7f71e1bc4feb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_join.sh |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -2305,17 +2305,16 @@ signal_address_tests()
+               ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1
+               speed=slow \
+                       run_tests $ns1 $ns2 10.0.1.1
++              chk_join_nr 3 3 3
+               # It is not directly linked to the commit introducing this
+               # symbol but for the parent one which is linked anyway.
+-              if ! mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
+-                      chk_join_nr 3 3 2
+-                      chk_add_nr 4 4
+-              else
+-                      chk_join_nr 3 3 3
++              if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then
+                       # the server will not signal the address terminating
+                       # the MPC subflow
+                       chk_add_nr 3 3
++              else
++                      chk_add_nr 4 4
+               fi
+       fi
+ }
index 309e51ccfd31bd0c1daa029f0dd89b75c274cb2a..ddbfa61f7061d1b178cdc1934eccd98c5c08b6a8 100644 (file)
@@ -56,3 +56,35 @@ drm-xe-nvm-manage-nvm-aux-cleanup-with-devres.patch
 drm-xe-nvm-fix-double-free-on-aux-add-failure.patch
 sched-deadline-document-dl_server.patch
 sched-deadline-fix-stuck-dl_server.patch
+writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch
+pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch
+pinctrl-meson-mark-the-gpio-controller-as-sleeping.patch
+pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch
+perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch
+firewire-core-fix-race-condition-against-transaction-list.patch
+riscv-compat-fix-compat_uts_machine-definition.patch
+rust-rbtree-fix-documentation-typo-in-cursormut-peek_next-method.patch
+rust-kbuild-give-config-path-to-rustfmt-in-.rsi-target.patch
+asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch
+scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch
+asoc-amd-yc-add-dmi-quirk-for-acer-travelmate-p216-41-tco.patch
+gpio-pca953x-mask-interrupts-in-irq-shutdown.patch
+kbuild-rust-clean-libpin_init_internal-in-mrproper.patch
+scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch
+efivarfs-fix-error-propagation-in-efivar_entry_get.patch
+nvmet-fix-race-in-nvmet_bio_done-leading-to-null-pointer-dereference.patch
+alsa-hda-realtek-fix-right-sounds-and-mute-micmute-leds-for-hp-machine.patch
+gpio-rockchip-stop-calling-pinctrl-for-set_direction.patch
+mm-kasan-fix-kasan-poisoning-in-vrealloc.patch
+mptcp-only-reset-subflow-errors-when-propagated.patch
+selftests-mptcp-check-no-dup-close-events-after-error.patch
+selftests-mptcp-check-subflow-errors-in-close-events.patch
+selftests-mptcp-join-fix-local-endp-not-being-tracked.patch
+flex_proportions-make-fprop_new_period-hardirq-safe.patch
+btrfs-do-not-strictly-require-dirty-metadata-threshold-for-metadata-writepages.patch
+mm-kfence-randomize-the-freelist-on-initialization.patch
+mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
+mm-swap-restore-swap_space-attr-aviod-kernel-panic.patch
+mm-memory-failure-teach-kill_accessing_process-to-accept-hugetlb-tail-page-pfn.patch
+mm-shmem-swap-fix-race-of-truncate-and-swap-entry-split.patch
+net-fix-segmentation-of-forwarding-fraglist-gro.patch
diff --git a/queue-6.18/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch b/queue-6.18/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch
new file mode 100644 (file)
index 0000000..a1fe873
--- /dev/null
@@ -0,0 +1,75 @@
+From 543467d6fe97e27e22a26e367fda972dbefebbff Mon Sep 17 00:00:00 2001
+From: Laveesh Bansal <laveeshb@laveeshbansal.com>
+Date: Tue, 6 Jan 2026 14:50:58 +0000
+Subject: writeback: fix 100% CPU usage when dirtytime_expire_interval is 0
+
+From: Laveesh Bansal <laveeshb@laveeshbansal.com>
+
+commit 543467d6fe97e27e22a26e367fda972dbefebbff upstream.
+
+When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback()
+schedules delayed work with a delay of 0, causing immediate execution.
+The function then reschedules itself with 0 delay again, creating an
+infinite busy loop that causes 100% kworker CPU usage.
+
+Fix by:
+- Only scheduling delayed work in wakeup_dirtytime_writeback() when
+  dirtytime_expire_interval is non-zero
+- Cancelling the delayed work in dirtytime_interval_handler() when
+  the interval is set to 0
+- Adding a guard in start_dirtytime_writeback() for defensive coding
+
+Tested by booting kernel in QEMU with virtme-ng:
+- Before fix: kworker CPU spikes to ~73%
+- After fix: CPU remains at normal levels
+- Setting interval back to non-zero correctly resumes writeback
+
+Fixes: a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written")
+Cc: stable@vger.kernel.org
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220227
+Signed-off-by: Laveesh Bansal <laveeshb@laveeshbansal.com>
+Link: https://patch.msgid.link/20260106145059.543282-2-laveeshb@laveeshbansal.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -2471,7 +2471,8 @@ static void wakeup_dirtytime_writeback(s
+                               wb_wakeup(wb);
+       }
+       rcu_read_unlock();
+-      schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
++      if (dirtytime_expire_interval)
++              schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
+ }
+ static int dirtytime_interval_handler(const struct ctl_table *table, int write,
+@@ -2480,8 +2481,12 @@ static int dirtytime_interval_handler(co
+       int ret;
+       ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+-      if (ret == 0 && write)
+-              mod_delayed_work(system_percpu_wq, &dirtytime_work, 0);
++      if (ret == 0 && write) {
++              if (dirtytime_expire_interval)
++                      mod_delayed_work(system_percpu_wq, &dirtytime_work, 0);
++              else
++                      cancel_delayed_work_sync(&dirtytime_work);
++      }
+       return ret;
+ }
+@@ -2498,7 +2503,8 @@ static const struct ctl_table vm_fs_writ
+ static int __init start_dirtytime_writeback(void)
+ {
+-      schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
++      if (dirtytime_expire_interval)
++              schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
+       register_sysctl_init("vm", vm_fs_writeback_table);
+       return 0;
+ }