]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Jun 2026 07:38:03 +0000 (09:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Jun 2026 07:38:03 +0000 (09:38 +0200)
added patches:
alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
alsa-scarlett2-return-enospc-for-out-of-bounds-flash-writes.patch
arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
bluetooth-hci_qca-migrate-to-serdev-specific-shutdown-function.patch
ice-fix-vf-queue-configuration-with-low-mtu-values.patch
iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch
mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
mptcp-cleanup-fallback-dummy-mapping-generation.patch
mptcp-do-not-drop-partial-packets.patch
mptcp-handle-first-subflow-closing-consistently.patch
mptcp-introduce-the-mptcp_init_skb-helper.patch
mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
mptcp-reset-rcv-wnd-on-disconnect.patch
net-hsr-defer-node-table-free-until-after-rcu-readers.patch
octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch
rxrpc-fix-data-decrypt-vs-splice-by-copying-data-to-buffer-in-recvmsg.patch
rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch
scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
selftests-mptcp-drop-nanoseconds-width-specifier.patch
serdev-provide-a-bustype-shutdown-function.patch
thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
x86-alternatives-rename-apply_relocation-to-text_poke_apply_relocation.patch
x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch

35 files changed:
queue-6.12/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch [new file with mode: 0644]
queue-6.12/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch [new file with mode: 0644]
queue-6.12/alsa-scarlett2-return-enospc-for-out-of-bounds-flash-writes.patch [new file with mode: 0644]
queue-6.12/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_qca-migrate-to-serdev-specific-shutdown-function.patch [new file with mode: 0644]
queue-6.12/ice-fix-vf-queue-configuration-with-low-mtu-values.patch [new file with mode: 0644]
queue-6.12/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch [new file with mode: 0644]
queue-6.12/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch [new file with mode: 0644]
queue-6.12/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch [new file with mode: 0644]
queue-6.12/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch [new file with mode: 0644]
queue-6.12/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch [new file with mode: 0644]
queue-6.12/mptcp-cleanup-fallback-dummy-mapping-generation.patch [new file with mode: 0644]
queue-6.12/mptcp-do-not-drop-partial-packets.patch [new file with mode: 0644]
queue-6.12/mptcp-handle-first-subflow-closing-consistently.patch [new file with mode: 0644]
queue-6.12/mptcp-introduce-the-mptcp_init_skb-helper.patch [new file with mode: 0644]
queue-6.12/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch [new file with mode: 0644]
queue-6.12/mptcp-reset-rcv-wnd-on-disconnect.patch [new file with mode: 0644]
queue-6.12/net-hsr-defer-node-table-free-until-after-rcu-readers.patch [new file with mode: 0644]
queue-6.12/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch [new file with mode: 0644]
queue-6.12/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch [new file with mode: 0644]
queue-6.12/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-data-decrypt-vs-splice-by-copying-data-to-buffer-in-recvmsg.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch [new file with mode: 0644]
queue-6.12/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch [new file with mode: 0644]
queue-6.12/selftests-mptcp-drop-nanoseconds-width-specifier.patch [new file with mode: 0644]
queue-6.12/serdev-provide-a-bustype-shutdown-function.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch [new file with mode: 0644]
queue-6.12/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch [new file with mode: 0644]
queue-6.12/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch [new file with mode: 0644]
queue-6.12/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch [new file with mode: 0644]
queue-6.12/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch [new file with mode: 0644]
queue-6.12/x86-alternatives-rename-apply_relocation-to-text_poke_apply_relocation.patch [new file with mode: 0644]
queue-6.12/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch [new file with mode: 0644]

diff --git a/queue-6.12/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch b/queue-6.12/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
new file mode 100644 (file)
index 0000000..50a0187
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-260595-greg=kroah.com@vger.kernel.org Fri Jun  5 03:04:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 20:59:03 -0400
+Subject: ALSA: firewire-motu: Protect register DSP event queue positions
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Takashi Sakamoto" <o-takashi@sakamocchi.jp>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260605005903.2802313-1-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 98fb1c1bb11e29eb609b7200a25e136e05aa4498 ]
+
+The register DSP event queue is updated under parser->lock, but
+snd_motu_register_dsp_message_parser_count_event() reads pull_pos and
+push_pos without the lock.
+snd_motu_register_dsp_message_parser_copy_event() also reads both queue
+positions before taking the lock.
+
+Protect these accesses with parser->lock as well. This keeps the hwdep
+poll/read path consistent with the producer side and with the cached
+meter/parameter accessors.
+
+Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260521-alsa-firewire-motu-event-locking-v1-1-708e1c2b5e56@gmail.com
+[ converted copy_event() from manual spin_lock_irqsave/spin_unlock_irqrestore to guard(spinlock_irqsave) ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/firewire/motu/motu-register-dsp-message-parser.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/sound/firewire/motu/motu-register-dsp-message-parser.c
++++ b/sound/firewire/motu/motu-register-dsp-message-parser.c
+@@ -393,6 +393,8 @@ unsigned int snd_motu_register_dsp_messa
+ {
+       struct msg_parser *parser = motu->message_parser;
++      guard(spinlock_irqsave)(&parser->lock);
++
+       if (parser->pull_pos > parser->push_pos)
+               return EVENT_QUEUE_SIZE - parser->pull_pos + parser->push_pos;
+       else
+@@ -402,14 +404,14 @@ unsigned int snd_motu_register_dsp_messa
+ bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32 *event)
+ {
+       struct msg_parser *parser = motu->message_parser;
+-      unsigned int pos = parser->pull_pos;
+-      unsigned long flags;
++      unsigned int pos;
+-      if (pos == parser->push_pos)
+-              return false;
++      guard(spinlock_irqsave)(&parser->lock);
+-      spin_lock_irqsave(&parser->lock, flags);
++      if (parser->pull_pos == parser->push_pos)
++              return false;
++      pos = parser->pull_pos;
+       *event = parser->event_queue[pos];
+       ++pos;
+@@ -417,7 +419,5 @@ bool snd_motu_register_dsp_message_parse
+               pos = 0;
+       parser->pull_pos = pos;
+-      spin_unlock_irqrestore(&parser->lock, flags);
+-
+       return true;
+ }
diff --git a/queue-6.12/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch b/queue-6.12/alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
new file mode 100644 (file)
index 0000000..7e0557c
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-256678-greg=kroah.com@vger.kernel.org Fri May 29 20:05:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:25:00 -0400
+Subject: ALSA: scarlett2: Allow flash writes ending at segment boundary
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529172500.1327796-2-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit a69b677e47a80319ce148d61cc29a2b57006e78d ]
+
+scarlett2_hwdep_write() rejects writes when offset + count is greater than
+or equal to the selected flash segment size. That incorrectly treats a
+write ending exactly at the end of the segment as out of space, although
+the last byte written is still within the segment.
+
+Split invalid argument checks from the segment-space check, keep
+zero-length writes as no-ops, and compare count against the remaining
+segment size. This permits exact-end writes and avoids relying on
+offset + count before deciding whether the request is in bounds.
+
+Fixes: 1abfbd3c9527 ("ALSA: scarlett2: Add support for uploading new firmware")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-alsa-scarlett2-flash-write-boundary-v1-1-b550480e92da@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/mixer_scarlett2.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/sound/usb/mixer_scarlett2.c
++++ b/sound/usb/mixer_scarlett2.c
+@@ -9549,12 +9549,15 @@ static long scarlett2_hwdep_write(struct
+       flash_size = private->flash_segment_blocks[segment_id] *
+                    SCARLETT2_FLASH_BLOCK_SIZE;
+-      if (count < 0 || *offset < 0 || *offset + count >= flash_size)
+-              return -ENOSPC;
++      if (count < 0 || *offset < 0)
++              return -EINVAL;
+       if (!count)
+               return 0;
++      if (*offset >= flash_size || count > flash_size - *offset)
++              return -ENOSPC;
++
+       /* Limit the *req size to SCARLETT2_FLASH_RW_MAX */
+       if (count > max_data_size)
+               count = max_data_size;
diff --git a/queue-6.12/alsa-scarlett2-return-enospc-for-out-of-bounds-flash-writes.patch b/queue-6.12/alsa-scarlett2-return-enospc-for-out-of-bounds-flash-writes.patch
new file mode 100644 (file)
index 0000000..216929b
--- /dev/null
@@ -0,0 +1,36 @@
+From stable+bounces-256677-greg=kroah.com@vger.kernel.org Fri May 29 20:05:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:24:59 -0400
+Subject: ALSA: scarlett2: Return ENOSPC for out-of-bounds flash writes
+To: stable@vger.kernel.org
+Cc: "Geoffrey D. Bennett" <g@b4.vu>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529172500.1327796-1-sashal@kernel.org>
+
+From: "Geoffrey D. Bennett" <g@b4.vu>
+
+[ Upstream commit 74641bfcbf4e698b770b1b62a74e73934843e90e ]
+
+When writing to flash, return ENOSPC instead of EINVAL if the requested
+write would exceed the size of the flash segment.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/3a4af07b0329bed5ffb6994594e4f7bd202aad0f.1727971672.git.g@b4.vu
+Stable-dep-of: a69b677e47a8 ("ALSA: scarlett2: Allow flash writes ending at segment boundary")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/mixer_scarlett2.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/usb/mixer_scarlett2.c
++++ b/sound/usb/mixer_scarlett2.c
+@@ -9550,7 +9550,7 @@ static long scarlett2_hwdep_write(struct
+                    SCARLETT2_FLASH_BLOCK_SIZE;
+       if (count < 0 || *offset < 0 || *offset + count >= flash_size)
+-              return -EINVAL;
++              return -ENOSPC;
+       if (!count)
+               return 0;
diff --git a/queue-6.12/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch b/queue-6.12/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
new file mode 100644 (file)
index 0000000..b2bb04a
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-259395-greg=kroah.com@vger.kernel.org Mon Jun  1 02:44:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 May 2026 20:44:17 -0400
+Subject: arm64: tlb: Flush walk cache when unsharing PMD tables
+To: stable@vger.kernel.org
+Cc: Zeng Heng <zengheng4@huawei.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601004417.90834-1-sashal@kernel.org>
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit c2ff4764e03e7a8d758352f4aceb8fe1be6ac971 ]
+
+When huge_pmd_unshare() is called to unshare a PMD table, the
+tlb_unshare_pmd_ptdesc() function sets tlb->unshared_tables=true
+but the aarch64 tlb_flush() only checked tlb->freed_tables to
+determine whether to use TLBF_NONE (vae1is, invalidates walk
+cache) or TLBF_NOWALKCACHE (vale1is, leaf-only).
+
+This caused the stale PMD page table entry to remain in the walk cache
+after unshare, potentially leading to incorrect page table walks.
+
+Fix by including unshared_tables in the check, so that when
+unsharing tables, TLBF_NONE is used and the walk cache is properly
+invalidated.
+
+Here is the detailed distinction between vae1is and vale1is:
+
+| Instruction Combination  | Actual Invalidation Scope                         |
+| ------------------------ | --------------------------------------------------|
+| `VAE1IS`  + TTL=`0`      | All entries at all levels (full invalidation)     |
+| `VAE1IS`  + TTL=`2` (L2) | Non-leaf at Level 0/1 + leaf at Level 2           |
+| `VALE1IS` + TTL=`0`      | Leaf entries at all levels (non-leaf not cleared) |
+| `VALE1IS` + TTL=`2` (L2) | Leaf entry at Level 2 only                        |
+
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/tlb.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/tlb.h
++++ b/arch/arm64/include/asm/tlb.h
+@@ -58,7 +58,7 @@ static inline int tlb_get_level(struct m
+ static inline void tlb_flush(struct mmu_gather *tlb)
+ {
+       struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
+-      bool last_level = !tlb->freed_tables;
++      bool last_level = !(tlb->freed_tables || tlb->unshared_tables);
+       unsigned long stride = tlb_get_unmap_size(tlb);
+       int tlb_level = tlb_get_level(tlb);
diff --git a/queue-6.12/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch b/queue-6.12/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
new file mode 100644 (file)
index 0000000..7301c3c
--- /dev/null
@@ -0,0 +1,154 @@
+From stable+bounces-256740-greg=kroah.com@vger.kernel.org Fri May 29 21:31:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 15:27:56 -0400
+Subject: Bluetooth: hci_qca: Convert timeout from jiffies to ms
+To: stable@vger.kernel.org
+Cc: Shuai Zhang <shuai.zhang@oss.qualcomm.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Bartosz Golaszewski <bartosz.golaszewski@linaro.org>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529192756.1699014-3-sashal@kernel.org>
+
+From: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+
+[ Upstream commit 375ba7484132662a4a8c7547d088fb6275c00282 ]
+
+Since the timer uses jiffies as its unit rather than ms, the timeout value
+must be converted from ms to jiffies when configuring the timer. Otherwise,
+the intended 8s timeout is incorrectly set to approximately 33s.
+
+To improve readability, embed msecs_to_jiffies() directly in the macro
+definitions and drop the _MS suffix from macros that now yield jiffies
+values: MEMDUMP_TIMEOUT, FW_DOWNLOAD_TIMEOUT, IBS_DISABLE_SSR_TIMEOUT,
+CMD_TRANS_TIMEOUT, and IBS_BTSOC_TX_IDLE_TIMEOUT.
+
+IBS_WAKE_RETRANS_TIMEOUT_MS and IBS_HOST_TX_IDLE_TIMEOUT_MS are
+intentionally left unchanged. Their values are stored in the struct fields
+wake_retrans and tx_idle_delay, which hold ms values at runtime and can be
+modified via debugfs. The msecs_to_jiffies() conversion happens at each
+call site against the field value, so it cannot be embedded in the macro.
+
+Wake timer depends on commit c347ca17d62a
+
+Cc: stable@vger.kernel.org
+Fixes: d841502c79e3 ("Bluetooth: hci_qca: Collect controller memory dump during SSR")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c |   33 ++++++++++++++++-----------------
+ 1 file changed, 16 insertions(+), 17 deletions(-)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -47,13 +47,12 @@
+ #define HCI_MAX_IBS_SIZE      10
+ #define IBS_WAKE_RETRANS_TIMEOUT_MS   100
+-#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS  200
++#define IBS_BTSOC_TX_IDLE_TIMEOUT     msecs_to_jiffies(200)
+ #define IBS_HOST_TX_IDLE_TIMEOUT_MS   2000
+-#define CMD_TRANS_TIMEOUT_MS          100
+-#define MEMDUMP_TIMEOUT_MS            8000
+-#define IBS_DISABLE_SSR_TIMEOUT_MS \
+-      (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS)
+-#define FW_DOWNLOAD_TIMEOUT_MS                3000
++#define CMD_TRANS_TIMEOUT             msecs_to_jiffies(100)
++#define MEMDUMP_TIMEOUT                       msecs_to_jiffies(8000)
++#define FW_DOWNLOAD_TIMEOUT           msecs_to_jiffies(3000)
++#define IBS_DISABLE_SSR_TIMEOUT               (MEMDUMP_TIMEOUT + FW_DOWNLOAD_TIMEOUT)
+ /* susclk rate */
+ #define SUSCLK_RATE_32KHZ     32768
+@@ -1078,7 +1077,7 @@ static void qca_controller_memdump(struc
+                       queue_delayed_work(qca->workqueue,
+                                          &qca->ctrl_memdump_timeout,
+-                                         msecs_to_jiffies(MEMDUMP_TIMEOUT_MS));
++                                         MEMDUMP_TIMEOUT);
+                       skb_pull(skb, sizeof(qca_memdump->ram_dump_size));
+                       qca_memdump->current_seq_no = 0;
+                       qca_memdump->received_dump = 0;
+@@ -1350,7 +1349,7 @@ static int qca_set_baudrate(struct hci_d
+       if (hu->serdev)
+               serdev_device_wait_until_sent(hu->serdev,
+-                    msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
++                    CMD_TRANS_TIMEOUT);
+       /* Give the controller time to process the request */
+       switch (qca_soc_type(hu)) {
+@@ -1381,8 +1380,8 @@ static inline void host_set_baudrate(str
+ static int qca_send_power_pulse(struct hci_uart *hu, bool on)
+ {
++      int timeout = CMD_TRANS_TIMEOUT;
+       int ret;
+-      int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
+       u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE;
+       /* These power pulses are single byte command which are sent
+@@ -1584,7 +1583,7 @@ static void qca_wait_for_dump_collection
+       struct qca_data *qca = hu->priv;
+       wait_on_bit_timeout(&qca->flags, QCA_MEMDUMP_COLLECTION,
+-                          TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT_MS);
++                          TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT);
+       clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
+ }
+@@ -2519,7 +2518,7 @@ static void qca_serdev_remove(struct ser
+ static void qca_serdev_shutdown(struct serdev_device *serdev)
+ {
+       int ret;
+-      int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
++      int timeout = CMD_TRANS_TIMEOUT;
+       struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+       struct hci_uart *hu = &qcadev->serdev_hu;
+       struct hci_dev *hdev = hu->hdev;
+@@ -2576,7 +2575,7 @@ static int __maybe_unused qca_suspend(st
+       bool tx_pending = false;
+       int ret = 0;
+       u8 cmd;
+-      u32 wait_timeout = 0;
++      unsigned long wait_timeout = 0;
+       set_bit(QCA_SUSPENDING, &qca->flags);
+@@ -2597,15 +2596,15 @@ static int __maybe_unused qca_suspend(st
+       if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
+           test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
+               wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
+-                                      IBS_DISABLE_SSR_TIMEOUT_MS :
+-                                      FW_DOWNLOAD_TIMEOUT_MS;
++                                      IBS_DISABLE_SSR_TIMEOUT :
++                                      FW_DOWNLOAD_TIMEOUT;
+               /* QCA_IBS_DISABLED flag is set to true, During FW download
+                * and during memory dump collection. It is reset to false,
+                * After FW download complete.
+                */
+               wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
+-                          TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));
++                          TASK_UNINTERRUPTIBLE, wait_timeout);
+               if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
+                       bt_dev_err(hu->hdev, "SSR or FW download time out");
+@@ -2657,7 +2656,7 @@ static int __maybe_unused qca_suspend(st
+       if (tx_pending) {
+               serdev_device_wait_until_sent(hu->serdev,
+-                                            msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
++                                            CMD_TRANS_TIMEOUT);
+               serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
+       }
+@@ -2666,7 +2665,7 @@ static int __maybe_unused qca_suspend(st
+        */
+       ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
+                       qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
+-                      msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
++                      IBS_BTSOC_TX_IDLE_TIMEOUT);
+       if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
diff --git a/queue-6.12/bluetooth-hci_qca-migrate-to-serdev-specific-shutdown-function.patch b/queue-6.12/bluetooth-hci_qca-migrate-to-serdev-specific-shutdown-function.patch
new file mode 100644 (file)
index 0000000..8e8efb4
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-256739-greg=kroah.com@vger.kernel.org Fri May 29 21:28:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 15:27:55 -0400
+Subject: Bluetooth: hci_qca: Migrate to serdev specific shutdown function
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529192756.1699014-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit 12a6a5726c515455935982429ac35dee2307233d ]
+
+This saves a cast in the driver. The motivation is stop using the callback
+.shutdown in qca_serdev_driver.driver to make it possible to drop that.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/261a3384e25c4837d4efee87958805f15d7d4e3c.1765526117.git.u.kleine-koenig@baylibre.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 375ba7484132 ("Bluetooth: hci_qca: Convert timeout from jiffies to ms")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -2516,11 +2516,10 @@ static void qca_serdev_remove(struct ser
+       hci_uart_unregister_device(&qcadev->serdev_hu);
+ }
+-static void qca_serdev_shutdown(struct device *dev)
++static void qca_serdev_shutdown(struct serdev_device *serdev)
+ {
+       int ret;
+       int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
+-      struct serdev_device *serdev = to_serdev_device(dev);
+       struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+       struct hci_uart *hu = &qcadev->serdev_hu;
+       struct hci_dev *hdev = hu->hdev;
+@@ -2741,11 +2740,11 @@ static void hciqca_coredump(struct devic
+ static struct serdev_device_driver qca_serdev_driver = {
+       .probe = qca_serdev_probe,
+       .remove = qca_serdev_remove,
++      .shutdown = qca_serdev_shutdown,
+       .driver = {
+               .name = "hci_uart_qca",
+               .of_match_table = of_match_ptr(qca_bluetooth_of_match),
+               .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
+-              .shutdown = qca_serdev_shutdown,
+               .pm = &qca_pm_ops,
+ #ifdef CONFIG_DEV_COREDUMP
+               .coredump = hciqca_coredump,
diff --git a/queue-6.12/ice-fix-vf-queue-configuration-with-low-mtu-values.patch b/queue-6.12/ice-fix-vf-queue-configuration-with-low-mtu-values.patch
new file mode 100644 (file)
index 0000000..fd3b937
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-256848-greg=kroah.com@vger.kernel.org Sat May 30 03:23:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 21:17:49 -0400
+Subject: ice: fix VF queue configuration with low MTU values
+To: stable@vger.kernel.org
+Cc: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>, Jacob Keller <jacob.e.keller@intel.com>, Michal Swiatkowski <michal.swiatkowski@linux.intel.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Rafal Romanowski <rafal.romanowski@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530011749.2555710-1-sashal@kernel.org>
+
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+
+[ Upstream commit 3ba4dd024d26372733d1c02e13e076c6016e3320 ]
+
+The ice driver's VF queue configuration validation rejects
+databuffer_size values below 1024 bytes, which prevents VFs from
+using MTU values below 871 bytes.
+
+The iavf driver calculates databuffer_size based on the MTU using:
+  databuffer_size = ALIGN(MTU + LIBETH_RX_LL_LEN, 128)
+
+where LIBETH_RX_LL_LEN = 26 (ETH_HLEN + 2*VLAN_HLEN + ETH_FCS_LEN).
+
+For MTU values below 871:
+  MTU 870: 870 + 26 = 896, aligned to 128 = 896 (< 1024, rejected)
+  MTU 871: 871 + 26 = 897, aligned to 128 = 1024 (>= 1024, accepted)
+
+The 1024-byte minimum seems unnecessarily restrictive, because the hardware
+supports databuffer_size as low as 128 bytes (the alignment boundary),
+which should allow MTU values down to the standard minimum of 68 bytes.
+
+I haven't found the reason why the limit was configured in the commit
+9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message"), so
+with no more information and since it is working, change the minimum
+databuffer_size validation from 1024 to 128 bytes to allow standard low
+MTU values while still preventing invalid configurations.
+
+Fixes: 9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message")
+cc: stable@vger.kernel.org
+Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260515182419.1597859-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied the change to ice_virtchnl.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_virtchnl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -1746,7 +1746,7 @@ static int ice_vc_cfg_qs_msg(struct ice_
+                       if (qpi->rxq.databuffer_size != 0 &&
+                           (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
+-                           qpi->rxq.databuffer_size < 1024))
++                           qpi->rxq.databuffer_size < 128))
+                               goto error_param;
+                       ring->rx_buf_len = qpi->rxq.databuffer_size;
+                       if (qpi->rxq.max_pkt_size > max_frame_size ||
diff --git a/queue-6.12/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch b/queue-6.12/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
new file mode 100644 (file)
index 0000000..99cbcec
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-260549-greg=kroah.com@vger.kernel.org Thu Jun  4 19:50:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 13:38:04 -0400
+Subject: iio: chemical: scd30: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604173804.26980-2-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 ]
+
+Add a zero check for val2 before using it as a divisor when setting the
+sampling frequency. A user writing a zero fractional part to the
+sampling_frequency sysfs attribute triggers a division by zero in the
+kernel.
+
+Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -257,7 +257,7 @@ static int scd30_write_raw(struct iio_de
+       guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+-              if (val)
++              if (val || !val2)
+                       return -EINVAL;
+               val = 1000000000 / val2;
diff --git a/queue-6.12/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch b/queue-6.12/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
new file mode 100644 (file)
index 0000000..6a0aede
--- /dev/null
@@ -0,0 +1,178 @@
+From stable+bounces-260548-greg=kroah.com@vger.kernel.org Thu Jun  4 19:40:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 13:38:03 -0400
+Subject: iio: chemical: scd30: Use guard(mutex) to allow early returns
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, David Lechner <dlechner@baylibre.com>, Tomasz Duszynski <tomasz.duszynski@octakon.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604173804.26980-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 5feb5532870fbced5d6f450b8061a33f461b88ca ]
+
+Auto cleanup based release of the lock allows for simpler code flow in a
+few functions with large multiplexing style switch statements and no
+common operations following the switch.
+
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Cc: Tomasz Duszynski <tomasz.duszynski@octakon.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250209180624.701140-3-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 5aba4f94b225 ("iio: chemical: scd30: fix division by zero in write_raw")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |   63 ++++++++++++++++----------------------
+ 1 file changed, 28 insertions(+), 35 deletions(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -5,6 +5,7 @@
+  * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
+  */
+ #include <linux/bits.h>
++#include <linux/cleanup.h>
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+@@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev
+                         int *val, int *val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+       u16 tmp;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_PROCESSED:
+               if (chan->output) {
+                       *val = state->pressure_comp;
+-                      ret = IIO_VAL_INT;
+-                      break;
++                      return IIO_VAL_INT;
+               }
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+-                      break;
++                      return ret;
+               ret = scd30_read(state);
+               if (ret) {
+                       iio_device_release_direct_mode(indio_dev);
+-                      break;
++                      return ret;
+               }
+               *val = state->meas[chan->address];
+               iio_device_release_direct_mode(indio_dev);
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = 1;
+-              ret = IIO_VAL_INT_PLUS_MICRO;
+-              break;
++              return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = 0;
+               *val2 = 1000000000 / tmp;
+-              ret = IIO_VAL_INT_PLUS_NANO;
+-              break;
++              return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = tmp;
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
+                          int val, int val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               if (val)
+-                      break;
++                      return -EINVAL;
+               val = 1000000000 / val2;
+               if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S)
+-                      break;
++                      return -EINVAL;
+               ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
+               if (ret)
+-                      break;
++                      return ret;
+               state->meas_interval = val;
+-              break;
++              return 0;
+       case IIO_CHAN_INFO_RAW:
+               switch (chan->type) {
+               case IIO_PRESSURE:
+                       if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
+                           val > SCD30_PRESSURE_COMP_MAX_MBAR)
+-                              break;
++                              return -EINVAL;
+                       ret = scd30_command_write(state, CMD_START_MEAS, val);
+                       if (ret)
+-                              break;
++                              return ret;
+                       state->pressure_comp = val;
+-                      break;
++                      return 0;
+               default:
+-                      break;
++                      return -EINVAL;
+               }
+-              break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
+-                      break;
++                      return -EINVAL;
+               /*
+                * Manufacturer does not explicitly specify min/max sensible
+                * values hence check is omitted for simplicity.
+                */
+-              ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++              return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
diff --git a/queue-6.12/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch b/queue-6.12/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
new file mode 100644 (file)
index 0000000..32595b9
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-260589-greg=kroah.com@vger.kernel.org Fri Jun  5 01:49:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 19:49:27 -0400
+Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604234928.2470788-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit ecae2ae606d493cf11457946436335bd0e726663 ]
+
+The reference bit position was ignored when writing the register at the
+probe() function (!!val was used). When such bit is 1, internal voltage
+reference is disabled so that an external one can be used. For
+multi-channel devices, bit 0 of the Internal Reference Setup command
+behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists
+since support for single-channel devices were first introduced.
+
+Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+[ adapted `has_external_vref` to the in-tree equivalent `voltage_uv` variable in the `val =` computation ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c |    6 +++---
+ drivers/iio/dac/ad5686.h |    1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -528,7 +528,7 @@ int ad5686_probe(struct device *dev,
+               break;
+       case AD5686_REGMAP:
+               cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
+-              ref_bit_msk = 0;
++              ref_bit_msk = AD5686_REF_BIT_MSK;
+               break;
+       case AD5693_REGMAP:
+               cmd = AD5686_CMD_CONTROL_REG;
+@@ -540,9 +540,9 @@ int ad5686_probe(struct device *dev,
+               goto error_disable_reg;
+       }
+-      val = (voltage_uv | ref_bit_msk);
++      val = voltage_uv ? ref_bit_msk : 0;
+-      ret = st->write(st, cmd, 0, !!val);
++      ret = st->write(st, cmd, 0, val);
+       if (ret)
+               goto error_disable_reg;
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -46,6 +46,7 @@
+ #define AD5310_REF_BIT_MSK                    BIT(8)
+ #define AD5683_REF_BIT_MSK                    BIT(12)
++#define AD5686_REF_BIT_MSK                    BIT(0)
+ #define AD5693_REF_BIT_MSK                    BIT(12)
+ /**
diff --git a/queue-6.12/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch b/queue-6.12/mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch
new file mode 100644 (file)
index 0000000..a0802d2
--- /dev/null
@@ -0,0 +1,94 @@
+From stable+bounces-260508-greg=kroah.com@vger.kernel.org Thu Jun  4 16:17:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 09:58:16 -0400
+Subject: mm/damon/sysfs-schemes: delete tried region in regions_rmdirs()
+To: stable@vger.kernel.org
+Cc: SeongJae Park <sj@kernel.org>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604135816.3505741-1-sashal@kernel.org>
+
+From: SeongJae Park <sj@kernel.org>
+
+[ Upstream commit 441f92f7d386b85bad16de49db95a307cba048a2 ]
+
+DAMON sysfs maintains the DAMOS tried region directory objects via a
+linked list.  When the user requests refresh of the directories, DAMON
+sysfs removes all the region directories first, and then generate updated
+regions directory on the empty space.  The removal function
+(damon_sysfs_scheme_regions_rm_dirs()) only puts the kobj objects.
+Deletion of the container region object from the linked list is done
+inside the kobj release callback function.
+
+If somehow the callback invocation is delayed, the list will contain
+regions list that gonna be freed.  If the updated region directories
+creation is started in this situation, the list can be corrupted and
+use-after-free can happen.
+
+Because the kobj objects are managed by only DAMON sysfs, the issue cannot
+happen in normal situation.  But, such delays can be made on kernels that
+built with CONFIG_DEBUG_KOBJECT_RELEASE.  On the kernel, the issue can
+indeed be reproduced like below.
+
+    # damo start --damos_action stat
+    # cd /sys/kernel/mm/damon/admin/kdamonds/0/
+    # for i in {1..10}; do echo update_schemes_tried_regions > state; done
+    # dmesg | grep underflow
+    [   89.296152] refcount_t: underflow; use-after-free.
+
+Fix the issue by removing the region object from the list when
+decrementing the reference count.
+
+Also update damos_sysfs_populate_region_dir() to add the region object to
+the list only after the kobject_init_and_add() is success, so that fail of
+kobject_init_and_add() is not leaving the deallocated object on the list.
+
+The issue was discovered [1] by Sashiko.
+
+Link: https://lore.kernel.org/20260518152559.93038-1-sj@kernel.org
+Link: https://lore.kernel.org/20260513011920.119183-1-sj@kernel.org [1]
+Fixes: 9277d0367ba1 ("mm/damon/sysfs-schemes: implement scheme region directory")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.2.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs-schemes.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/mm/damon/sysfs-schemes.c
++++ b/mm/damon/sysfs-schemes.c
+@@ -79,7 +79,6 @@ static void damon_sysfs_scheme_region_re
+       struct damon_sysfs_scheme_region *region = container_of(kobj,
+                       struct damon_sysfs_scheme_region, kobj);
+-      list_del(&region->list);
+       kfree(region);
+ }
+@@ -197,7 +196,7 @@ static void damon_sysfs_scheme_regions_r
+       struct damon_sysfs_scheme_region *r, *next;
+       list_for_each_entry_safe(r, next, &regions->regions_list, list) {
+-              /* release function deletes it from the list */
++              list_del(&r->list);
+               kobject_put(&r->kobj);
+               regions->nr_regions--;
+       }
+@@ -2186,14 +2185,15 @@ static int damon_sysfs_before_damos_appl
+       region = damon_sysfs_scheme_region_alloc(r);
+       if (!region)
+               return 0;
+-      list_add_tail(&region->list, &sysfs_regions->regions_list);
+-      sysfs_regions->nr_regions++;
+       if (kobject_init_and_add(&region->kobj,
+                               &damon_sysfs_scheme_region_ktype,
+                               &sysfs_regions->kobj, "%d",
+                               damon_sysfs_schemes_region_idx++)) {
+               kobject_put(&region->kobj);
++              return 0;
+       }
++      list_add_tail(&region->list, &sysfs_regions->regions_list);
++      sysfs_regions->nr_regions++;
+       return 0;
+ }
diff --git a/queue-6.12/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch b/queue-6.12/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
new file mode 100644 (file)
index 0000000..084a33d
--- /dev/null
@@ -0,0 +1,192 @@
+From stable+bounces-256682-greg=kroah.com@vger.kernel.org Fri May 29 19:55:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:47:59 -0400
+Subject: mm/memory: fix spurious warning when unmapping device-private/exclusive pages
+To: stable@vger.kernel.org
+Cc: "Alistair Popple" <apopple@nvidia.com>, "Arsen Arsenović" <aarsenovic@baylibre.com>, "Balbir Singh" <balbirs@nvidia.com>, "David Hildenbrand" <david@kernel.org>, "Jason Gunthorpe" <jgg@ziepe.ca>, "John Hubbard" <jhubbard@nvidia.com>, "Leon Romanovsky" <leon@kernel.org>, "Liam R. Howlett" <liam@infradead.org>, "Lorenzo Stoakes" <ljs@kernel.org>, "Peter Xu" <peterx@redhat.com>, "Matthew Brost" <matthew.brost@intel.com>, "Michal Hocko" <mhocko@suse.com>, "Mike Rapoport" <rppt@kernel.org>, "Shuah Khan" <shuah@kernel.org>, "Suren Baghdasaryan" <surenb@google.com>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Vlastimil Babka" <vbabka@kernel.org>, "Andrew Morton" <akpm@linux-foundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529174800.1443622-1-sashal@kernel.org>
+
+From: Alistair Popple <apopple@nvidia.com>
+
+[ Upstream commit be3f38d05cc5a7c3f13e51994c5dd043ab604d28 ]
+
+Device private and exclusive entries are only supported for anonymous
+folios.  This condition is tested in __migrate_device_pages() and
+make_device_exclusive() using folio_test_anon().  However the unmap path
+tests this assumption using vma_is_anonymous().
+
+This is wrong because whilst anonymous VMAs can only contain folios where
+folio_test_anon() is true the opposite relation does not hold.  A folio
+for which folio_test_anon() is true does not imply vma_is_anonymous() is
+true.  Such a condition can occur if for example a folio is part of a
+private filebacked mapping.
+
+In this case vma_is_anonymous() is false as the mapping is filebacked, but
+folio_test_anon() may be true, thus permitting devices to migrate the
+folio to device private memory.  This can lead to the following spurious
+warnings during process teardown:
+
+[  772.737706] ------------[ cut here ]------------
+[  772.739201] WARNING: mm/memory.c:1754 at unmap_page_range.cold+0x26/0x18a, CPU#17: hmm-tests/2041
+[  772.742050] Modules linked in: test_hmm nvidia_uvm(O) nvidia(O)
+[  772.743959] CPU: 17 UID: 0 PID: 2041 Comm: hmm-tests Tainted: G        W  O        7.0.0+ #387 PREEMPT(full)
+[  772.747104] Tainted: [W]=WARN, [O]=OOT_MODULE
+[  772.748509] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
+[  772.752117] RIP: 0010:unmap_page_range.cold+0x26/0x18a
+[  772.753780] Code: 7e fe ff ff 48 89 4c 24 78 4c 89 44 24 38 e8 f2 ff b1 00 48 8b 4c 24 78 4c 8b 44 24 38 48 8b 44 24 18 48 83 78 48 00 74 04 90 <0f> 0b 90 48 89 ca b8 ff ff 37 00 48 c1 ea 03 48 c1 e0 2a 80 3c 02
+[  772.759602] RSP: 0018:ffff888112607550 EFLAGS: 00010286
+[  772.761310] RAX: ffff88811bbf4dc0 RBX: dffffc0000000000 RCX: ffffea03e9bfffd8
+[  772.763583] RDX: 1ffff1102377e9c1 RSI: 0000000000000008 RDI: ffff88811bbf4e08
+[  772.765914] RBP: 0000000000000006 R08: ffff8881059f7448 R09: ffffed10224c0e68
+[  772.768184] R10: ffff888112607347 R11: 0000000000000001 R12: 0000000000000001
+[  772.770461] R13: ffffea03e9bfffc0 R14: ffff888112607908 R15: ffffea03e9bfffc0
+[  772.772782] FS:  00007f327caa2780(0000) GS:ffff888427b7d000(0000) knlGS:0000000000000000
+[  772.775328] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  772.777187] CR2: 00007f327ca89000 CR3: 00000001994d5000 CR4: 00000000000006f0
+[  772.779135] Call Trace:
+[  772.779792]  <TASK>
+[  772.780317]  ? dmirror_interval_invalidate+0x1a3/0x290 [test_hmm]
+[  772.781873]  ? vm_normal_page_pud+0x2b0/0x2b0
+[  772.782992]  ? __rwlock_init+0x150/0x150
+[  772.784006]  ? lock_release+0x216/0x2b0
+[  772.785008]  ? __mmu_notifier_invalidate_range_start+0x505/0x6e0
+[  772.786522]  ? lock_release+0x216/0x2b0
+[  772.787498]  ? unmap_single_vma+0xb6/0x210
+[  772.788573]  unmap_vmas+0x27d/0x520
+[  772.789506]  ? unmap_single_vma+0x210/0x210
+[  772.790607]  ? mas_update_gap.part.0+0x620/0x620
+[  772.791834]  unmap_region+0x19e/0x350
+[  772.792769]  ? remove_vma+0x130/0x130
+[  772.793684]  ? mas_alloc_nodes+0x1f2/0x300
+[  772.794730]  vms_complete_munmap_vmas+0x8c1/0xe20
+[  772.795926]  ? unmap_region+0x350/0x350
+[  772.796917]  do_vmi_align_munmap+0x36a/0x4e0
+[  772.798018]  ? lock_release+0x216/0x2b0
+[  772.799024]  ? vma_shrink+0x620/0x620
+[  772.799983]  do_vmi_munmap+0x150/0x2c0
+[  772.800939]  __vm_munmap+0x161/0x2c0
+[  772.801872]  ? expand_downwards+0xd60/0xd60
+[  772.802948]  ? clockevents_program_event+0x1ef/0x540
+[  772.804217]  ? lock_release+0x216/0x2b0
+[  772.805158]  __x64_sys_munmap+0x59/0x80
+[  772.805776]  do_syscall_64+0xfc/0x670
+[  772.806336]  ? irqentry_exit+0xda/0x580
+[  772.806976]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  772.807772] RIP: 0033:0x7f327cbb2717
+[  772.808323] Code: 73 01 c3 48 8b 0d f9 76 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 0b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c9 76 0d 00 f7 d8 64 89 01 48
+[  772.811337] RSP: 002b:00007ffde7f57d38 EFLAGS: 00000202 ORIG_RAX: 000000000000000b
+[  772.812564] RAX: ffffffffffffffda RBX: 00007f327cc9c000 RCX: 00007f327cbb2717
+[  772.813733] RDX: 0000000000000000 RSI: 0000000000400000 RDI: 00007f327c289000
+[  772.814867] RBP: 0000000000421360 R08: 000000000000001a R09: 0000000000000000
+[  772.815991] R10: 0000000000000003 R11: 0000000000000202 R12: 00007ffde7f57d74
+[  772.817121] R13: 00007f327c689010 R14: 0000000000100000 R15: 00007f327c289000
+[  772.818272]  </TASK>
+[  772.818614] irq event stamp: 0
+[  772.819159] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+[  772.820174] hardirqs last disabled at (0): [<ffffffff82a57ab3>] copy_process+0x19f3/0x6440
+[  772.821511] softirqs last  enabled at (0): [<ffffffff82a57b00>] copy_process+0x1a40/0x6440
+[  772.822869] softirqs last disabled at (0): [<0000000000000000>] 0x0
+[  772.823871] ---[ end trace 0000000000000000 ]---
+
+Fix this by using the same check for folio_test_anon() in
+zap_nonpresent_ptes(). Also add a hmm-test case for this.
+
+Link: https://lore.kernel.org/20260501065116.2057242-1-apopple@nvidia.com
+Fixes: 999dad824c39 ("mm/shmem: persist uffd-wp bit across zapping for file-backed")
+Signed-off-by: Alistair Popple <apopple@nvidia.com>
+Reported-by: Arsen Arsenović <aarsenovic@baylibre.com>
+Reviewed-by: Balbir Singh <balbirs@nvidia.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ applied the change in `zap_pte_range()` instead of `zap_nonpresent_ptes()` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory.c                            |    2 -
+ tools/testing/selftests/mm/hmm-tests.c |   50 +++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+), 1 deletion(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1639,7 +1639,7 @@ static unsigned long zap_pte_range(struc
+                        * consider uffd-wp bit when zap. For more information,
+                        * see zap_install_uffd_wp_if_needed().
+                        */
+-                      WARN_ON_ONCE(!vma_is_anonymous(vma));
++                      WARN_ON_ONCE(!folio_test_anon(folio));
+                       rss[mm_counter(folio)]--;
+                       if (is_device_private_entry(entry))
+                               folio_remove_rmap_pte(folio, page, vma);
+--- a/tools/testing/selftests/mm/hmm-tests.c
++++ b/tools/testing/selftests/mm/hmm-tests.c
+@@ -999,6 +999,56 @@ TEST_F(hmm, migrate)
+ }
+ /*
++ * Migrate private file memory to device private memory.
++ */
++TEST_F(hmm, migrate_file_private)
++{
++      struct hmm_buffer *buffer;
++      unsigned long npages;
++      unsigned long size;
++      unsigned long i;
++      int *ptr;
++      int ret;
++      int fd;
++
++      npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
++      ASSERT_NE(npages, 0);
++      size = npages << self->page_shift;
++
++      fd = hmm_create_file(size);
++      ASSERT_GE(fd, 0);
++
++      buffer = malloc(sizeof(*buffer));
++      ASSERT_NE(buffer, NULL);
++
++      buffer->fd = fd;
++      buffer->size = size;
++      buffer->mirror = malloc(size);
++      ASSERT_NE(buffer->mirror, NULL);
++
++      buffer->ptr = mmap(NULL, size,
++                         PROT_READ | PROT_WRITE,
++                         MAP_PRIVATE,
++                         buffer->fd, 0);
++      ASSERT_NE(buffer->ptr, MAP_FAILED);
++
++      /* Initialize buffer in system memory. */
++      for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
++              ptr[i] = i;
++
++      /* Migrate memory to device. */
++      ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
++      ASSERT_EQ(ret, 0);
++      ASSERT_EQ(buffer->cpages, npages);
++
++      /* Check what the device read. */
++      for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
++              ASSERT_EQ(ptr[i], i);
++
++      hmm_buffer_free(buffer);
++}
++
++/*
+  * Migrate anonymous memory to device private memory and fault some of it back
+  * to system memory, then try migrating the resulting mix of system and device
+  * private memory to the device.
diff --git a/queue-6.12/mptcp-cleanup-fallback-dummy-mapping-generation.patch b/queue-6.12/mptcp-cleanup-fallback-dummy-mapping-generation.patch
new file mode 100644 (file)
index 0000000..22d557b
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-256888-greg=kroah.com@vger.kernel.org Sat May 30 13:52:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 07:50:51 -0400
+Subject: mptcp: cleanup fallback dummy mapping generation
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, Geliang Tang <geliang@kernel.org>, Mat Martineau <martineau@kernel.org>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530115052.1973393-1-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 2834f8edd74d5dda368087a654c0e52b141e9893 ]
+
+MPTCP currently access ack_seq outside the msk socket log scope to
+generate the dummy mapping for fallback socket. Soon we are going
+to introduce backlog usage and even for fallback socket the ack_seq
+value will be significantly off outside of the msk socket lock scope.
+
+Avoid relying on ack_seq for dummy mapping generation, using instead
+the subflow sequence number. Note that in case of disconnect() and
+(re)connect() we must ensure that any previous state is re-set.
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Tested-by: Geliang Tang <geliang@kernel.org>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20251121-net-next-mptcp-memcg-backlog-imp-v1-6-1f34b6c1e0b1@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0981f90e1a05 ("mptcp: reset rcv wnd on disconnect")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    3 +++
+ net/mptcp/subflow.c  |    8 +++++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -3369,6 +3369,9 @@ static int mptcp_disconnect(struct sock
+       msk->rcvspace_init = 0;
+       msk->fastclosing = 0;
++      /* for fallback's sake */
++      WRITE_ONCE(msk->ack_seq, 0);
++
+       WRITE_ONCE(sk->sk_shutdown, 0);
+       sk_error_report(sk);
+       return 0;
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -490,6 +490,9 @@ static void subflow_set_remote_key(struc
+       mptcp_crypto_key_sha(subflow->remote_key, NULL, &subflow->iasn);
+       subflow->iasn++;
++      /* for fallback's sake */
++      subflow->map_seq = subflow->iasn;
++
+       WRITE_ONCE(msk->remote_key, subflow->remote_key);
+       WRITE_ONCE(msk->ack_seq, subflow->iasn);
+       WRITE_ONCE(msk->can_ack, true);
+@@ -1415,9 +1418,12 @@ reset:
+       skb = skb_peek(&ssk->sk_receive_queue);
+       subflow->map_valid = 1;
+-      subflow->map_seq = READ_ONCE(msk->ack_seq);
+       subflow->map_data_len = skb->len;
+       subflow->map_subflow_seq = tcp_sk(ssk)->copied_seq - subflow->ssn_offset;
++      subflow->map_seq = __mptcp_expand_seq(subflow->map_seq,
++                                            subflow->iasn +
++                                            TCP_SKB_CB(skb)->seq -
++                                            subflow->ssn_offset - 1);
+       WRITE_ONCE(subflow->data_avail, true);
+       return true;
+ }
diff --git a/queue-6.12/mptcp-do-not-drop-partial-packets.patch b/queue-6.12/mptcp-do-not-drop-partial-packets.patch
new file mode 100644 (file)
index 0000000..f336bb4
--- /dev/null
@@ -0,0 +1,78 @@
+From stable+bounces-256908-greg=kroah.com@vger.kernel.org Sat May 30 16:21:08 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:19:32 -0400
+Subject: mptcp: do not drop partial packets
+To: stable@vger.kernel.org
+Cc: Shardul Bankar <shardul.b@mpiricsoftware.com>, Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530141932.2407122-3-sashal@kernel.org>
+
+From: Shardul Bankar <shardul.b@mpiricsoftware.com>
+
+[ Upstream commit 50c2d91c5dfa0e465826ec1f8dbad9cdc254bd85 ]
+
+When a packet arrives with map_seq < ack_seq < end_seq, the beginning
+of the packet has already been acknowledged but the end contains new
+data. Currently the entire packet is dropped as "old data," forcing
+the sender to retransmit.
+
+Instead, skip the already-acked bytes by adjusting the skb offset and
+enqueue only the new portion. Update bytes_received and ack_seq to
+reflect the new data consumed.
+
+A previous attempt at this fix has been sent by Paolo Abeni [1], but had
+issues [2]: it also added a zero-window check and changed rcv_wnd_sent
+initialization, which caused test regressions. This version addresses
+only the partial packet handling without modifying receive window
+accounting.
+
+Fixes: ab174ad8ef76 ("mptcp: move ooo skbs into msk out of order queue.")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/c9b426a4e163aa3c4fe8b80c79f1a610f47ae7d8.1763075056.git.pabeni@redhat.com [1]
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/600 [2]
+Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
+[pabeni@redhat.com: update map]
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-1-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |   24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -390,12 +390,26 @@ static bool __mptcp_move_skb(struct sock
+               return false;
+       }
+-      /* old data, keep it simple and drop the whole pkt, sender
+-       * will retransmit as needed, if needed.
++      /* Completely old data? */
++      if (!after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) {
++              MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
++              mptcp_drop(sk, skb);
++              return false;
++      }
++
++      /* Partial packet: map_seq < ack_seq < end_seq.
++       * Skip the already-acked bytes and enqueue the new data.
+        */
+-      MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
+-      mptcp_drop(sk, skb);
+-      return false;
++      copy_len = MPTCP_SKB_CB(skb)->end_seq - msk->ack_seq;
++      MPTCP_SKB_CB(skb)->offset += msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;
++      MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq -
++                                    MPTCP_SKB_CB(skb)->map_seq;
++      msk->bytes_received += copy_len;
++      WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len);
++
++      skb_set_owner_r(skb, sk);
++      __skb_queue_tail(&sk->sk_receive_queue, skb);
++      return true;
+ }
+ static void mptcp_stop_rtx_timer(struct sock *sk)
diff --git a/queue-6.12/mptcp-handle-first-subflow-closing-consistently.patch b/queue-6.12/mptcp-handle-first-subflow-closing-consistently.patch
new file mode 100644 (file)
index 0000000..d0daca1
--- /dev/null
@@ -0,0 +1,104 @@
+From stable+bounces-256907-greg=kroah.com@vger.kernel.org Sat May 30 16:21:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:19:31 -0400
+Subject: mptcp: handle first subflow closing consistently
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, Mat Martineau <martineau@kernel.org>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530141932.2407122-2-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 0eeb372deebce6c25b9afc09e35d6c75a744299a ]
+
+Currently, as soon as the PM closes a subflow, the msk stops accepting
+data from it, even if the TCP socket could be still formally open in the
+incoming direction, with the notable exception of the first subflow.
+
+The root cause of such behavior is that code currently piggy back two
+separate semantic on the subflow->disposable bit: the subflow context
+must be released and that the subflow must stop accepting incoming
+data.
+
+The first subflow is never disposed, so it also never stop accepting
+incoming data. Use a separate bit to mark the latter status and set such
+bit in __mptcp_close_ssk() for all subflows.
+
+Beyond making per subflow behaviour more consistent this will also
+simplify the next patch.
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20251121-net-next-mptcp-memcg-backlog-imp-v1-11-1f34b6c1e0b1@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 50c2d91c5dfa ("mptcp: do not drop partial packets")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |   14 +++++++++-----
+ net/mptcp/protocol.h |    3 ++-
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -877,10 +877,10 @@ void mptcp_data_ready(struct sock *sk, s
+       int sk_rbuf, ssk_rbuf;
+       /* The peer can send data while we are shutting down this
+-       * subflow at msk destruction time, but we must avoid enqueuing
++       * subflow at subflow destruction time, but we must avoid enqueuing
+        * more data to the msk receive queue
+        */
+-      if (unlikely(subflow->disposable))
++      if (unlikely(subflow->closing))
+               return;
+       ssk_rbuf = READ_ONCE(ssk->sk_rcvbuf);
+@@ -2514,6 +2514,13 @@ static void __mptcp_close_ssk(struct soc
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       bool dispose_it, need_push = false;
++      /* Do not pass RX data to the msk, even if the subflow socket is not
++       * going to be freed (i.e. even for the first subflow on graceful
++       * subflow close.
++       */
++      lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
++      subflow->closing = 1;
++
+       /* If the first subflow moved to a close state before accept, e.g. due
+        * to an incoming reset or listener shutdown, the subflow socket is
+        * already deleted by inet_child_forget() and the mptcp socket can't
+@@ -2524,7 +2531,6 @@ static void __mptcp_close_ssk(struct soc
+               /* ensure later check in mptcp_worker() will dispose the msk */
+               sock_set_flag(sk, SOCK_DEAD);
+               mptcp_set_close_tout(sk, tcp_jiffies32 - (mptcp_close_timeout(sk) + 1));
+-              lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+               mptcp_subflow_drop_ctx(ssk);
+               goto out_release;
+       }
+@@ -2533,8 +2539,6 @@ static void __mptcp_close_ssk(struct soc
+       if (dispose_it)
+               list_del(&subflow->node);
+-      lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+-
+       if (subflow->send_fastclose && ssk->sk_state != TCP_CLOSE)
+               tcp_set_state(ssk, TCP_CLOSE);
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -537,12 +537,13 @@ struct mptcp_subflow_context {
+               send_infinite_map : 1,
+               remote_key_valid : 1,        /* received the peer key from */
+               disposable : 1,     /* ctx can be free at ulp release time */
++              closing : 1,        /* must not pass rx data to msk anymore */
+               stale : 1,          /* unable to snd/rcv data, do not use for xmit */
+               valid_csum_seen : 1,        /* at least one csum validated */
+               is_mptfo : 1,       /* subflow is doing TFO */
+               close_event_done : 1,       /* has done the post-closed part */
+               mpc_drop : 1,       /* the MPC option has been dropped in a rtx */
+-              __unused : 9;
++              __unused : 8;
+       bool    data_avail;
+       bool    scheduled;
+       bool    pm_listener;        /* a listener managed by the kernel PM? */
diff --git a/queue-6.12/mptcp-introduce-the-mptcp_init_skb-helper.patch b/queue-6.12/mptcp-introduce-the-mptcp_init_skb-helper.patch
new file mode 100644 (file)
index 0000000..47c2872
--- /dev/null
@@ -0,0 +1,119 @@
+From stable+bounces-256906-greg=kroah.com@vger.kernel.org Sat May 30 16:23:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:19:30 -0400
+Subject: mptcp: introduce the mptcp_init_skb helper
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Geliang Tang <geliang@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530141932.2407122-1-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 9a0afe0db46720ce1a009c7dac168aa0584bd732 ]
+
+Factor out all the skb initialization step in a new helper and
+use it. Note that this change moves the MPTCP CB initialization
+earlier: we can do such step as soon as the skb leaves the
+subflow socket receive queues.
+
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Tested-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20250927-net-next-mptcp-rcv-path-imp-v1-4-5da266aa9c1a@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 50c2d91c5dfa ("mptcp: do not drop partial packets")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |   50 +++++++++++++++++++++++++++-----------------------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -321,7 +321,7 @@ end:
+       mptcp_set_owner_r(skb, sk);
+ }
+-static bool mptcp_rmem_schedule(struct sock *sk, struct sock *ssk, int size)
++static bool mptcp_rmem_schedule(struct sock *sk, int size)
+ {
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       int amt, amount;
+@@ -339,27 +339,11 @@ static bool mptcp_rmem_schedule(struct s
+       return true;
+ }
+-static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
+-                           struct sk_buff *skb, unsigned int offset,
+-                           size_t copy_len)
++static void mptcp_init_skb(struct sock *ssk, struct sk_buff *skb, int offset,
++                         int copy_len)
+ {
+-      struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+-      struct sock *sk = (struct sock *)msk;
+-      struct sk_buff *tail;
+-      bool has_rxtstamp;
+-
+-      __skb_unlink(skb, &ssk->sk_receive_queue);
+-
+-      skb_ext_reset(skb);
+-      skb_orphan(skb);
+-
+-      /* try to fetch required memory from subflow */
+-      if (!mptcp_rmem_schedule(sk, ssk, skb->truesize)) {
+-              MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED);
+-              goto drop;
+-      }
+-
+-      has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
++      const struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
++      bool has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
+       /* the skb map_seq accounts for the skb offset:
+        * mptcp_subflow_get_mapped_dsn() is based on the current tp->copied_seq
+@@ -371,6 +355,25 @@ static bool __mptcp_move_skb(struct mptc
+       MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
+       MPTCP_SKB_CB(skb)->cant_coalesce = 0;
++      __skb_unlink(skb, &ssk->sk_receive_queue);
++
++      skb_ext_reset(skb);
++      skb_dst_drop(skb);
++}
++
++static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
++{
++      u64 copy_len = MPTCP_SKB_CB(skb)->end_seq - MPTCP_SKB_CB(skb)->map_seq;
++      struct mptcp_sock *msk = mptcp_sk(sk);
++      struct sk_buff *tail;
++
++      /* try to fetch required memory from subflow */
++      if (!mptcp_rmem_schedule(sk, skb->truesize)) {
++              MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED);
++              mptcp_drop(sk, skb);
++              return false;
++      }
++
+       if (MPTCP_SKB_CB(skb)->map_seq == msk->ack_seq) {
+               /* in sequence */
+               msk->bytes_received += copy_len;
+@@ -391,7 +394,6 @@ static bool __mptcp_move_skb(struct mptc
+        * will retransmit as needed, if needed.
+        */
+       MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
+-drop:
+       mptcp_drop(sk, skb);
+       return false;
+ }
+@@ -720,7 +722,9 @@ static bool __mptcp_move_skbs_from_subfl
+                       if (tp->urg_data)
+                               done = true;
+-                      if (__mptcp_move_skb(msk, ssk, skb, offset, len))
++                      mptcp_init_skb(ssk, skb, offset, len);
++                      skb_orphan(skb);
++                      if (__mptcp_move_skb(sk, skb))
+                               moved += len;
+                       seq += len;
diff --git a/queue-6.12/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch b/queue-6.12/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
new file mode 100644 (file)
index 0000000..013be80
--- /dev/null
@@ -0,0 +1,150 @@
+From stable+bounces-256843-greg=kroah.com@vger.kernel.org Sat May 30 02:57:02 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 20:50:21 -0400
+Subject: mptcp: pm: fix ADD_ADDR timer infinite retry on option space insufficient
+To: stable@vger.kernel.org
+Cc: Li Xiasong <lixiasong1@huawei.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530005022.2387154-1-sashal@kernel.org>
+
+From: Li Xiasong <lixiasong1@huawei.com>
+
+[ Upstream commit 51e398a3b8961b26a8c0a4ba9a777c5339791707 ]
+
+When TCP option space is insufficient (e.g., when sending ADD_ADDR with an
+IPv6 address and port while tcp_timestamps is enabled), the original code
+jumped to out_unlock without clearing the addr_signal flag. This caused
+mptcp_pm_add_timer to keep rescheduling indefinitely, not sending ADD_ADDR,
+preventing subsequent addresses in the endpoint list from being announced.
+
+Handle this case by clearing the ADD_ADDR signal and skipping the matching
+ADD_ADDR retransmission entry. The skip path cancels the matching timer
+(with id check) and advances PM state progression, preserving forward
+progress to subsequent PM work.
+
+This cancellation is inherently best-effort. A concurrent add_timer
+callback may already be running and may acquire pm.lock before the
+cancel path updates entry state. In that case, one final ADD_ADDR
+transmit attempt can still be executed.
+
+Once the cancel path sets entry->retrans_times to ADD_ADDR_RETRANS_MAX,
+the callback-side retrans_times check suppresses further ADD_ADDR
+retransmissions.
+
+Note that when an ADD_ADDR is being prepared, a pure-ACK is queued. On
+the output side, it means that it is fine to skip non-pure-ACK packets,
+when drop_other_suboptions is set: a pure-ACK will be processed soon
+after.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-2-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm.c         |   40 +++++++++++++++++++++++++++++++++-------
+ net/mptcp/pm_netlink.c |   16 +++++++++++++---
+ 2 files changed, 46 insertions(+), 10 deletions(-)
+
+--- a/net/mptcp/pm.c
++++ b/net/mptcp/pm.c
+@@ -334,6 +334,7 @@ bool mptcp_pm_add_addr_signal(struct mpt
+                             struct mptcp_addr_info *addr, bool *echo,
+                             bool *drop_other_suboptions)
+ {
++      bool skip_add_addr = false;
+       int ret = false;
+       u8 add_addr;
+       u8 family;
+@@ -355,24 +356,49 @@ bool mptcp_pm_add_addr_signal(struct mpt
+       }
+       *echo = mptcp_pm_should_add_signal_echo(msk);
+-      port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
+-
+-      family = *echo ? msk->pm.remote.family : msk->pm.local.family;
+-      if (remaining < mptcp_add_addr_len(family, *echo, port))
+-              goto out_unlock;
+-
+       if (*echo) {
+               *addr = msk->pm.remote;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO);
++              port = !!msk->pm.remote.port;
++              family = msk->pm.remote.family;
+       } else {
+               *addr = msk->pm.local;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL);
++              port = !!msk->pm.local.port;
++              family = msk->pm.local.family;
+       }
+-      WRITE_ONCE(msk->pm.addr_signal, add_addr);
++
++      if (remaining < mptcp_add_addr_len(family, *echo, port)) {
++              struct net *net = sock_net((struct sock *)msk);
++
++              if (!*drop_other_suboptions)
++                      goto out_unlock;
++
++              if (*echo) {
++                      MPTCP_INC_STATS(net, MPTCP_MIB_ECHOADDTXDROP);
++              } else {
++                      skip_add_addr = true;
++                      MPTCP_INC_STATS(net, MPTCP_MIB_ADDADDRTXDROP);
++              }
++              goto drop_signal_mark;
++      }
++
+       ret = true;
++drop_signal_mark:
++      WRITE_ONCE(msk->pm.addr_signal, add_addr);
++
+ out_unlock:
+       spin_unlock_bh(&msk->pm.lock);
++
++      /* On pure-ACK option-space exhaustion, stop retrying this ADD_ADDR:
++       * clear the signal bit, cancel the matching retransmission timer, and
++       * let the PM state machine progress.
++       */
++      if (skip_add_addr) {
++              mptcp_pm_del_add_timer(msk, addr, true);
++              mptcp_pm_subflow_established(msk);
++      }
+       return ret;
+ }
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -320,7 +320,13 @@ static void mptcp_pm_add_timer(struct ti
+       spin_lock_bh(&msk->pm.lock);
+-      if (!mptcp_pm_should_add_signal_addr(msk)) {
++      /* The cancel path (mptcp_pm_del_add_timer()) can race with this
++       * callback. Once cancel updates retrans_times to MAX, suppress further
++       * retransmissions here. If this callback acquires pm.lock first, one
++       * final transmit attempt is still possible.
++       */
++      if (entry->retrans_times < ADD_ADDR_RETRANS_MAX &&
++          !mptcp_pm_should_add_signal_addr(msk)) {
+               pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
+               mptcp_pm_announce_addr(msk, &entry->addr, false);
+               mptcp_pm_add_addr_send_ack(msk);
+@@ -368,8 +374,12 @@ mptcp_pm_del_add_timer(struct mptcp_sock
+       /* Note: entry might have been removed by another thread.
+        * We hold rcu_read_lock() to ensure it is not freed under us.
+        */
+-      if (stop_timer)
+-              sk_stop_timer_sync(sk, &entry->add_timer);
++      if (stop_timer) {
++              if (check_id)
++                      sk_stop_timer(sk, &entry->add_timer);
++              else
++                      sk_stop_timer_sync(sk, &entry->add_timer);
++      }
+       rcu_read_unlock();
+       return entry;
diff --git a/queue-6.12/mptcp-reset-rcv-wnd-on-disconnect.patch b/queue-6.12/mptcp-reset-rcv-wnd-on-disconnect.patch
new file mode 100644 (file)
index 0000000..5fa37d3
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-256889-greg=kroah.com@vger.kernel.org Sat May 30 13:52:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 07:50:52 -0400
+Subject: mptcp: reset rcv wnd on disconnect
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530115052.1973393-2-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 0981f90e1a05773a4c29c6e720f5ea1e3c8f1876 ]
+
+If the MPTCP socket fallback to TCP before the MP handshake completion,
+the IASN remain 0, and the rcv_wnd_sent field is not explicitly
+initialized, just incremented over time with the data transfer.
+
+At disconnect time such value is not cleared. If the next connection falls
+back to TCP before the MP handshake completion, the data transfer will
+keep incrementing the receive window end sequence starting from the last
+value used in the previous connection: the announced window will be
+unrelated from the actual receiver buffer size and likely too big.
+
+Address the issue zeroing the field at disconnect time.
+
+Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-4-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -3371,6 +3371,7 @@ static int mptcp_disconnect(struct sock
+       /* for fallback's sake */
+       WRITE_ONCE(msk->ack_seq, 0);
++      atomic64_set(&msk->rcv_wnd_sent, 0);
+       WRITE_ONCE(sk->sk_shutdown, 0);
+       sk_error_report(sk);
diff --git a/queue-6.12/net-hsr-defer-node-table-free-until-after-rcu-readers.patch b/queue-6.12/net-hsr-defer-node-table-free-until-after-rcu-readers.patch
new file mode 100644 (file)
index 0000000..0b06074
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-256827-greg=kroah.com@vger.kernel.org Sat May 30 01:44:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:39:22 -0400
+Subject: net: hsr: defer node table free until after RCU readers
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529233922.1913663-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit aaec7096f9961eb223b5b149abe9495525c205d9 ]
+
+HSR node-list and node-status generic-netlink operations run under
+rcu_read_lock(). They walk hsr->node_db through hsr_get_next_node() and
+hsr_get_node_data(), but RTM_DELLINK teardown removes the same node table
+with plain list_del() and frees each node immediately.
+
+That lets a generic-netlink reader hold a struct hsr_node pointer across
+hsr_dellink(). In a KASAN build, widening the reader window after
+hsr_get_next_node() obtains the node reproduces a slab-use-after-free
+when the reader copies node->macaddress_A; the freeing stack is
+hsr_del_nodes() from hsr_dellink().
+
+Use list_del_rcu() and defer the free through the existing
+hsr_free_node_rcu() callback. This matches the lifetime rule used by the
+HSR prune paths, which already delete nodes with list_del_rcu() and
+call_rcu().
+
+Fixes: b9a1e627405d ("hsr: implement dellink to clean up resources")
+Cc: stable@vger.kernel.org # v5.3+
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/20260513233838.3064715-2-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ replaced `list_del`+`call_rcu(hsr_free_node_rcu)` with `list_del_rcu`+`kfree_rcu(node, rcu_head)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/hsr/hsr_framereg.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -131,8 +131,10 @@ void hsr_del_nodes(struct list_head *nod
+       struct hsr_node *node;
+       struct hsr_node *tmp;
+-      list_for_each_entry_safe(node, tmp, node_db, mac_list)
+-              kfree(node);
++      list_for_each_entry_safe(node, tmp, node_db, mac_list) {
++              list_del_rcu(&node->mac_list);
++              kfree_rcu(node, rcu_head);
++      }
+ }
+ void prp_handle_san_frame(bool san, enum hsr_port_type port,
diff --git a/queue-6.12/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch b/queue-6.12/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
new file mode 100644 (file)
index 0000000..f262886
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-257321-greg=kroah.com@vger.kernel.org Sat May 30 19:13:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 13:03:20 -0400
+Subject: octeontx2-pf: avoid double free of pool->stack on AQ init failure
+To: stable@vger.kernel.org
+Cc: Dawei Feng <dawei.feng@seu.edu.cn>, Zilin Guan <zilin@seu.edu.cn>, Simon Horman <horms@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530170320.3036620-1-sashal@kernel.org>
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 9b244c242bec48b37e82b89787afd6a4c43457e1 ]
+
+otx2_pool_aq_init() frees pool->stack when mailbox sync or retry
+allocation fails, but leaves the pointer unchanged. Later,
+otx2_sq_aura_pool_init() unwinds the partial setup through
+otx2_aura_pool_free(), which frees pool->stack again. The CN20K-specific
+cn20k_pool_aq_init() implementation has the same bug in
+its corresponding error path.
+
+Set pool->stack to NULL immediately after the local free so the shared
+cleanup path does not free the same stack again while cleaning up
+partially initialized pool state.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available. Manual inspection confirms that the bug is still present in
+v7.1-rc3.
+
+Runtime validation was not performed because reproducing this path
+requires OcteonTX2/CN20K hardware.
+
+Fixes: caa2da34fd25 ("octeontx2-pf: Initialize and config queues")
+Fixes: d322fbd17203 ("octeontx2-pf: Initialize cn20k specific aura and pool contexts")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260515151826.1005397-1-dawei.feng@seu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1386,11 +1386,13 @@ int otx2_pool_init(struct otx2_nic *pfvf
+               err = otx2_sync_mbox_msg(&pfvf->mbox);
+               if (err) {
+                       qmem_free(pfvf->dev, pool->stack);
++                      pool->stack = NULL;
+                       return err;
+               }
+               aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox);
+               if (!aq) {
+                       qmem_free(pfvf->dev, pool->stack);
++                      pool->stack = NULL;
+                       return -ENOMEM;
+               }
+       }
diff --git a/queue-6.12/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch b/queue-6.12/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
new file mode 100644 (file)
index 0000000..05ccb21
--- /dev/null
@@ -0,0 +1,113 @@
+From stable+bounces-256791-greg=kroah.com@vger.kernel.org Fri May 29 23:43:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 17:42:44 -0400
+Subject: platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery
+To: stable@vger.kernel.org
+Cc: "Lukas Wunner" <lukas@wunner.de>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529214244.1795477-1-sashal@kernel.org>
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 348ccc754d8939e21ca5956ff45720b81d6e407f ]
+
+After a PCIe Uncorrectable Error has been reported by a device with
+Intel Vendor Specific Extended Capabilities and has been recovered
+through a Secondary Bus Reset, its driver calls intel_vsec_pci_probe()
+to rescan and reinitialize VSECs.
+
+intel_vsec_pci_probe() invokes pcim_enable_device() and thereby adds
+another devm action which calls pcim_disable_device() on driver unbind.
+
+So once the driver unbinds, pcim_disable_device() will be called as many
+times as an Uncorrectable Error occurred, plus one.  This will lead to
+an enable_cnt imbalance on driver unbind.
+
+Additionally, since commit dc957ab6aa05 ("platform/x86/intel/vsec: Add
+private data for per-device data"), a devm_kzalloc() allocation is
+leaked on every Uncorrectable Error.
+
+Avoid by splitting the VSEC rescan out of intel_vsec_pci_probe() into a
+separate helper and calling that on PCIe error recovery.
+
+Fixes: 936874b77dd0 ("platform/x86/intel/vsec: Add PCI error recovery support to Intel PMT")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org  # v6.0+
+Link: https://patch.msgid.link/bd594d09fa866dc51dddc9a447c3b23f9b1402cc.1778736835.git.lukas@wunner.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c |   36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -348,20 +348,10 @@ void intel_vsec_register(struct pci_dev
+ }
+ EXPORT_SYMBOL_NS_GPL(intel_vsec_register, INTEL_VSEC);
+-static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++static int intel_vsec_pci_init(struct pci_dev *pdev,
++                             struct intel_vsec_platform_info *info)
+ {
+-      struct intel_vsec_platform_info *info;
+       bool have_devices = false;
+-      int ret;
+-
+-      ret = pcim_enable_device(pdev);
+-      if (ret)
+-              return ret;
+-
+-      pci_save_state(pdev);
+-      info = (struct intel_vsec_platform_info *)id->driver_data;
+-      if (!info)
+-              return -EINVAL;
+       if (intel_vsec_walk_dvsec(pdev, info))
+               have_devices = true;
+@@ -379,6 +369,23 @@ static int intel_vsec_pci_probe(struct p
+       return 0;
+ }
++static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++{
++      struct intel_vsec_platform_info *info;
++      int ret;
++
++      ret = pcim_enable_device(pdev);
++      if (ret)
++              return ret;
++
++      pci_save_state(pdev);
++      info = (struct intel_vsec_platform_info *)id->driver_data;
++      if (!info)
++              return -EINVAL;
++
++      return intel_vsec_pci_init(pdev, info);
++}
++
+ /* DG1 info */
+ static struct intel_vsec_header dg1_header = {
+       .length = 0x10,
+@@ -467,6 +474,7 @@ static pci_ers_result_t intel_vsec_pci_e
+ static pci_ers_result_t intel_vsec_pci_slot_reset(struct pci_dev *pdev)
+ {
+       struct intel_vsec_device *intel_vsec_dev;
++      struct intel_vsec_platform_info *info;
+       pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT;
+       const struct pci_device_id *pci_dev_id;
+       unsigned long index;
+@@ -489,10 +497,10 @@ static pci_ers_result_t intel_vsec_pci_s
+               devm_release_action(&pdev->dev, intel_vsec_remove_aux,
+                                   &intel_vsec_dev->auxdev);
+       }
+-      pci_disable_device(pdev);
+       pci_restore_state(pdev);
+       pci_dev_id = pci_match_id(intel_vsec_pci_ids, pdev);
+-      intel_vsec_pci_probe(pdev, pci_dev_id);
++      info = (struct intel_vsec_platform_info *)pci_dev_id->driver_data;
++      intel_vsec_pci_init(pdev, info);
+ out:
+       return status;
diff --git a/queue-6.12/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch b/queue-6.12/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch
new file mode 100644 (file)
index 0000000..839a2b4
--- /dev/null
@@ -0,0 +1,321 @@
+From stable+bounces-256847-greg=kroah.com@vger.kernel.org Sat May 30 03:06:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 21:02:19 -0400
+Subject: ring-buffer: Flush and stop persistent ring buffer on panic
+To: stable@vger.kernel.org
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>, Will Deacon <will@kernel.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, Ian Rogers <irogers@google.com>, Catalin Marinas <catalin.marinas@arm.com>, Geert Uytterhoeven <geert@linux-m68k.org>, Steven Rostedt <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530010219.2456798-1-sashal@kernel.org>
+
+From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+
+[ Upstream commit a494d3c8d5392bcdff83c2a593df0c160ff9f322 ]
+
+On real hardware, panic and machine reboot may not flush hardware cache
+to memory. This means the persistent ring buffer, which relies on a
+coherent state of memory, may not have its events written to the buffer
+and they may be lost. Moreover, there may be inconsistency with the
+counters which are used for validation of the integrity of the
+persistent ring buffer which may cause all data to be discarded.
+
+To avoid this issue, stop recording of the ring buffer on panic and
+flush the cache of the ring buffer's memory.
+
+Fixes: e645535a954a ("tracing: Add option to use memmapped memory for trace boot instance")
+Cc: stable@vger.kernel.org
+Cc: Will Deacon <will@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Ian Rogers <irogers@google.com>
+Link: https://patch.msgid.link/177751969602.2136606.12031934362587643488.stgit@mhiramat.tok.corp.google.com
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/alpha/include/asm/Kbuild        |    1 +
+ arch/arc/include/asm/Kbuild          |    1 +
+ arch/arm/include/asm/Kbuild          |    1 +
+ arch/arm64/include/asm/ring_buffer.h |   10 ++++++++++
+ arch/csky/include/asm/Kbuild         |    1 +
+ arch/hexagon/include/asm/Kbuild      |    1 +
+ arch/loongarch/include/asm/Kbuild    |    1 +
+ arch/m68k/include/asm/Kbuild         |    1 +
+ arch/microblaze/include/asm/Kbuild   |    1 +
+ arch/mips/include/asm/Kbuild         |    1 +
+ arch/nios2/include/asm/Kbuild        |    1 +
+ arch/openrisc/include/asm/Kbuild     |    1 +
+ arch/parisc/include/asm/Kbuild       |    1 +
+ arch/powerpc/include/asm/Kbuild      |    1 +
+ arch/riscv/include/asm/Kbuild        |    1 +
+ arch/s390/include/asm/Kbuild         |    1 +
+ arch/sh/include/asm/Kbuild           |    1 +
+ arch/sparc/include/asm/Kbuild        |    1 +
+ arch/um/include/asm/Kbuild           |    1 +
+ arch/x86/include/asm/Kbuild          |    1 +
+ arch/xtensa/include/asm/Kbuild       |    1 +
+ include/asm-generic/ring_buffer.h    |   13 +++++++++++++
+ kernel/trace/ring_buffer.c           |   22 ++++++++++++++++++++++
+ 23 files changed, 65 insertions(+)
+ create mode 100644 arch/arm64/include/asm/ring_buffer.h
+ create mode 100644 include/asm-generic/ring_buffer.h
+
+--- a/arch/alpha/include/asm/Kbuild
++++ b/arch/alpha/include/asm/Kbuild
+@@ -5,3 +5,4 @@ generic-y += agp.h
+ generic-y += asm-offsets.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+--- a/arch/arc/include/asm/Kbuild
++++ b/arch/arc/include/asm/Kbuild
+@@ -5,4 +5,5 @@ generic-y += extable.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
+ generic-y += parport.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+--- a/arch/arm/include/asm/Kbuild
++++ b/arch/arm/include/asm/Kbuild
+@@ -3,6 +3,7 @@ generic-y += early_ioremap.h
+ generic-y += extable.h
+ generic-y += flat.h
+ generic-y += parport.h
++generic-y += ring_buffer.h
+ generated-y += mach-types.h
+ generated-y += unistd-nr.h
+--- /dev/null
++++ b/arch/arm64/include/asm/ring_buffer.h
+@@ -0,0 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++#ifndef _ASM_ARM64_RING_BUFFER_H
++#define _ASM_ARM64_RING_BUFFER_H
++
++#include <asm/cacheflush.h>
++
++/* Flush D-cache on persistent ring buffer */
++#define arch_ring_buffer_flush_range(start, end)      dcache_clean_pop(start, end)
++
++#endif /* _ASM_ARM64_RING_BUFFER_H */
+--- a/arch/csky/include/asm/Kbuild
++++ b/arch/csky/include/asm/Kbuild
+@@ -9,5 +9,6 @@ generic-y += qrwlock.h
+ generic-y += qrwlock_types.h
+ generic-y += qspinlock.h
+ generic-y += parport.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+ generic-y += vmlinux.lds.h
+--- a/arch/hexagon/include/asm/Kbuild
++++ b/arch/hexagon/include/asm/Kbuild
+@@ -5,3 +5,4 @@ generic-y += extable.h
+ generic-y += iomap.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+--- a/arch/loongarch/include/asm/Kbuild
++++ b/arch/loongarch/include/asm/Kbuild
+@@ -9,5 +9,6 @@ generic-y += qrwlock.h
+ generic-y += user.h
+ generic-y += ioctl.h
+ generic-y += mmzone.h
++generic-y += ring_buffer.h
+ generic-y += statfs.h
+ generic-y += param.h
+--- a/arch/m68k/include/asm/Kbuild
++++ b/arch/m68k/include/asm/Kbuild
+@@ -3,4 +3,5 @@ generated-y += syscall_table.h
+ generic-y += extable.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+ generic-y += spinlock.h
+--- a/arch/microblaze/include/asm/Kbuild
++++ b/arch/microblaze/include/asm/Kbuild
+@@ -5,6 +5,7 @@ generic-y += extable.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
+ generic-y += parport.h
++generic-y += ring_buffer.h
+ generic-y += syscalls.h
+ generic-y += tlb.h
+ generic-y += user.h
+--- a/arch/mips/include/asm/Kbuild
++++ b/arch/mips/include/asm/Kbuild
+@@ -12,4 +12,5 @@ generic-y += mcs_spinlock.h
+ generic-y += parport.h
+ generic-y += qrwlock.h
+ generic-y += qspinlock.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+--- a/arch/nios2/include/asm/Kbuild
++++ b/arch/nios2/include/asm/Kbuild
+@@ -5,5 +5,6 @@ generic-y += cmpxchg.h
+ generic-y += extable.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+ generic-y += spinlock.h
+ generic-y += user.h
+--- a/arch/openrisc/include/asm/Kbuild
++++ b/arch/openrisc/include/asm/Kbuild
+@@ -8,4 +8,5 @@ generic-y += spinlock_types.h
+ generic-y += spinlock.h
+ generic-y += qrwlock_types.h
+ generic-y += qrwlock.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+--- a/arch/parisc/include/asm/Kbuild
++++ b/arch/parisc/include/asm/Kbuild
+@@ -4,4 +4,5 @@ generated-y += syscall_table_64.h
+ generic-y += agp.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+--- a/arch/powerpc/include/asm/Kbuild
++++ b/arch/powerpc/include/asm/Kbuild
+@@ -6,4 +6,5 @@ generic-y += agp.h
+ generic-y += kvm_types.h
+ generic-y += mcs_spinlock.h
+ generic-y += qrwlock.h
++generic-y += ring_buffer.h
+ generic-y += early_ioremap.h
+--- a/arch/riscv/include/asm/Kbuild
++++ b/arch/riscv/include/asm/Kbuild
+@@ -11,5 +11,6 @@ generic-y += spinlock.h
+ generic-y += spinlock_types.h
+ generic-y += qrwlock.h
+ generic-y += qrwlock_types.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+ generic-y += vmlinux.lds.h
+--- a/arch/s390/include/asm/Kbuild
++++ b/arch/s390/include/asm/Kbuild
+@@ -8,3 +8,4 @@ generic-y += asm-offsets.h
+ generic-y += kvm_types.h
+ generic-y += mcs_spinlock.h
+ generic-y += mmzone.h
++generic-y += ring_buffer.h
+--- a/arch/sh/include/asm/Kbuild
++++ b/arch/sh/include/asm/Kbuild
+@@ -3,3 +3,4 @@ generated-y += syscall_table.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
+ generic-y += parport.h
++generic-y += ring_buffer.h
+--- a/arch/sparc/include/asm/Kbuild
++++ b/arch/sparc/include/asm/Kbuild
+@@ -4,3 +4,4 @@ generated-y += syscall_table_64.h
+ generic-y += agp.h
+ generic-y += kvm_para.h
+ generic-y += mcs_spinlock.h
++generic-y += ring_buffer.h
+--- a/arch/um/include/asm/Kbuild
++++ b/arch/um/include/asm/Kbuild
+@@ -19,6 +19,7 @@ generic-y += param.h
+ generic-y += parport.h
+ generic-y += percpu.h
+ generic-y += preempt.h
++generic-y += ring_buffer.h
+ generic-y += runtime-const.h
+ generic-y += softirq_stack.h
+ generic-y += switch_to.h
+--- a/arch/x86/include/asm/Kbuild
++++ b/arch/x86/include/asm/Kbuild
+@@ -12,3 +12,4 @@ generated-y += xen-hypercalls.h
+ generic-y += early_ioremap.h
+ generic-y += mcs_spinlock.h
+ generic-y += mmzone.h
++generic-y += ring_buffer.h
+--- a/arch/xtensa/include/asm/Kbuild
++++ b/arch/xtensa/include/asm/Kbuild
+@@ -7,4 +7,5 @@ generic-y += param.h
+ generic-y += parport.h
+ generic-y += qrwlock.h
+ generic-y += qspinlock.h
++generic-y += ring_buffer.h
+ generic-y += user.h
+--- /dev/null
++++ b/include/asm-generic/ring_buffer.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Generic arch dependent ring_buffer macros.
++ */
++#ifndef __ASM_GENERIC_RING_BUFFER_H__
++#define __ASM_GENERIC_RING_BUFFER_H__
++
++#include <linux/cacheflush.h>
++
++/* Flush cache on ring buffer range if needed. Do nothing by default. */
++#define arch_ring_buffer_flush_range(start, end)      do { } while (0)
++
++#endif /* __ASM_GENERIC_RING_BUFFER_H__ */
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -5,6 +5,7 @@
+  * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+  */
+ #include <linux/trace_recursion.h>
++#include <linux/panic_notifier.h>
+ #include <linux/trace_events.h>
+ #include <linux/ring_buffer.h>
+ #include <linux/trace_clock.h>
+@@ -29,6 +30,7 @@
+ #include <linux/oom.h>
+ #include <linux/mm.h>
++#include <asm/ring_buffer.h>
+ #include <asm/local64.h>
+ #include <asm/local.h>
+@@ -549,6 +551,7 @@ struct trace_buffer {
+       unsigned long                   range_addr_start;
+       unsigned long                   range_addr_end;
++      struct notifier_block           flush_nb;
+       long                            last_text_delta;
+       long                            last_data_delta;
+@@ -2316,6 +2319,16 @@ static void rb_free_cpu_buffer(struct ri
+       kfree(cpu_buffer);
+ }
++/* Stop recording on a persistent buffer and flush cache if needed. */
++static int rb_flush_buffer_cb(struct notifier_block *nb, unsigned long event, void *data)
++{
++      struct trace_buffer *buffer = container_of(nb, struct trace_buffer, flush_nb);
++
++      ring_buffer_record_off(buffer);
++      arch_ring_buffer_flush_range(buffer->range_addr_start, buffer->range_addr_end);
++      return NOTIFY_DONE;
++}
++
+ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
+                                        int order, unsigned long start,
+                                        unsigned long end,
+@@ -2421,6 +2434,12 @@ static struct trace_buffer *alloc_buffer
+       mutex_init(&buffer->mutex);
++      /* Persistent ring buffer needs to flush cache before reboot. */
++      if (start && end) {
++              buffer->flush_nb.notifier_call = rb_flush_buffer_cb;
++              atomic_notifier_chain_register(&panic_notifier_list, &buffer->flush_nb);
++      }
++
+       return buffer;
+  fail_free_buffers:
+@@ -2512,6 +2531,9 @@ ring_buffer_free(struct trace_buffer *bu
+ {
+       int cpu;
++      if (buffer->range_addr_start && buffer->range_addr_end)
++              atomic_notifier_chain_unregister(&panic_notifier_list, &buffer->flush_nb);
++
+       cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
+       irq_work_sync(&buffer->irq_work.work);
diff --git a/queue-6.12/rxrpc-fix-data-decrypt-vs-splice-by-copying-data-to-buffer-in-recvmsg.patch b/queue-6.12/rxrpc-fix-data-decrypt-vs-splice-by-copying-data-to-buffer-in-recvmsg.patch
new file mode 100644 (file)
index 0000000..160fd1f
--- /dev/null
@@ -0,0 +1,443 @@
+From stable+bounces-256788-greg=kroah.com@vger.kernel.org Fri May 29 23:42:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 17:42:07 -0400
+Subject: rxrpc: Fix DATA decrypt vs splice() by copying data to buffer in recvmsg
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Hyunwoo Kim <imv4bel@gmail.com>, Simon Horman <horms@kernel.org>, Jiayuan Chen <jiayuan.chen@linux.dev>, linux-afs@lists.infradead.org, Jeffrey Altman <jaltman@auristor.com>, Marc Dionne <marc.dionne@auristor.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529214208.1792984-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit d2bc90cf6c75cb96d2ce549be6c35efa3099d25b ]
+
+This improves the fix for CVE-2026-43500.
+
+Fix the pagecache corruption from in-place decryption of a DATA packet
+transmitted locally by splice() by getting rid of the packet sharing in the
+I/O thread and unconditionally extracting the packet content into a bounce
+buffer in which the buffer is decrypted.  recvmsg() (or the kernel
+equivalent) then copies the data from the bounce buffer to the destination
+buffer.  The sk_buff then remains unmodified.
+
+This has an additional advantage in that the packet is then arranged in the
+buffer with the correct alignment required for the crypto algorithms to
+process directly.  The performance of the crypto does seem to be a little
+faster and, surprisingly, the unencrypted performance doesn't seem to
+change much - possibly due to removing complexity from the I/O thread.
+
+Yet another advantage is that the I/O thread doesn't have to copy packets
+which would slow down packet distribution, ACK generation, etc..
+
+The buffer belongs to the call and is allocated initially at 2K,
+sufficiently large to hold a whole jumbo subpacket, but the buffer will be
+increased in size if needed.  However, to take this work, MSG_PEEK may
+cause a later packet to be decrypted into the buffer, in which case the
+earlier one will need re-decrypting for a subsequent recvmsg().
+
+Note that rx_pkt_offset may legitimately see 0 as a valid offset now, so
+switch to using USHRT_MAX to indicate an invalid offset.
+
+Note also that I would generally prefer to replace the buffers of the
+current sk_buff with a new kmalloc'd buffer of the right size, ditching the
+old data and frags as this makes the handling of MSG_PEEK easier and
+removes the re-decryption issue, but this looks like quite a complicated
+thing to achieve.  skb_morph() looks half way to what I want, but I don't
+want to have to allocate a new sk_buff.
+
+Fixes: d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Closes: https://lore.kernel.org/r/afKV2zGR6rrelPC7@v4bel/
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Simon Horman <horms@kernel.org>
+cc: Jiayuan Chen <jiayuan.chen@linux.dev>
+cc: linux-afs@lists.infradead.org
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+Tested-by: Marc Dionne <marc.dionne@auristor.com>
+Link: https://patch.msgid.link/20260515230516.2718212-3-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 8bfab4b6ffc2 ("rxrpc: Fix RESPONSE packet verification to extract skb to a linear buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/ar-internal.h |    7 ++-
+ net/rxrpc/call_event.c  |   27 +--------------
+ net/rxrpc/call_object.c |    2 +
+ net/rxrpc/insecure.c    |    3 -
+ net/rxrpc/recvmsg.c     |   68 ++++++++++++++++++++++++++++++-------
+ net/rxrpc/rxkad.c       |   86 +++++++++++++++++-------------------------------
+ 6 files changed, 96 insertions(+), 97 deletions(-)
+
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -203,8 +203,6 @@ struct rxrpc_skb_priv {
+               struct {
+                       u16             offset;         /* Offset of data */
+                       u16             len;            /* Length of data */
+-                      u8              flags;
+-#define RXRPC_RX_VERIFIED     0x01
+               };
+               struct {
+                       rxrpc_seq_t     first_ack;      /* First packet in acks table */
+@@ -686,6 +684,11 @@ struct rxrpc_call {
+       /* Received data tracking */
+       struct sk_buff_head     recvmsg_queue;  /* Queue of packets ready for recvmsg() */
+       struct sk_buff_head     rx_oos_queue;   /* Queue of out of sequence packets */
++      void                    *rx_dec_buffer; /* Decryption buffer */
++      unsigned short          rx_dec_bsize;   /* rx_dec_buffer size */
++      unsigned short          rx_dec_offset;  /* Decrypted packet data offset */
++      unsigned short          rx_dec_len;     /* Decrypted packet data len */
++      rxrpc_seq_t             rx_dec_seq;     /* Packet in decryption buffer */
+       rxrpc_seq_t             rx_highest_seq; /* Higest sequence number received */
+       rxrpc_seq_t             rx_consumed;    /* Highest packet consumed */
+--- a/net/rxrpc/call_event.c
++++ b/net/rxrpc/call_event.c
+@@ -342,31 +342,8 @@ bool rxrpc_input_call_event(struct rxrpc
+       if (skb && skb->mark == RXRPC_SKB_MARK_ERROR)
+               goto out;
+-      if (skb) {
+-              struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+-
+-              if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&
+-                  sp->hdr.securityIndex != 0 &&
+-                  (skb_cloned(skb) ||
+-                   skb_has_frag_list(skb) ||
+-                   skb_has_shared_frag(skb))) {
+-                      /* Unshare the packet so that it can be modified for
+-                       * in-place decryption.
+-                       */
+-                      struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
+-
+-                      if (nskb) {
+-                              rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
+-                              rxrpc_input_call_packet(call, nskb);
+-                              rxrpc_free_skb(nskb, rxrpc_skb_put_input);
+-                      } else {
+-                              /* OOM - Drop the packet. */
+-                              rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
+-                      }
+-              } else {
+-                      rxrpc_input_call_packet(call, skb);
+-              }
+-      }
++      if (skb)
++              rxrpc_input_call_packet(call, skb);
+       /* If we see our async-event poke, check for timeout trippage. */
+       now = ktime_get_real();
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -154,6 +154,7 @@ struct rxrpc_call *rxrpc_alloc_call(stru
+       spin_lock_init(&call->tx_lock);
+       refcount_set(&call->ref, 1);
+       call->debug_id          = debug_id;
++      call->rx_pkt_offset     = USHRT_MAX;
+       call->tx_total_len      = -1;
+       call->next_rx_timo      = 20 * HZ;
+       call->next_req_timo     = 1 * HZ;
+@@ -535,6 +536,7 @@ static void rxrpc_cleanup_ring(struct rx
+ {
+       rxrpc_purge_queue(&call->recvmsg_queue);
+       rxrpc_purge_queue(&call->rx_oos_queue);
++      kfree(call->rx_dec_buffer);
+ }
+ /*
+--- a/net/rxrpc/insecure.c
++++ b/net/rxrpc/insecure.c
+@@ -29,9 +29,6 @@ static int none_secure_packet(struct rxr
+ static int none_verify_packet(struct rxrpc_call *call, struct sk_buff *skb)
+ {
+-      struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+-
+-      sp->flags |= RXRPC_RX_VERIFIED;
+       return 0;
+ }
+--- a/net/rxrpc/recvmsg.c
++++ b/net/rxrpc/recvmsg.c
+@@ -143,15 +143,52 @@ static void rxrpc_rotate_rx_window(struc
+ }
+ /*
+- * Decrypt and verify a DATA packet.
++ * Decrypt and verify a DATA packet.  The content of the packet is pulled out
++ * into a flat buffer rather than decrypting in place in the skbuff.  This also
++ * has the advantage of aligning the buffer correctly for the crypto routines.
++ *
++ * We keep track of the sequence number of the packet currently decrypted into
++ * the buffer in ->rx_dec_seq.  If MSG_PEEK is used and steps onto a new
++ * packet, subsequent recvmsg() calls will have to go back and re-decrypt the
++ * current packet.
+  */
+ static int rxrpc_verify_data(struct rxrpc_call *call, struct sk_buff *skb)
+ {
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
++      int ret;
+-      if (sp->flags & RXRPC_RX_VERIFIED)
+-              return 0;
+-      return call->security->verify_packet(call, skb);
++      if (sp->len > call->rx_dec_bsize) {
++              /* Make sure we can hold a 1412-byte jumbo subpacket and make
++               * sure that the buffer size is aligned to a crypto blocksize.
++               */
++              size_t size = clamp(round_up(sp->len, 32), 2048, 65535);
++              void *buffer = krealloc(call->rx_dec_buffer, size, GFP_NOFS);
++
++              if (!buffer)
++                      return -ENOMEM;
++              call->rx_dec_buffer = buffer;
++              call->rx_dec_bsize = size;
++      }
++
++      ret = -EFAULT;
++      if (skb_copy_bits(skb, sp->offset, call->rx_dec_buffer, sp->len) < 0)
++              goto err;
++
++      call->rx_dec_offset = 0;
++      call->rx_dec_len = sp->len;
++      call->rx_dec_seq = sp->hdr.seq;
++      ret = call->security->verify_packet(call, skb);
++      if (ret < 0)
++              goto err;
++      return 0;
++
++err:
++      kfree(call->rx_dec_buffer);
++      call->rx_dec_buffer = NULL;
++      call->rx_dec_bsize = 0;
++      call->rx_dec_offset = 0;
++      call->rx_dec_len = 0;
++      return ret;
+ }
+ /*
+@@ -202,17 +239,22 @@ static int rxrpc_recvmsg_data(struct soc
+               if (msg)
+                       sock_recv_timestamp(msg, sock->sk, skb);
+-              if (rx_pkt_offset == 0) {
++              if (call->rx_dec_seq != sp->hdr.seq ||
++                  !call->rx_dec_buffer) {
+                       ret2 = rxrpc_verify_data(call, skb);
+                       trace_rxrpc_recvdata(call, rxrpc_recvmsg_next, seq,
+-                                           sp->offset, sp->len, ret2);
++                                           call->rx_dec_offset,
++                                           call->rx_dec_len, ret2);
+                       if (ret2 < 0) {
+                               kdebug("verify = %d", ret2);
+                               ret = ret2;
+                               goto out;
+                       }
+-                      rx_pkt_offset = sp->offset;
+-                      rx_pkt_len = sp->len;
++              }
++
++              if (rx_pkt_offset == USHRT_MAX) {
++                      rx_pkt_offset = call->rx_dec_offset;
++                      rx_pkt_len = call->rx_dec_len;
+               } else {
+                       trace_rxrpc_recvdata(call, rxrpc_recvmsg_cont, seq,
+                                            rx_pkt_offset, rx_pkt_len, 0);
+@@ -224,10 +266,10 @@ static int rxrpc_recvmsg_data(struct soc
+               if (copy > remain)
+                       copy = remain;
+               if (copy > 0) {
+-                      ret2 = skb_copy_datagram_iter(skb, rx_pkt_offset, iter,
+-                                                    copy);
+-                      if (ret2 < 0) {
+-                              ret = ret2;
++                      ret2 = copy_to_iter(call->rx_dec_buffer + rx_pkt_offset,
++                                          copy, iter);
++                      if (ret2 != copy) {
++                              ret = -EFAULT;
+                               goto out;
+                       }
+@@ -248,7 +290,7 @@ static int rxrpc_recvmsg_data(struct soc
+               /* The whole packet has been transferred. */
+               if (sp->hdr.flags & RXRPC_LAST_PACKET)
+                       ret = 1;
+-              rx_pkt_offset = 0;
++              rx_pkt_offset = USHRT_MAX;
+               rx_pkt_len = 0;
+               skb = skb_peek_next(skb, &call->recvmsg_queue);
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -414,27 +414,25 @@ static int rxkad_verify_packet_1(struct
+                                rxrpc_seq_t seq,
+                                struct skcipher_request *req)
+ {
+-      struct rxkad_level1_hdr sechdr;
++      struct rxkad_level1_hdr *sechdr;
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+       struct rxrpc_crypt iv;
+-      struct scatterlist sg[16];
+-      u32 data_size, buf;
++      struct scatterlist sg[1];
++      void *data = call->rx_dec_buffer;
++      u32 len = sp->len, data_size, buf;
+       u16 check;
+       int ret;
+       _enter("");
+-      if (sp->len < 8)
++      if (len < 8)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_1_short_header);
+       /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
+        * directly into the target buffer.
+        */
+-      sg_init_table(sg, ARRAY_SIZE(sg));
+-      ret = skb_to_sgvec(skb, sg, sp->offset, 8);
+-      if (unlikely(ret < 0))
+-              return ret;
++      sg_init_one(sg, data, len);
+       /* start the decryption afresh */
+       memset(&iv, 0, sizeof(iv));
+@@ -448,13 +446,11 @@ static int rxkad_verify_packet_1(struct
+               return ret;
+       /* Extract the decrypted packet length */
+-      if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+-              return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+-                                        rxkad_abort_1_short_encdata);
+-      sp->offset += sizeof(sechdr);
+-      sp->len    -= sizeof(sechdr);
++      sechdr = data;
++      call->rx_dec_offset = sizeof(*sechdr);
++      len -= sizeof(*sechdr);
+-      buf = ntohl(sechdr.data_size);
++      buf = ntohl(sechdr->data_size);
+       data_size = buf & 0xffff;
+       check = buf >> 16;
+@@ -463,10 +459,10 @@ static int rxkad_verify_packet_1(struct
+       if (check != 0)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_1_short_check);
+-      if (data_size > sp->len)
++      if (data_size > len)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_1_short_data);
+-      sp->len = data_size;
++      call->rx_dec_len = data_size;
+       _leave(" = 0 [dlen=%x]", data_size);
+       return 0;
+@@ -480,43 +476,28 @@ static int rxkad_verify_packet_2(struct
+                                struct skcipher_request *req)
+ {
+       const struct rxrpc_key_token *token;
+-      struct rxkad_level2_hdr sechdr;
++      struct rxkad_level2_hdr *sechdr;
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+       struct rxrpc_crypt iv;
+-      struct scatterlist _sg[4], *sg;
+-      u32 data_size, buf;
++      struct scatterlist sg[1];
++      void *data = call->rx_dec_buffer;
++      u32 len = sp->len, data_size, buf;
+       u16 check;
+-      int nsg, ret;
++      int ret;
+-      _enter(",{%d}", sp->len);
++      _enter(",{%d}", len);
+-      if (sp->len < 8)
++      if (len < 8)
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_2_short_header);
+       /* Don't let the crypto algo see a misaligned length. */
+-      sp->len = round_down(sp->len, 8);
++      len = round_down(len, 8);
+-      /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
+-       * directly into the target buffer.
++      /* Decrypt in place in the call's decryption buffer.  TODO: We really
++       * want to decrypt directly into the target buffer.
+        */
+-      sg = _sg;
+-      nsg = skb_shinfo(skb)->nr_frags + 1;
+-      if (nsg <= 4) {
+-              nsg = 4;
+-      } else {
+-              sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO);
+-              if (!sg)
+-                      return -ENOMEM;
+-      }
+-
+-      sg_init_table(sg, nsg);
+-      ret = skb_to_sgvec(skb, sg, sp->offset, sp->len);
+-      if (unlikely(ret < 0)) {
+-              if (sg != _sg)
+-                      kfree(sg);
+-              return ret;
+-      }
++      sg_init_one(sg, data, len);
+       /* decrypt from the session key */
+       token = call->conn->key->payload.data[0];
+@@ -524,11 +505,9 @@ static int rxkad_verify_packet_2(struct
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+-      skcipher_request_set_crypt(req, sg, sg, sp->len, iv.x);
++      skcipher_request_set_crypt(req, sg, sg, len, iv.x);
+       ret = crypto_skcipher_decrypt(req);
+       skcipher_request_zero(req);
+-      if (sg != _sg)
+-              kfree(sg);
+       if (ret < 0) {
+               if (ret == -ENOMEM)
+                       return ret;
+@@ -537,13 +516,11 @@ static int rxkad_verify_packet_2(struct
+       }
+       /* Extract the decrypted packet length */
+-      if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+-              return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+-                                        rxkad_abort_2_short_len);
+-      sp->offset += sizeof(sechdr);
+-      sp->len    -= sizeof(sechdr);
++      sechdr = data;
++      call->rx_dec_offset = sizeof(*sechdr);
++      len -= sizeof(*sechdr);
+-      buf = ntohl(sechdr.data_size);
++      buf = ntohl(sechdr->data_size);
+       data_size = buf & 0xffff;
+       check = buf >> 16;
+@@ -553,17 +530,18 @@ static int rxkad_verify_packet_2(struct
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_2_short_check);
+-      if (data_size > sp->len)
++      if (data_size > len)
+               return rxrpc_abort_eproto(call, skb, RXKADDATALEN,
+                                         rxkad_abort_2_short_data);
+-      sp->len = data_size;
++      call->rx_dec_len = data_size;
+       _leave(" = 0 [dlen=%x]", data_size);
+       return 0;
+ }
+ /*
+- * Verify the security on a received packet and the subpackets therein.
++ * Verify the security on a received (sub)packet.  If the packet needs
++ * modifying (e.g. decrypting), it must be copied.
+  */
+ static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb)
+ {
diff --git a/queue-6.12/rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch b/queue-6.12/rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch
new file mode 100644 (file)
index 0000000..37549de
--- /dev/null
@@ -0,0 +1,192 @@
+From stable+bounces-256789-greg=kroah.com@vger.kernel.org Fri May 29 23:42:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 17:42:08 -0400
+Subject: rxrpc: Fix RESPONSE packet verification to extract skb to a linear buffer
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Hyunwoo Kim <imv4bel@gmail.com>, Simon Horman <horms@kernel.org>, Jiayuan Chen <jiayuan.chen@linux.dev>, linux-afs@lists.infradead.org, stable@kernel.org, Jeffrey Altman <jaltman@auristor.com>, Marc Dionne <marc.dionne@auristor.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529214208.1792984-2-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 8bfab4b6ffc2fe92da86300728fc8c3c7ebffb56 ]
+
+This improves the fix for CVE-2026-43500.
+
+Fix the verification of RESPONSE packets to avoid the problem of
+overwriting a RESPONSE packet sent via splice to a local address by
+extracting the contents of the UDP packet into a kmalloc'd linear buffer
+rather than decrypting the data in place in the sk_buff (which may corrupt
+the original buffer).
+
+Fixes: 24481a7f5733 ("rxrpc: Fix conn-level packet handling to unshare RESPONSE packets")
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Closes: https://lore.kernel.org/r/afKV2zGR6rrelPC7@v4bel/
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Simon Horman <horms@kernel.org>
+cc: Jiayuan Chen <jiayuan.chen@linux.dev>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+Tested-by: Marc Dionne <marc.dionne@auristor.com>
+Link: https://patch.msgid.link/20260515230516.2718212-4-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/ar-internal.h |    5 +++--
+ net/rxrpc/conn_event.c  |   30 ++++++++++++------------------
+ net/rxrpc/insecure.c    |    5 +++--
+ net/rxrpc/rxkad.c       |   29 ++++++++++-------------------
+ 4 files changed, 28 insertions(+), 41 deletions(-)
+
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -270,8 +270,9 @@ struct rxrpc_security {
+                                   struct sk_buff *);
+       /* verify a response */
+-      int (*verify_response)(struct rxrpc_connection *,
+-                             struct sk_buff *);
++      int (*verify_response)(struct rxrpc_connection *conn,
++                             struct sk_buff *response_skb,
++                             void *response, unsigned int len);
+       /* clear connection security */
+       void (*clear)(struct rxrpc_connection *);
+--- a/net/rxrpc/conn_event.c
++++ b/net/rxrpc/conn_event.c
+@@ -229,28 +229,22 @@ static void rxrpc_call_is_secure(struct
+ static int rxrpc_verify_response(struct rxrpc_connection *conn,
+                                struct sk_buff *skb)
+ {
++      unsigned int len = skb->len - sizeof(struct rxrpc_wire_header);
++      void *buffer;
+       int ret;
+-      if (skb_cloned(skb) || skb_has_frag_list(skb) ||
+-          skb_has_shared_frag(skb)) {
+-              /* Copy the packet if shared so that we can do in-place
+-               * decryption.
+-               */
+-              struct sk_buff *nskb = skb_copy(skb, GFP_NOFS);
++      buffer = kmalloc(len, GFP_NOFS);
++      if (!buffer)
++              return -ENOMEM;
+-              if (nskb) {
+-                      rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
+-                      ret = conn->security->verify_response(conn, nskb);
+-                      rxrpc_free_skb(nskb, rxrpc_skb_put_response_copy);
+-              } else {
+-                      /* OOM - Drop the packet. */
+-                      rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
+-                      ret = -ENOMEM;
+-              }
+-      } else {
+-              ret = conn->security->verify_response(conn, skb);
+-      }
++      ret = skb_copy_bits(skb, sizeof(struct rxrpc_wire_header), buffer, len);
++      if (ret < 0)
++              goto out;
++      ret = conn->security->verify_response(conn, skb, buffer, len);
++
++out:
++      kfree(buffer);
+       return ret;
+ }
+--- a/net/rxrpc/insecure.c
++++ b/net/rxrpc/insecure.c
+@@ -44,9 +44,10 @@ static int none_respond_to_challenge(str
+ }
+ static int none_verify_response(struct rxrpc_connection *conn,
+-                              struct sk_buff *skb)
++                              struct sk_buff *response_skb,
++                              void *response, unsigned int len)
+ {
+-      return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, -EPROTO,
++      return rxrpc_abort_conn(conn, response_skb, RX_PROTOCOL_ERROR, -EPROTO,
+                               rxrpc_eproto_rxnull_response);
+ }
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -875,7 +875,6 @@ static int rxkad_decrypt_ticket(struct r
+       *_expiry = 0;
+       ASSERT(server_key->payload.data[0] != NULL);
+-      ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
+       memcpy(&iv, &server_key->payload.data[2], sizeof(iv));
+@@ -1024,14 +1023,15 @@ unlock:
+  * verify a response
+  */
+ static int rxkad_verify_response(struct rxrpc_connection *conn,
+-                               struct sk_buff *skb)
++                               struct sk_buff *skb,
++                               void *buffer, unsigned int len)
+ {
+       struct rxkad_response *response;
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
+       struct rxrpc_crypt session_key;
+       struct key *server_key;
+       time64_t expiry;
+-      void *ticket = NULL;
++      void *ticket;
+       u32 version, kvno, ticket_len, level;
+       __be32 csum;
+       int ret, i;
+@@ -1054,13 +1054,8 @@ static int rxkad_verify_response(struct
+               }
+       }
+-      ret = -ENOMEM;
+-      response = kzalloc(sizeof(struct rxkad_response), GFP_NOFS);
+-      if (!response)
+-              goto error;
+-
+-      if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
+-                        response, sizeof(*response)) < 0) {
++      response = buffer;
++      if (len < sizeof(*response)) {
+               ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+                                      rxkad_abort_resp_short);
+               goto error;
+@@ -1072,6 +1067,9 @@ static int rxkad_verify_response(struct
+       trace_rxrpc_rx_response(conn, sp->hdr.serial, version, kvno, ticket_len);
++      buffer  += sizeof(*response);
++      len     -= sizeof(*response);
++
+       if (version != RXKAD_VERSION) {
+               ret = rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
+                                      rxkad_abort_resp_version);
+@@ -1091,13 +1089,8 @@ static int rxkad_verify_response(struct
+       }
+       /* extract the kerberos ticket and decrypt and decode it */
+-      ret = -ENOMEM;
+-      ticket = kmalloc(ticket_len, GFP_NOFS);
+-      if (!ticket)
+-              goto error;
+-
+-      if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header) + sizeof(*response),
+-                        ticket, ticket_len) < 0) {
++      ticket = buffer;
++      if (ticket_len > len) {
+               ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+                                      rxkad_abort_resp_short_tkt);
+               goto error;
+@@ -1177,8 +1170,6 @@ static int rxkad_verify_response(struct
+       ret = rxrpc_get_server_data_key(conn, &session_key, expiry, kvno);
+ error:
+-      kfree(ticket);
+-      kfree(response);
+       key_put(server_key);
+       _leave(" = %d", ret);
+       return ret;
diff --git a/queue-6.12/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch b/queue-6.12/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
new file mode 100644 (file)
index 0000000..1dbda18
--- /dev/null
@@ -0,0 +1,124 @@
+From stable+bounces-260848-greg=kroah.com@vger.kernel.org Sat Jun  6 04:47:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 22:47:23 -0400
+Subject: scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd()
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, John Garry <john.g.garry@oracle.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606024723.2515163-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit 778c2ab142c625a8a8afa570e0f9b7873f445d99 ]
+
+Two latent bugs in the Text-phase handler, both present since the
+original LIO integration in commit e48354ce078c ("iscsi-target: Add
+iSCSI fabric support for target v4.1"):
+
+1) DataDigest CRC buffer overread (4 bytes past text_in).
+
+   text_in is kzalloc()'d at ALIGN(payload_length, 4).  rx_size is then
+   incremented by ISCSI_CRC_LEN to make room for the received DataDigest
+   in the iovec, but the same (now-bumped) rx_size is passed as the
+   buffer length to iscsit_crc_buf():
+
+       if (conn->conn_ops->DataDigest) {
+               ...
+               rx_size += ISCSI_CRC_LEN;
+       }
+       ...
+       if (conn->conn_ops->DataDigest) {
+               data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
+
+   iscsit_crc_buf() walks rx_size bytes of text_in with crc32c(), so
+   when DataDigest is negotiated it reads 4 bytes past the end of the
+   text_in allocation.  KASAN reproduces this directly on the unpatched
+   mainline tree as slab-out-of-bounds in crc32c() called from the Text
+   PDU path.  The OOB bytes feed crc32c() and are then compared against
+   the initiator-supplied checksum, so the value does not flow back to
+   the attacker, but the kernel does read past the buffer on every Text
+   PDU with DataDigest=CRC32C.
+
+   Fix by passing the actual padded payload length
+   (ALIGN(payload_length, 4)) that was used for the kzalloc().
+
+2) Stale cmd->text_in_ptr re-free (double-free) on ERL>0 bad DataDigest
+   drop.
+
+   On DataDigest mismatch with ErrorRecoveryLevel > 0 the handler
+   silently drops the PDU and lets the initiator plug the CmdSN gap:
+
+               kfree(text_in);
+               return 0;
+
+   cmd->text_in_ptr still points at the freed buffer.  The next Text
+   Request on the same ITT re-enters iscsit_setup_text_cmd(), which
+   unconditionally does
+
+       kfree(cmd->text_in_ptr);
+       cmd->text_in_ptr = NULL;
+
+   freeing the same pointer a second time.  Session teardown via
+   iscsit_release_cmd() has the same shape and hits the same double-free
+   if the connection is dropped before a second Text Request arrives.
+
+   On an unmodified mainline tree the bug-1 CRC overread fires first on
+   the initial valid Text Request and perturbs the subsequent state, so
+   #4 was isolated by building a kernel with only the bug-1 hunk of this
+   patch applied plus temporary printk() observability around the three
+   relevant kfree() sites.  The observability prints are not part of
+   this patch.  On that build, a three-PDU Text Request sequence after
+   login produces two back-to-back splats:
+
+       BUG: KASAN: double-free in iscsit_setup_text_cmd+0x??
+       BUG: KASAN: double-free in iscsit_release_cmd+0x??
+
+   showing the same pointer freed in the ERL>0 drop path and again in
+   iscsit_setup_text_cmd() (next Text Request on the same ITT) and once
+   more in iscsit_release_cmd() (session teardown).  On distro kernels
+   with CONFIG_SLAB_FREELIST_HARDENED=y (default) the double-free
+   becomes a remote kernel BUG(); on non-hardened kernels it corrupts
+   the slab freelist.
+
+   Fix by clearing cmd->text_in_ptr after the kfree() in the ERL>0 drop
+   path.  With both hunks applied #4 is directly observable on the stock
+   tree without observability printks; fixing bug-1 alone would mask #4
+   less, not more, so the hunks are submitted together.
+
+Both fixes are one-liners.  The Text PDU state machine is unchanged and
+the wire protocol is unaffected.
+
+Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Tested-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/iscsi/iscsi_target.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -2329,8 +2329,9 @@ iscsit_handle_text_cmd(struct iscsit_con
+               if (conn->conn_ops->DataDigest) {
+                       iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
+-                                                text_in, rx_size, 0, NULL,
+-                                                &data_crc);
++                                                text_in,
++                                                ALIGN(payload_length, 4),
++                                                0, NULL, &data_crc);
+                       if (checksum != data_crc) {
+                               pr_err("Text data CRC32C DataDigest"
+@@ -2350,6 +2351,7 @@ iscsit_handle_text_cmd(struct iscsit_con
+                                       " Command CmdSN: 0x%08x due to"
+                                       " DataCRC error.\n", hdr->cmdsn);
+                                       kfree(text_in);
++                                      cmd->text_in_ptr = NULL;
+                                       return 0;
+                               }
+                       } else {
diff --git a/queue-6.12/selftests-mptcp-drop-nanoseconds-width-specifier.patch b/queue-6.12/selftests-mptcp-drop-nanoseconds-width-specifier.patch
new file mode 100644 (file)
index 0000000..f8202fc
--- /dev/null
@@ -0,0 +1,112 @@
+From stable+bounces-256841-greg=kroah.com@vger.kernel.org Sat May 30 02:30:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 20:25:46 -0400
+Subject: selftests: mptcp: drop nanoseconds width specifier
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530002546.2210747-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 01ff78e4b3d98689184c52d97f9575dfbdc3b10f ]
+
+Using the format specifier +%s%3N with GNU date is honoured, and only
+prints 3 digits of the nanoseconds portion of the seconds since epoch,
+which corresponds to the milliseconds.
+
+The uutils implementation of date currently does not honour this, and
+always prints all 9 digits. This is a known issue [1], but can be worked
+around by adapting this test to use nanoseconds instead of microseconds,
+and then divide it by 1e6.
+
+This fix is similar to what has been done on systemd side [2], and it is
+needed to run the selftests on Ubuntu 26.04, containing uutils 0.8.0.
+
+Note that the Fixes tag is there even if this patch doesn't fix an issue
+in the kernel selftests, but it is useful for those using uutils 0.8.0.
+
+Fixes: 048d19d444be ("mptcp: add basic kselftest for mptcp")
+Cc: stable@vger.kernel.org
+Link: https://github.com/uutils/coreutils/issues/11658 [1]
+Link: https://github.com/systemd/systemd/pull/41627 [2]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-6-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ kept `timeout ${timeout_test}` wrapper in do_transfer() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_connect.sh |    6 +++---
+ tools/testing/selftests/net/mptcp/mptcp_lib.sh     |   10 +++++-----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+@@ -412,7 +412,7 @@ do_transfer()
+       mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}"
+       local start
+-      start=$(date +%s%3N)
++      start=$(date +%s%N)
+       timeout ${timeout_test} \
+               ip netns exec ${connector_ns} \
+                       ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
+@@ -425,7 +425,7 @@ do_transfer()
+       local rets=$?
+       local stop
+-      stop=$(date +%s%3N)
++      stop=$(date +%s%N)
+       if $capture; then
+               sleep 1
+@@ -441,7 +441,7 @@ do_transfer()
+       fi
+       local duration
+-      duration=$((stop-start))
++      duration=$(((stop-start) / 1000000))
+       printf "(duration %05sms) " "${duration}"
+       if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
+               mptcp_lib_pr_fail "client exit code $retc, server $rets"
+--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+@@ -29,7 +29,7 @@ declare -rx MPTCP_LIB_AF_INET6=10
+ MPTCP_LIB_SUBTESTS=()
+ MPTCP_LIB_SUBTESTS_DUPLICATED=0
+ MPTCP_LIB_SUBTEST_FLAKY=0
+-MPTCP_LIB_SUBTESTS_LAST_TS_MS=
++MPTCP_LIB_SUBTESTS_LAST_TS_NS=
+ MPTCP_LIB_TEST_COUNTER=0
+ MPTCP_LIB_TEST_FORMAT="%02u %-50s"
+ MPTCP_LIB_IP_MPTCP=0
+@@ -207,7 +207,7 @@ mptcp_lib_kversion_ge() {
+ }
+ mptcp_lib_subtests_last_ts_reset() {
+-      MPTCP_LIB_SUBTESTS_LAST_TS_MS="$(date +%s%3N)"
++      MPTCP_LIB_SUBTESTS_LAST_TS_NS="$(date +%s%N)"
+ }
+ mptcp_lib_subtests_last_ts_reset
+@@ -226,7 +226,7 @@ __mptcp_lib_result_check_duplicated() {
+ __mptcp_lib_result_add() {
+       local result="${1}"
+       local time="time="
+-      local ts_prev_ms
++      local ts_prev_ns
+       shift
+       local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1))
+@@ -236,9 +236,9 @@ __mptcp_lib_result_add() {
+       # not to add two '#'
+       [[ "${*}" != *"#"* ]] && time="# ${time}"
+-      ts_prev_ms="${MPTCP_LIB_SUBTESTS_LAST_TS_MS}"
++      ts_prev_ns="${MPTCP_LIB_SUBTESTS_LAST_TS_NS}"
+       mptcp_lib_subtests_last_ts_reset
+-      time+="$((MPTCP_LIB_SUBTESTS_LAST_TS_MS - ts_prev_ms))ms"
++      time+="$(((MPTCP_LIB_SUBTESTS_LAST_TS_NS - ts_prev_ns) / 1000000))ms"
+       MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*} ${time}")
+ }
diff --git a/queue-6.12/serdev-provide-a-bustype-shutdown-function.patch b/queue-6.12/serdev-provide-a-bustype-shutdown-function.patch
new file mode 100644 (file)
index 0000000..83fb39c
--- /dev/null
@@ -0,0 +1,88 @@
+From stable+bounces-256738-greg=kroah.com@vger.kernel.org Fri May 29 21:28:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 15:27:54 -0400
+Subject: serdev: Provide a bustype shutdown function
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>, "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529192756.1699014-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit 6d71c62b13c33ea858ab298fe20beaec5736edc7 ]
+
+To prepare serdev driver to migrate away from struct device_driver::shutdown
+(and then eventually remove that callback) create a serdev driver shutdown
+callback and migration code to keep the existing behaviour. Note this
+introduces a warning for each driver at register time that isn't converted
+yet to that callback.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/ab518883e3ed0976a19cb5b5b5faf42bd3a655b7.1765526117.git.u.kleine-koenig@baylibre.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 375ba7484132 ("Bluetooth: hci_qca: Convert timeout from jiffies to ms")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serdev/core.c |   21 +++++++++++++++++++++
+ include/linux/serdev.h    |    1 +
+ 2 files changed, 22 insertions(+)
+
+--- a/drivers/tty/serdev/core.c
++++ b/drivers/tty/serdev/core.c
+@@ -431,11 +431,21 @@ static void serdev_drv_remove(struct dev
+       dev_pm_domain_detach(dev, true);
+ }
++static void serdev_drv_shutdown(struct device *dev)
++{
++      const struct serdev_device_driver *sdrv =
++              to_serdev_device_driver(dev->driver);
++
++      if (dev->driver && sdrv->shutdown)
++              sdrv->shutdown(to_serdev_device(dev));
++}
++
+ static const struct bus_type serdev_bus_type = {
+       .name           = "serial",
+       .match          = serdev_device_match,
+       .probe          = serdev_drv_probe,
+       .remove         = serdev_drv_remove,
++      .shutdown       = serdev_drv_shutdown,
+ };
+ /**
+@@ -832,6 +842,14 @@ void serdev_controller_remove(struct ser
+ }
+ EXPORT_SYMBOL_GPL(serdev_controller_remove);
++static void serdev_legacy_shutdown(struct serdev_device *serdev)
++{
++      struct device *dev = &serdev->dev;
++      struct device_driver *driver = dev->driver;
++
++      driver->shutdown(dev);
++}
++
+ /**
+  * __serdev_device_driver_register() - Register client driver with serdev core
+  * @sdrv:     client driver to be associated with client-device.
+@@ -848,6 +866,9 @@ int __serdev_device_driver_register(stru
+       /* force drivers to async probe so I/O is possible in probe */
+         sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS;
++      if (!sdrv->shutdown && sdrv->driver.shutdown)
++              sdrv->shutdown = serdev_legacy_shutdown;
++
+       return driver_register(&sdrv->driver);
+ }
+ EXPORT_SYMBOL_GPL(__serdev_device_driver_register);
+--- a/include/linux/serdev.h
++++ b/include/linux/serdev.h
+@@ -65,6 +65,7 @@ struct serdev_device_driver {
+       struct device_driver driver;
+       int     (*probe)(struct serdev_device *);
+       void    (*remove)(struct serdev_device *);
++      void    (*shutdown)(struct serdev_device *);
+ };
+ static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d)
index 2699626d3a172479eaab2ba9fb0f72c8806516fa..332f4ae5cf8053cc99983fc61ec23cd527dd5cda 100644 (file)
@@ -265,3 +265,37 @@ xhci-tegra-fix-ghost-usb-device-on-dual-role-port-un.patch
 iommu-skip-pasid-validation-for-devices-without-pasi.patch
 x86-boot-disable-stack-protector-for-early-boot-code.patch
 x86-kexec-disable-kcov-instrumentation-after-load_se.patch
+rxrpc-fix-data-decrypt-vs-splice-by-copying-data-to-buffer-in-recvmsg.patch
+rxrpc-fix-response-packet-verification-to-extract-skb-to-a-linear-buffer.patch
+serdev-provide-a-bustype-shutdown-function.patch
+bluetooth-hci_qca-migrate-to-serdev-specific-shutdown-function.patch
+bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
+alsa-scarlett2-return-enospc-for-out-of-bounds-flash-writes.patch
+alsa-scarlett2-allow-flash-writes-ending-at-segment-boundary.patch
+mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
+platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
+net-hsr-defer-node-table-free-until-after-rcu-readers.patch
+selftests-mptcp-drop-nanoseconds-width-specifier.patch
+mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
+ice-fix-vf-queue-configuration-with-low-mtu-values.patch
+ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch
+mptcp-cleanup-fallback-dummy-mapping-generation.patch
+mptcp-reset-rcv-wnd-on-disconnect.patch
+arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
+octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
+mptcp-introduce-the-mptcp_init_skb-helper.patch
+mptcp-handle-first-subflow-closing-consistently.patch
+mptcp-do-not-drop-partial-packets.patch
+mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch
+iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
+iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
+iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
+alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
+usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
+usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
+usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
+thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
+scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
+usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
+x86-alternatives-rename-apply_relocation-to-text_poke_apply_relocation.patch
+x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch
diff --git a/queue-6.12/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch b/queue-6.12/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
new file mode 100644 (file)
index 0000000..08603d9
--- /dev/null
@@ -0,0 +1,112 @@
+From stable+bounces-260780-greg=kroah.com@vger.kernel.org Fri Jun  5 21:34:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:33:10 -0400
+Subject: thunderbolt: property: Cap recursion depth in __tb_property_parse_dir()
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Mika Westerberg <mika.westerberg@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193310.2159165-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit 928abe19fbf0127003abcb1ea69cabc1c897d0ab ]
+
+A DIRECTORY entry's value field is used as the dir_offset for a
+recursive call into __tb_property_parse_dir() with no depth counter.
+A crafted peer that chains DIRECTORY entries into a back-reference
+loop drives the parser until the kernel stack is exhausted and the
+guard page fires.  Any untrusted XDomain peer (cable, dock, in-line
+inspector, adjacent host) that reaches the PROPERTIES_REQUEST
+control-plane exchange can trigger this without authentication.
+
+Thread a depth counter through tb_property_parse() and
+__tb_property_parse_dir(), and reject blocks that exceed
+TB_PROPERTY_MAX_DEPTH = 8.  That is comfortably larger than any
+observed legitimate XDomain layout.
+
+Operators who do not need XDomain host-to-host discovery can disable
+the path entirely with thunderbolt.xdomain=0 on the kernel command
+line.
+
+Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Assisted-by: Codex:gpt-5-4
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/property.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/thunderbolt/property.c
++++ b/drivers/thunderbolt/property.c
+@@ -35,10 +35,11 @@ struct tb_property_dir_entry {
+ };
+ #define TB_PROPERTY_ROOTDIR_MAGIC     0x55584401
++#define TB_PROPERTY_MAX_DEPTH         8
+ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
+       size_t block_len, unsigned int dir_offset, size_t dir_len,
+-      bool is_root);
++      bool is_root, unsigned int depth);
+ static inline void parse_dwdata(void *dst, const void *src, size_t dwords)
+ {
+@@ -97,7 +98,8 @@ tb_property_alloc(const char *key, enum
+ }
+ static struct tb_property *tb_property_parse(const u32 *block, size_t block_len,
+-                                      const struct tb_property_entry *entry)
++                                      const struct tb_property_entry *entry,
++                                      unsigned int depth)
+ {
+       char key[TB_PROPERTY_KEY_SIZE + 1];
+       struct tb_property *property;
+@@ -118,7 +120,7 @@ static struct tb_property *tb_property_p
+       switch (property->type) {
+       case TB_PROPERTY_TYPE_DIRECTORY:
+               dir = __tb_property_parse_dir(block, block_len, entry->value,
+-                                            entry->length, false);
++                                            entry->length, false, depth + 1);
+               if (!dir) {
+                       kfree(property);
+                       return NULL;
+@@ -163,13 +165,17 @@ static struct tb_property *tb_property_p
+ }
+ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
+-      size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root)
++      size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root,
++      unsigned int depth)
+ {
+       const struct tb_property_entry *entries;
+       size_t i, content_len, nentries;
+       unsigned int content_offset;
+       struct tb_property_dir *dir;
++      if (depth > TB_PROPERTY_MAX_DEPTH)
++              return NULL;
++
+       dir = kzalloc(sizeof(*dir), GFP_KERNEL);
+       if (!dir)
+               return NULL;
+@@ -200,7 +206,7 @@ static struct tb_property_dir *__tb_prop
+       for (i = 0; i < nentries; i++) {
+               struct tb_property *property;
+-              property = tb_property_parse(block, block_len, &entries[i]);
++              property = tb_property_parse(block, block_len, &entries[i], depth);
+               if (!property) {
+                       tb_property_free_dir(dir);
+                       return NULL;
+@@ -237,7 +243,7 @@ struct tb_property_dir *tb_property_pars
+               return NULL;
+       return __tb_property_parse_dir(block, block_len, 0, rootdir->length,
+-                                     true);
++                                     true, 0);
+ }
+ /**
diff --git a/queue-6.12/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch b/queue-6.12/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
new file mode 100644 (file)
index 0000000..68ee684
--- /dev/null
@@ -0,0 +1,95 @@
+From sashal@kernel.org Fri Jun  5 15:53:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 09:53:32 -0400
+Subject: usb: dwc3: xilinx: fix error handling in zynqmp init error paths
+To: stable@vger.kernel.org
+Cc: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>, Thinh Nguyen <Thinh.Nguyen@synopsys.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605135332.930021-1-sashal@kernel.org>
+
+From: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+
+[ Upstream commit c1a0ecbf32c4b397353204e2ec94c5bb9f3300ed ]
+
+Fix error handling and resource cleanup i.e remove invalid
+phy_exit() after failed phy_init(), route failures through
+proper cleanup paths and return 0 explicitly on success.
+
+Fixes: 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
+Cc: stable@vger.kernel.org
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Link: https://patch.msgid.link/20260519115529.2980421-1-radhey.shyam.pandey@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-xilinx.c |   26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-xilinx.c
++++ b/drivers/usb/dwc3/dwc3-xilinx.c
+@@ -170,15 +170,13 @@ static int dwc3_xlnx_init_zynqmp(struct
+       }
+       ret = phy_init(priv_data->usb3_phy);
+-      if (ret < 0) {
+-              phy_exit(priv_data->usb3_phy);
++      if (ret < 0)
+               goto err;
+-      }
+       ret = reset_control_deassert(apbrst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release APB reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       /* Set PIPE Power Present signal in FPD Power Present Register*/
+@@ -190,27 +188,25 @@ static int dwc3_xlnx_init_zynqmp(struct
+       ret = reset_control_deassert(crst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release core reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       ret = reset_control_deassert(hibrst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release hibernation reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       ret = phy_power_on(priv_data->usb3_phy);
+-      if (ret < 0) {
+-              phy_exit(priv_data->usb3_phy);
+-              goto err;
+-      }
++      if (ret < 0)
++              goto err_phy_exit;
+ skip_usb3_phy:
+       /* ulpi reset via gpio-modepin or gpio-framework driver */
+       reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(reset_gpio)) {
+-              return dev_err_probe(dev, PTR_ERR(reset_gpio),
+-                                   "Failed to request reset GPIO\n");
++              ret = PTR_ERR(reset_gpio);
++              goto err_phy_power_off;
+       }
+       if (reset_gpio) {
+@@ -230,6 +226,12 @@ skip_usb3_phy:
+               writel(reg, priv_data->regs + XLNX_USB_TRAFFIC_ROUTE_CONFIG);
+       }
++      return 0;
++
++err_phy_power_off:
++      phy_power_off(priv_data->usb3_phy);
++err_phy_exit:
++      phy_exit(priv_data->usb3_phy);
+ err:
+       return ret;
+ }
diff --git a/queue-6.12/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch b/queue-6.12/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
new file mode 100644 (file)
index 0000000..d0321ba
--- /dev/null
@@ -0,0 +1,54 @@
+From sashal@kernel.org Fri Jun  5 15:57:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 09:57:44 -0400
+Subject: usb: musb: omap2430: Fix use-after-free in omap2430_probe()
+To: stable@vger.kernel.org
+Cc: Wentao Liang <vulab@iscas.ac.cn>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605135745.975090-1-sashal@kernel.org>
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit e194ce048f5a6c549b3a23a8c568c6470f40f772 ]
+
+In omap2430_probe(), of_node_put(np) is called prematurely before the
+last access to np, leading to a use-after-free if the node's reference
+count drops to zero. Move the of_node_put() calls after the last use of
+np in both the success and error paths.
+
+Fixes: ffbe2feac59b ("usb: musb: omap2430: Fix probe regression for missing resources")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260409101104.480623-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/musb/omap2430.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -340,7 +340,6 @@ static int omap2430_probe(struct platfor
+       } else {
+               device_set_of_node_from_dev(&musb->dev, &pdev->dev);
+       }
+-      of_node_put(np);
+       glue->dev                       = &pdev->dev;
+       glue->musb                      = musb;
+@@ -458,6 +457,7 @@ static int omap2430_probe(struct platfor
+               dev_err(&pdev->dev, "failed to register musb device\n");
+               goto err3;
+       }
++      of_node_put(np);
+       return 0;
+@@ -467,6 +467,7 @@ err_put_control_otghs:
+       if (!IS_ERR(glue->control_otghs))
+               put_device(glue->control_otghs);
+ err2:
++      of_node_put(np);
+       platform_device_put(musb);
+ err0:
diff --git a/queue-6.12/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch b/queue-6.12/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
new file mode 100644 (file)
index 0000000..2059d63
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-260765-greg=kroah.com@vger.kernel.org Fri Jun  5 20:32:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 14:31:35 -0400
+Subject: usb: typec: ucsi: Check if power role change actually happened before handling
+To: stable@vger.kernel.org
+Cc: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>, stable <stable@kernel.org>, Sergey Senozhatsky <senozhatsky@chromium.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605183135.2056737-1-sashal@kernel.org>
+
+From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+
+[ Upstream commit b80e7d34c7ea6a564525119d6138fbb577a23dba ]
+
+The CrOS EC may send a connector status change event with the power
+direction changed flag set even if the power direction hasn't actually
+changed after initiating a SET_PDR command internally [1]. In practice
+this happens on every system suspend due to other changes performed by
+the EC [2][3][4], causing suspend to fail.
+
+Fix this by checking if the power role change actually happened before
+handling it.
+
+[1]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=1689;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[2]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=3923;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[3]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=5094;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[4]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=2229;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+
+Cc: stable <stable@kernel.org>
+Fixes: 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change")
+Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+Reported-and-tested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260519-ucsi-fix-2-v1-1-6f1239535187@qtmlabs.xyz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1201,7 +1201,7 @@ static void ucsi_handle_connector_change
+       struct ucsi_connector *con = container_of(work, struct ucsi_connector,
+                                                 work);
+       struct ucsi *ucsi = con->ucsi;
+-      enum typec_role role;
++      enum typec_role role, prev_role;
+       u64 command;
+       int ret;
+@@ -1211,6 +1211,8 @@ static void ucsi_handle_connector_change
+               dev_err_once(ucsi->dev, "%s entered without EVENT_PENDING\n",
+                            __func__);
++      prev_role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
++
+       command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
+       ret = ucsi_send_command_common(ucsi, command, &con->status,
+@@ -1229,7 +1231,7 @@ static void ucsi_handle_connector_change
+       role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
+-      if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) {
++      if ((con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) && role != prev_role) {
+               typec_set_pwr_role(con->port, role);
+               ucsi_port_psy_changed(con);
diff --git a/queue-6.12/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch b/queue-6.12/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
new file mode 100644 (file)
index 0000000..6da4e3f
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-260867-greg=kroah.com@vger.kernel.org Sat Jun  6 14:20:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  6 Jun 2026 08:18:59 -0400
+Subject: usb: typec: ucsi: Don't update power_supply on power role change if not connected
+To: stable@vger.kernel.org
+Cc: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>, stable <stable@kernel.org>, Sergey Senozhatsky <senozhatsky@chromium.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606121900.2851177-1-sashal@kernel.org>
+
+From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+
+[ Upstream commit d98d413ca65d0790a8f3695d0a5845538958ab84 ]
+
+We only need to update the power_supply on power role change if the port
+is connected, because otherwise the online status should be the same for
+both cases.
+
+Cc: stable <stable@kernel.org>
+Fixes: 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change")
+Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+Reported-and-tested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Link: https://patch.msgid.link/20260519-ucsi-fix-2-v1-2-6f1239535187@qtmlabs.xyz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ This is documentation for an already-completed backport. The change is described clearly.
+
+"translated upstream `UCSI_CONSTAT(con, CONNECTED)` accessor macro to in-tree idiom `con->status.flags & UCSI_CONSTAT_CONNECTED`" ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1233,7 +1233,12 @@ static void ucsi_handle_connector_change
+       if ((con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) && role != prev_role) {
+               typec_set_pwr_role(con->port, role);
+-              ucsi_port_psy_changed(con);
++
++              /* Some power_supply properties vary depending on the power direction when
++               * connected
++               */
++              if (con->status.flags & UCSI_CONSTAT_CONNECTED)
++                      ucsi_port_psy_changed(con);
+               /* Complete pending power role swap */
+               if (!completion_done(&con->complete))
diff --git a/queue-6.12/x86-alternatives-rename-apply_relocation-to-text_poke_apply_relocation.patch b/queue-6.12/x86-alternatives-rename-apply_relocation-to-text_poke_apply_relocation.patch
new file mode 100644 (file)
index 0000000..c023390
--- /dev/null
@@ -0,0 +1,98 @@
+From stable+bounces-260869-greg=kroah.com@vger.kernel.org Sat Jun  6 14:20:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  6 Jun 2026 08:19:05 -0400
+Subject: x86/alternatives: Rename 'apply_relocation()' to 'text_poke_apply_relocation()'
+To: stable@vger.kernel.org
+Cc: Ingo Molnar <mingo@kernel.org>, Juergen Gross <jgross@suse.com>, "H . Peter Anvin" <hpa@zytor.com>, Linus Torvalds <torvalds@linux-foundation.org>, Peter Zijlstra <peterz@infradead.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606121906.2851584-1-sashal@kernel.org>
+
+From: Ingo Molnar <mingo@kernel.org>
+
+[ Upstream commit 023f42dd59203be8ad2fc0574af32d3b4ad041ec ]
+
+Join the text_poke_*() API namespace.
+
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: "H . Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250411054105.2341982-52-mingo@kernel.org
+Stable-dep-of: a17dc12bfed8 ("x86/ftrace: Relocate %rip-relative percpu refs in dynamic trampolines")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/text-patching.h |    2 +-
+ arch/x86/kernel/alternative.c        |    6 +++---
+ arch/x86/kernel/callthunks.c         |    6 +++---
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/arch/x86/include/asm/text-patching.h
++++ b/arch/x86/include/asm/text-patching.h
+@@ -15,7 +15,7 @@
+ extern void text_poke_early(void *addr, const void *opcode, size_t len);
+-extern void apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len);
++extern void text_poke_apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len);
+ /*
+  * Clear and restore the kernel write-protection flag on the local CPU.
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -502,7 +502,7 @@ static void __apply_relocation(u8 *buf,
+       }
+ }
+-void apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len)
++void text_poke_apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len)
+ {
+       __apply_relocation(buf, instr, instrlen, repl, repl_len);
+       optimize_nops(instr, buf, instrlen);
+@@ -658,7 +658,7 @@ void __init_or_module noinline apply_alt
+               for (; insn_buff_sz < a->instrlen; insn_buff_sz++)
+                       insn_buff[insn_buff_sz] = 0x90;
+-              apply_relocation(insn_buff, instr, a->instrlen, replacement, a->replacementlen);
++              text_poke_apply_relocation(insn_buff, instr, a->instrlen, replacement, a->replacementlen);
+               DUMP_BYTES(ALT, instr, a->instrlen, "%px:   old_insn: ", instr);
+               DUMP_BYTES(ALT, replacement, a->replacementlen, "%px:   rpl_insn: ", replacement);
+@@ -1865,7 +1865,7 @@ __visible noinline void __init __alt_rel
+ static noinline void __init alt_reloc_selftest(void)
+ {
+       /*
+-       * Tests apply_relocation().
++       * Tests text_poke_apply_relocation().
+        *
+        * This has a relative immediate (CALL) in a place other than the first
+        * instruction and additionally on x86_64 we get a RIP-relative LEA:
+--- a/arch/x86/kernel/callthunks.c
++++ b/arch/x86/kernel/callthunks.c
+@@ -180,7 +180,7 @@ static void *patch_dest(void *dest, bool
+       u8 *pad = dest - tsize;
+       memcpy(insn_buff, skl_call_thunk_template, tsize);
+-      apply_relocation(insn_buff, pad, tsize, skl_call_thunk_template, tsize);
++      text_poke_apply_relocation(insn_buff, pad, tsize, skl_call_thunk_template, tsize);
+       /* Already patched? */
+       if (!bcmp(pad, insn_buff, tsize))
+@@ -302,7 +302,7 @@ static bool is_callthunk(void *addr)
+       pad = (void *)(dest - tmpl_size);
+       memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
+-      apply_relocation(insn_buff, pad, tmpl_size, skl_call_thunk_template, tmpl_size);
++      text_poke_apply_relocation(insn_buff, pad, tmpl_size, skl_call_thunk_template, tmpl_size);
+       return !bcmp(pad, insn_buff, tmpl_size);
+ }
+@@ -320,7 +320,7 @@ int x86_call_depth_emit_accounting(u8 **
+               return 0;
+       memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
+-      apply_relocation(insn_buff, ip, tmpl_size, skl_call_thunk_template, tmpl_size);
++      text_poke_apply_relocation(insn_buff, ip, tmpl_size, skl_call_thunk_template, tmpl_size);
+       memcpy(*pprog, insn_buff, tmpl_size);
+       *pprog += tmpl_size;
diff --git a/queue-6.12/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch b/queue-6.12/x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch
new file mode 100644 (file)
index 0000000..8de983e
--- /dev/null
@@ -0,0 +1,102 @@
+From stable+bounces-260870-greg=kroah.com@vger.kernel.org Sat Jun  6 14:20:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  6 Jun 2026 08:19:06 -0400
+Subject: x86/ftrace: Relocate %rip-relative percpu refs in dynamic trampolines
+To: stable@vger.kernel.org
+Cc: "Alexis Lothoré (eBPF Foundation)" <alexis.lothore@bootlin.com>, "Borislav Petkov (AMD)" <bp@alien8.de>, "Peter Zijlstra (Intel)" <peterz@infradead.org>, "Steven Rostedt" <rostedt@goodmis.org>, stable@kernel.org, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260606121906.2851584-2-sashal@kernel.org>
+
+From: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
+
+[ Upstream commit a17dc12bfed8868e6a86f3b45c16065a70641acb ]
+
+With CONFIG_CALL_DEPTH_TRACKING enabled on an x86 retbleed-affected platform
+(eg: Skylake), with retbleed=stuff, registering a dynamic ftrace trampoline
+crashes on the first call into the traced function:
+
+  BUG: unable to handle page fault for address: ffff88817ae18880
+  #PF: supervisor write access in kernel mode
+  #PF: error_code(0x0002) - not-present page
+  PGD 4b53067 P4D 4b53067 PUD 0
+  Oops: Oops: 0002 [#1] SMP PTI
+  CPU: 3 UID: 0 PID: 187 Comm: usleep Not tainted 7.0.10 #243 PREEMPT(full)
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014
+  Code: 24 78 00 00 00 00 48 89 ea 48 89 54 24 20 48 8b b4 24 b8 00 00 00 48 8b bc 24 b0 00 00 00 48 89 bc 24 80 00 00 00 48 83 ef 05 <65> 48 c1 3d 1f a8 b6 02 05 48 8b 15 f6 00 00 00 4c 89 3c 24 4c 89
+  Call Trace:
+   <TASK>
+   ? find_held_lock
+   ? exc_page_fault
+   ? lock_release
+   ? __x64_sys_clock_nanosleep
+   ? lockdep_hardirqs_on_prepare
+   ? trace_hardirqs_on
+   __x64_sys_clock_nanosleep
+   do_syscall_64
+   ? exc_page_fault
+   ? call_depth_return_thunk
+   entry_SYSCALL_64_after_hwframe
+  ...
+  Kernel panic - not syncing: Fatal exception
+
+This small reproducer allows to easily trigger the crash:
+
+  # echo 'p __x64_sys_clock_nanosleep' > /sys/kernel/tracing/kprobe_events
+  # echo 1 > /sys/kernel/tracing/events/kprobes/p___x64_sys_clock_nanosleep_0/enable
+  # usleep 1
+
+Monitoring the crash under GDB points to the exact instruction in charge of
+incrementing the call depth:
+
+  sarq $5, %gs:__x86_call_depth(%rip)
+
+This instruction matches the one inserted by the ftrace_regs_caller from
+ftrace_64.S. This emitted code was likely working fine until the introduction
+of
+
+  59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()"):
+
+it has made the call depth accounting addressing relative to $rip, instead of
+being based on an absolute address.
+
+As this code exact location depends on where the trampoline lives in memory,
+the corresponding displacement needs to be adjusted at runtime to actually
+correctly find the per-cpu __x86_call_depth value, otherwise the targeted
+address is wrong, leading to the page fault seen above.
+
+Fix the %rip-relative displacement of the copied CALL_DEPTH_ACCOUNT
+instruction (from ftrace_regs_caller) by calling text_poke_apply_relocation(),
+as it is done for example by the x86 BPF JIT compiler through
+x86_call_depth_emit_accounting(). This corrects both CALL_DEPTH_ACCOUNT slots,
+in ftrace_caller and ftrace_regs_caller.
+
+  [ bp: Massage. ]
+
+Fixes: 59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()")
+Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Steven Rostedt <rostedt@goodmis.org>
+Cc: <stable@kernel.org>
+Link: https://patch.msgid.link/20260527-fix_call_depth_in_trampoline-v1-1-1c1abc8ae310@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/ftrace.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -371,6 +371,13 @@ create_trampoline(struct ftrace_ops *ops
+       }
+       /*
++       * Generated trampoline may contain rIP-relative addressing which
++       * displacement needs to be fixed.
++       */
++      text_poke_apply_relocation(trampoline, trampoline, size,
++                                 (void *)start_offset, size);
++
++      /*
+        * The address of the ftrace_ops that is used for this trampoline
+        * is stored at the end of the trampoline. This will be used to
+        * load the third parameter for the callback. Basically, that