--- /dev/null
+From bc11fe4fb6c044fcebd82ed1bfc542b52ba0cd61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index 44eb6faacf44d0..124d2d9ce71605 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From 73f21627da7b212a9763d0935f525f808b4167c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index f1ff204e3ad052..a2ddb692b8f697 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -720,11 +720,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From d9998b0e53afc868b3f72aacd7bded4f2994d215 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 464260f6687082..e9383db1b13a98 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1246,9 +1246,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = &ofdev->dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+@@ -1281,6 +1278,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(&ofdev->dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From d2db6dae7433407ef5753155580c2077b414143e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index e9383db1b13a98..6a7e9aac4814e6 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -443,8 +443,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From db44edab779838378172e678065c800bb2dbceee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 399d0766fd6d4c..26c3b287ac1f6f 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -650,14 +650,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+
+ /* To be picked up by completion functions */
+--
+2.53.0
+
--- /dev/null
+From bb15b867cd93162b4646290c757891cae5c16aab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 15:17:59 +0100
+Subject: ata: sata_dwc_460ex: remove variable num_processed
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit de58fd3d80f884f7f322a06bfe08465e49b47c5d ]
+
+Variable num_processed is just being incremented and it's never used
+anywhere else. The variable and the increment are redundant so
+remove it.
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Stable-dep-of: c2130f6553f4 ("ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 6a7e9aac4814e6..399d0766fd6d4c 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -511,7 +511,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ u8 status, tag;
+- int handled, num_processed, port = 0;
++ int handled, port = 0;
+ uint intpr, sactive, sactive2, tag_mask;
+ struct sata_dwc_device_port *hsdevp;
+ hsdev->sactive_issued = 0;
+@@ -651,9 +651,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+ tag = 0;
+- num_processed = 0;
+ while (tag_mask) {
+- num_processed++;
+ while (!(tag_mask & 0x00000001)) {
+ tag++;
+ tag_mask <<= 1;
+--
+2.53.0
+
--- /dev/null
+From db7073b013f2dfb0a0793096a01ec1edd51c5bb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 756a06f062fdf3..57e41ed899fe1d 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -466,6 +466,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From 68993fdc68c389de854a6a7e03ad6914e6506839 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Dec 2020 10:09:48 +0200
+Subject: btrfs: remove crc_check logic from free space
+
+From: Nikolay Borisov <nborisov@suse.com>
+
+[ Upstream commit 7dbdb443a7b49f66d9c4da0d810e2c54e0727d82 ]
+
+Following removal of the ino cache io_ctl_init will be called only on
+behalf of the freespace inode. In this case we always want to check
+CRCs so conditional code that depended on io_ctl::check_crc can be
+removed.
+
+Signed-off-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: a2d8d5647ed8 ("btrfs: reject free space cache with more entries than pages")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 37 +++++--------------------------------
+ fs/btrfs/free-space-cache.h | 1 -
+ 2 files changed, 5 insertions(+), 33 deletions(-)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index a779965d299054..756a06f062fdf3 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -304,16 +304,11 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode,
+ int write)
+ {
+ int num_pages;
+- int check_crcs = 0;
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+
+- if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FREE_INO_OBJECTID)
+- check_crcs = 1;
+-
+ /* Make sure we can fit our crcs and generation into the first page */
+- if (write && check_crcs &&
+- (num_pages * sizeof(u32) + sizeof(u64)) > PAGE_SIZE)
++ if (write && (num_pages * sizeof(u32) + sizeof(u64)) > PAGE_SIZE)
+ return -ENOSPC;
+
+ memset(io_ctl, 0, sizeof(struct btrfs_io_ctl));
+@@ -324,7 +319,6 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode,
+
+ io_ctl->num_pages = num_pages;
+ io_ctl->fs_info = btrfs_sb(inode->i_sb);
+- io_ctl->check_crcs = check_crcs;
+ io_ctl->inode = inode;
+
+ return 0;
+@@ -419,13 +413,8 @@ static void io_ctl_set_generation(struct btrfs_io_ctl *io_ctl, u64 generation)
+ * Skip the csum areas. If we don't check crcs then we just have a
+ * 64bit chunk at the front of the first page.
+ */
+- if (io_ctl->check_crcs) {
+- io_ctl->cur += (sizeof(u32) * io_ctl->num_pages);
+- io_ctl->size -= sizeof(u64) + (sizeof(u32) * io_ctl->num_pages);
+- } else {
+- io_ctl->cur += sizeof(u64);
+- io_ctl->size -= sizeof(u64) * 2;
+- }
++ io_ctl->cur += (sizeof(u32) * io_ctl->num_pages);
++ io_ctl->size -= sizeof(u64) + (sizeof(u32) * io_ctl->num_pages);
+
+ put_unaligned_le64(generation, io_ctl->cur);
+ io_ctl->cur += sizeof(u64);
+@@ -439,14 +428,8 @@ static int io_ctl_check_generation(struct btrfs_io_ctl *io_ctl, u64 generation)
+ * Skip the crc area. If we don't check crcs then we just have a 64bit
+ * chunk at the front of the first page.
+ */
+- if (io_ctl->check_crcs) {
+- io_ctl->cur += sizeof(u32) * io_ctl->num_pages;
+- io_ctl->size -= sizeof(u64) +
+- (sizeof(u32) * io_ctl->num_pages);
+- } else {
+- io_ctl->cur += sizeof(u64);
+- io_ctl->size -= sizeof(u64) * 2;
+- }
++ io_ctl->cur += sizeof(u32) * io_ctl->num_pages;
++ io_ctl->size -= sizeof(u64) + (sizeof(u32) * io_ctl->num_pages);
+
+ cache_gen = get_unaligned_le64(io_ctl->cur);
+ if (cache_gen != generation) {
+@@ -466,11 +449,6 @@ static void io_ctl_set_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
+- if (!io_ctl->check_crcs) {
+- io_ctl_unmap_page(io_ctl);
+- return;
+- }
+-
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+@@ -488,11 +466,6 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
+- if (!io_ctl->check_crcs) {
+- io_ctl_map_page(io_ctl, 0);
+- return 0;
+- }
+-
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
+index e3d5e0ad8f8e4e..d8c2f3df5a0666 100644
+--- a/fs/btrfs/free-space-cache.h
++++ b/fs/btrfs/free-space-cache.h
+@@ -76,7 +76,6 @@ struct btrfs_io_ctl {
+ int num_pages;
+ int entries;
+ int bitmaps;
+- unsigned check_crcs:1;
+ };
+
+ struct inode *lookup_free_space_inode(struct btrfs_block_group *block_group,
+--
+2.53.0
+
--- /dev/null
+From a0d9f2c16b48486f847fb6162710cd0ef1b9e418 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 9f77a730be4847..21a4a4b10fc080 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -346,6 +346,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -354,8 +366,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -1998,8 +2009,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From e47cbbd752afe98e290483c7e0896960adfb6c1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index da21d2a10cc942..9aa7040e295ede 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -232,7 +232,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From de24d3e7bc2a092c61512e190ad3d15387a78ffd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index 6180a47c1b5114..9ec66ef774cf56 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -17,9 +17,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -29,9 +29,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 49450c4b687db51b5aae1afaeb8370cf85edda32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 66196b293b6c2a..99887349de2383 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -594,9 +594,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 1cc0743acdf531b7b04e64e378635a6e8382c644 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index e38ae4ac454f6b..10d29167b585c0 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1783,6 +1783,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ &mad_send_wr->mad_agent_priv->done_list);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -1801,6 +1819,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From e2d61b96d4ed8de0eae8f4bad66afc5378f6bad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 5c75591bcce003..5c061dffc3795f 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1340,7 +1340,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From ae6f1f99a124ea98776cb17334c8503b50e3398d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Dec 2020 00:11:55 -0300
+Subject: mac80211_hwsim: add 6GHz channels
+
+From: Ramon Fontes <ramonreisfontes@gmail.com>
+
+[ Upstream commit 28881922abd786a1e62a4ca77394a84373dd5279 ]
+
+Advertise 6GHz channels to mac80211.
+
+Signed-off-by: Ramon Fontes <ramonreisfontes@gmail.com>
+Link: https://lore.kernel.org/r/20201227031155.81161-1-ramonreisfontes@gmail.com
+[reword commit message]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 10a2b430f8f0 ("wifi: mac80211_hwsim: clamp virtio RX length before skb_put")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mac80211_hwsim.c | 74 ++++++++++++++++++++++++++-
+ 1 file changed, 73 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 865bbe0293436c..d8b997859de063 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -311,6 +311,12 @@ static struct net_device *hwsim_mon; /* global monitor netdev */
+ .hw_value = (_freq), \
+ }
+
++#define CHAN6G(_freq) { \
++ .band = NL80211_BAND_6GHZ, \
++ .center_freq = (_freq), \
++ .hw_value = (_freq), \
++}
++
+ static const struct ieee80211_channel hwsim_channels_2ghz[] = {
+ CHAN2G(2412), /* Channel 1 */
+ CHAN2G(2417), /* Channel 2 */
+@@ -377,6 +383,68 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] = {
+ CHAN5G(5925), /* Channel 185 */
+ };
+
++static const struct ieee80211_channel hwsim_channels_6ghz[] = {
++ CHAN6G(5955), /* Channel 1 */
++ CHAN6G(5975), /* Channel 5 */
++ CHAN6G(5995), /* Channel 9 */
++ CHAN6G(6015), /* Channel 13 */
++ CHAN6G(6035), /* Channel 17 */
++ CHAN6G(6055), /* Channel 21 */
++ CHAN6G(6075), /* Channel 25 */
++ CHAN6G(6095), /* Channel 29 */
++ CHAN6G(6115), /* Channel 33 */
++ CHAN6G(6135), /* Channel 37 */
++ CHAN6G(6155), /* Channel 41 */
++ CHAN6G(6175), /* Channel 45 */
++ CHAN6G(6195), /* Channel 49 */
++ CHAN6G(6215), /* Channel 53 */
++ CHAN6G(6235), /* Channel 57 */
++ CHAN6G(6255), /* Channel 61 */
++ CHAN6G(6275), /* Channel 65 */
++ CHAN6G(6295), /* Channel 69 */
++ CHAN6G(6315), /* Channel 73 */
++ CHAN6G(6335), /* Channel 77 */
++ CHAN6G(6355), /* Channel 81 */
++ CHAN6G(6375), /* Channel 85 */
++ CHAN6G(6395), /* Channel 89 */
++ CHAN6G(6415), /* Channel 93 */
++ CHAN6G(6435), /* Channel 97 */
++ CHAN6G(6455), /* Channel 181 */
++ CHAN6G(6475), /* Channel 105 */
++ CHAN6G(6495), /* Channel 109 */
++ CHAN6G(6515), /* Channel 113 */
++ CHAN6G(6535), /* Channel 117 */
++ CHAN6G(6555), /* Channel 121 */
++ CHAN6G(6575), /* Channel 125 */
++ CHAN6G(6595), /* Channel 129 */
++ CHAN6G(6615), /* Channel 133 */
++ CHAN6G(6635), /* Channel 137 */
++ CHAN6G(6655), /* Channel 141 */
++ CHAN6G(6675), /* Channel 145 */
++ CHAN6G(6695), /* Channel 149 */
++ CHAN6G(6715), /* Channel 153 */
++ CHAN6G(6735), /* Channel 157 */
++ CHAN6G(6755), /* Channel 161 */
++ CHAN6G(6775), /* Channel 165 */
++ CHAN6G(6795), /* Channel 169 */
++ CHAN6G(6815), /* Channel 173 */
++ CHAN6G(6835), /* Channel 177 */
++ CHAN6G(6855), /* Channel 181 */
++ CHAN6G(6875), /* Channel 185 */
++ CHAN6G(6895), /* Channel 189 */
++ CHAN6G(6915), /* Channel 193 */
++ CHAN6G(6935), /* Channel 197 */
++ CHAN6G(6955), /* Channel 201 */
++ CHAN6G(6975), /* Channel 205 */
++ CHAN6G(6995), /* Channel 209 */
++ CHAN6G(7015), /* Channel 213 */
++ CHAN6G(7035), /* Channel 217 */
++ CHAN6G(7055), /* Channel 221 */
++ CHAN6G(7075), /* Channel 225 */
++ CHAN6G(7095), /* Channel 229 */
++ CHAN6G(7115), /* Channel 233 */
++};
++
+ #define NUM_S1G_CHANS_US 51
+ static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US];
+
+@@ -548,6 +616,7 @@ struct mac80211_hwsim_data {
+ struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
+ struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
+ struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
++ struct ieee80211_channel channels_6ghz[ARRAY_SIZE(hwsim_channels_6ghz)];
+ struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)];
+ struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
+ struct ieee80211_iface_combination if_combination;
+@@ -579,7 +648,8 @@ struct mac80211_hwsim_data {
+ struct ieee80211_channel *channel;
+ unsigned long next_start, start, end;
+ } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
+- ARRAY_SIZE(hwsim_channels_5ghz)];
++ ARRAY_SIZE(hwsim_channels_5ghz) +
++ ARRAY_SIZE(hwsim_channels_6ghz)];
+
+ struct ieee80211_channel *channel;
+ u64 beacon_int /* beacon interval in us */;
+@@ -3187,6 +3257,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
+ sizeof(hwsim_channels_2ghz));
+ memcpy(data->channels_5ghz, hwsim_channels_5ghz,
+ sizeof(hwsim_channels_5ghz));
++ memcpy(data->channels_6ghz, hwsim_channels_6ghz,
++ sizeof(hwsim_channels_6ghz));
+ memcpy(data->channels_s1g, hwsim_channels_s1g,
+ sizeof(hwsim_channels_s1g));
+ memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
+--
+2.53.0
+
--- /dev/null
+From 6c3cbd6d609adaf9dd29fbf1150c3d0452a60f85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index fa095bc8b0c1a6..66f498667ed892 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2144,6 +2144,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From a3f9d3ce72d863659db2c3f84bde91247f1a5e43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 58eefa43af1414..bd4ac120996243 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1264,7 +1265,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1465,6 +1467,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From 3b5dd720c4057885d45ad10f1f90e5a2614027ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/mtk_ecc.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c
+index c115e03ede889b..c60e04cdf03a52 100644
+--- a/drivers/mtd/nand/raw/mtk_ecc.c
++++ b/drivers/mtd/nand/raw/mtk_ecc.c
+@@ -116,8 +116,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -129,6 +129,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -302,7 +304,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -402,7 +408,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 806f2fc640f7518186a209ab490e51f51ec63989 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 8c08f07ce46551..3fb93840ec91bb 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2083,6 +2083,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2132,6 +2134,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 3386833633a737894fb34a2591ef0688e7f15b51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 0d90349636f0e7..5a28adcd370a6a 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -343,14 +343,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 242ebd8a38542a82dea78edcb41005dbeffde34a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 570a1bc24fd5a7..f36ea9141c7a1a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -896,7 +896,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From 76d45000694b09cdeea7c22adbf78e6b59827e30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 8d058b50f1386b..85ed2b59ffe71d 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -318,7 +318,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
input-ims-pcu-fix-heap-buffer-overflow-in-ims_pcu_pr.patch
input-ims-pcu-fix-logic-error-in-packet-reset.patch
kvm-vmx-make-vmread_error_trampoline-uncallable-from.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-remove-crc_check-logic-from-free-space.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+mac80211_hwsim-add-6ghz-channels.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-remove-variable-num_processed.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+can-j1939-fix-lockless-local-destination-check.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From fd10d0996d7023d5844521f4e7e7f5d14a1c7d86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index bd4ea48e057613..51f8ea0c890658 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -3553,6 +3553,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3589,13 +3590,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3612,11 +3621,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 512efeeb06f60e7eee2e71636fe977069bb211a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 6ac2132c306478..5338d93e5b2299 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4438,6 +4438,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4451,7 +4452,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From d945d27ee0b2a1e2c31ae847457fb893c0320559 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 2b64bf73cbcf0a..7d0ddc467232a0 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -240,7 +240,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From da8afebc6c9b5272315951354287906a4641669d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 4e636a07c1e1b4..19a1b256fc0ecf 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -116,6 +116,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -124,6 +125,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From e72a1cf9f3fc9d0bf9e44b36c99d9b55bc1c7a26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 33e2c29fbd3fde..3b2a70b467de9e 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -280,7 +280,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 6ea21f13db07299d8d5eefc58e1fdc7b7c7b6834 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 7503c7dd71ab5e..4e636a07c1e1b4 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -168,6 +168,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -220,6 +221,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -229,10 +238,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 0089396684d1eee1e6b9dfb713667556aa3b9252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 23fbddd0c1f8e0..a46ecfa07ba2b9 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6183,6 +6183,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6195,16 +6197,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From 97762a32a263f0acdc4db5275440f22444d97673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From cc5bad66b2b2a16bf276656aed319a77b3a37f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 644eabaf10e31e..9abec4f929ca0a 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -492,6 +492,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -499,10 +500,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From 807fcddcb05fe17336045e90e6d80ae5d9be958f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index d8b997859de063..02c31f7fcfd13c 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -4335,6 +4335,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From 0da27e73f307343b5fe2ce88487a25bd239ecdde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 6333b1000f925b..303badbd53d9b0 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -503,11 +503,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 049bf23bac19b5ecc622a5dfa9adf920086b10fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 37c4128e313cb2..26bc0821395507 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1292,8 +1292,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 5d4655fddc5b8b52529a3dc8ca7c683b9159ed12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index acfad876362772..9cb0e24004db60 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1947,6 +1947,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
+--
+2.53.0
+
--- /dev/null
+From 1de03092214f4067c593daa46beccc2198b117ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index 2fb30f89bf7a2c..515310e8eae79b 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From 5f06e23a0b4502c5ec24568f34c7335a45a13a9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index 10302552195e17..8ee40e584c0501 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -719,11 +719,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From ab7cc0fbdd35dec88ba1574585aeb21161ba46f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 29e2b0dfba3096..dc9d91eacac82e 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1256,9 +1256,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = &ofdev->dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+@@ -1291,6 +1288,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(&ofdev->dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From 4c93fa8d3cfa9efa6dca830917397729b5f7b8d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index dc9d91eacac82e..0023b232aeca2f 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -443,8 +443,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From 5b74bba0f41066ae63323d5bb3103003d2b385c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 98c91c89a3b336..1692c29227a024 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -655,14 +655,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+ if (unlikely(!qc)) {
+ dev_err(ap->dev, "failed to get qc");
+--
+2.53.0
+
--- /dev/null
+From 3c90e66701e829e7b45b5de1c631ffefdbf1b089 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 15:17:59 +0100
+Subject: ata: sata_dwc_460ex: remove variable num_processed
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit de58fd3d80f884f7f322a06bfe08465e49b47c5d ]
+
+Variable num_processed is just being incremented and it's never used
+anywhere else. The variable and the increment are redundant so
+remove it.
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Stable-dep-of: c2130f6553f4 ("ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 0023b232aeca2f..98c91c89a3b336 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -511,7 +511,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ u8 status, tag;
+- int handled, num_processed, port = 0;
++ int handled, port = 0;
+ uint intpr, sactive, sactive2, tag_mask;
+ struct sata_dwc_device_port *hsdevp;
+ hsdev->sactive_issued = 0;
+@@ -656,9 +656,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+ tag = 0;
+- num_processed = 0;
+ while (tag_mask) {
+- num_processed++;
+ while (!(tag_mask & 0x00000001)) {
+ tag++;
+ tag_mask <<= 1;
+--
+2.53.0
+
--- /dev/null
+From 54a36dafdfb3f7e245d57694bcceca251e39d654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 25e98ce4a5af98..142d61abb137fd 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -352,7 +352,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From 737cd72277a7a44f8110808611b4ba0522d5d876 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index e66ec0c23153ea..2c4130c3120175 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -2047,6 +2047,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From 86ee5eb18aae835eae7aa9e11aa7c6dc9fd07ee3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index ed8729c990883b..3ffcb6217b530f 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -528,6 +528,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From f20136e2b53fe2458a4bb9e4c063be6e413b4b84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index e17a166a73c422..57d7b14c3949e6 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -350,6 +350,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -358,8 +370,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2021,8 +2032,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From c3458c9bda2521377baa7d28714cfbe2a9fd0047 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index 8f8bea08e734d3..04fced8e9d367f 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -235,7 +235,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From 0b9eeff7aebf90212572d62c98b52a06fa5ce60e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index b9441217ca3d4d..f8f66beca5340b 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -15,9 +15,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -27,9 +27,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From bfeb6c11124e01bbdc0c1e491e2f791cae515992 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 34351f8c4d6f36..2f8c95d9362f44 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -558,7 +558,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From 6355b173b4f9be30acab6460a6cc6e676fe8a1ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 4782b115e6ec51..1bc715fe3968c3 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -595,9 +595,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 8609e8db5b61e1fd494bb538c12b0800ba669c98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 242434c09e8d8f..bddb1c607aff62 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1778,6 +1778,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ &mad_send_wr->mad_agent_priv->done_list);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -1796,6 +1814,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From ba1ddc885f55c5e084ae624b6459ecb03a5b08ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 3f43851f87e392..03dac903d96baa 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1384,7 +1384,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From bee2f325e0b26bddb545c15a91a1992093a81237 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ksmbd/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c
+index 9e54ecc9d4adac..8d7368ccda85dc 100644
+--- a/fs/ksmbd/smb2misc.c
++++ b/fs/ksmbd/smb2misc.c
+@@ -399,6 +399,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From d0202c13939e1b8854f4881be7e53fe156aad314 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index b111778bcc3547..bd84c9ddb006d6 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2145,6 +2145,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From 57f9268989f7968ee9650bd93922ad1504bf6305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 7e309270ddd402..e890b5ec6a72f4 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1263,7 +1264,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1464,6 +1466,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From 275832697c94c66a4edb50aef2596cf43213442c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/mtk_ecc.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c
+index ec9d1fb07006fc..ec10e942bed2d7 100644
+--- a/drivers/mtd/nand/raw/mtk_ecc.c
++++ b/drivers/mtd/nand/raw/mtk_ecc.c
+@@ -116,8 +116,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -129,6 +129,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -302,7 +304,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -402,7 +408,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 93d0e59ca9050103039402bf5e813fbea076b1dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 3188d719a2e42d..4156e69496b67e 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2084,6 +2084,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2133,6 +2135,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 949963854b3bb1fa957accb9ab9f9be36a544ea1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index c79f23367dfb3e..0be95240b939e3 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -342,14 +342,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 0510cc48135b7bc49bddc8a93b5862bf98dc6035 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Oct 2022 20:56:53 +1000
+Subject: powerpc: remove the last remnants of cputime_t
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit f985adaf2ff934ec869b32ca1f7f97e2825e3a49 ]
+
+cputime_t was a core kernel type, removed by commits
+ed5c8c854f2b..b672592f0221. As explained in commit b672592f0221
+("sched/cputime: Remove generic asm headers"), the final cleanup
+is for the arch to provide cputime_to_nsec[s](). Commit ade7667a981b
+("powerpc: Add cputime_to_nsecs()") did that, but justdidn't remove
+the then-unused cputime_to_usecs(), cputime_t type, and associated
+remnants.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20221006105653.115829-1-npiggin@gmail.com
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/cputime.h | 17 +----------------
+ arch/powerpc/kernel/time.c | 23 ++---------------------
+ 2 files changed, 3 insertions(+), 37 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
+index 504f7fe6711a32..a23356c05af193 100644
+--- a/arch/powerpc/include/asm/cputime.h
++++ b/arch/powerpc/include/asm/cputime.h
+@@ -20,23 +20,8 @@
+ #include <asm/time.h>
+ #include <asm/param.h>
+
+-typedef u64 __nocast cputime_t;
+-typedef u64 __nocast cputime64_t;
+-
+-#define cmpxchg_cputime(ptr, old, new) cmpxchg(ptr, old, new)
+-
+ #ifdef __KERNEL__
+-/*
+- * Convert cputime <-> microseconds
+- */
+-extern u64 __cputime_usec_factor;
+-
+-static inline unsigned long cputime_to_usecs(const cputime_t ct)
+-{
+- return mulhdu((__force u64) ct, __cputime_usec_factor);
+-}
+-
+-#define cputime_to_nsecs(cputime) tb_to_ns((__force u64)cputime)
++#define cputime_to_nsecs(cputime) tb_to_ns(cputime)
+
+ /*
+ * PPC64 uses PACA which is task independent for storing accounting data while
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index d3f579f9880173..d0e59f427fd6f1 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -123,7 +123,7 @@ unsigned long tb_ticks_per_jiffy;
+ unsigned long tb_ticks_per_usec = 100; /* sane default */
+ EXPORT_SYMBOL(tb_ticks_per_usec);
+ unsigned long tb_ticks_per_sec;
+-EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */
++EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime conversions */
+
+ DEFINE_SPINLOCK(rtc_lock);
+ EXPORT_SYMBOL_GPL(rtc_lock);
+@@ -143,21 +143,6 @@ EXPORT_SYMBOL_GPL(ppc_tb_freq);
+ bool tb_invalid;
+
+ #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+-/*
+- * Factor for converting from cputime_t (timebase ticks) to
+- * microseconds. This is stored as 0.64 fixed-point binary fraction.
+- */
+-u64 __cputime_usec_factor;
+-EXPORT_SYMBOL(__cputime_usec_factor);
+-
+-static void calc_cputime_factors(void)
+-{
+- struct div_result res;
+-
+- div128_by_32(1000000, 0, tb_ticks_per_sec, &res);
+- __cputime_usec_factor = res.result_low;
+-}
+-
+ /*
+ * Read the SPURR on systems that have it, otherwise the PURR,
+ * or if that doesn't exist return the timebase value passed in.
+@@ -444,10 +429,7 @@ void vtime_flush(struct task_struct *tsk)
+ acct->hardirq_time = 0;
+ acct->softirq_time = 0;
+ }
+-
+-#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+-#define calc_cputime_factors()
+-#endif
++#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+ {
+@@ -962,7 +944,6 @@ void __init time_init(void)
+ tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+ tb_ticks_per_sec = ppc_tb_freq;
+ tb_ticks_per_usec = ppc_tb_freq / 1000000;
+- calc_cputime_factors();
+
+ /*
+ * Compute scale factor for sched_clock.
+--
+2.53.0
+
--- /dev/null
+From 338e32d78231b6f6129cd62d06a9adb364ae7c21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Mar 2021 05:09:39 -0400
+Subject: powerpc/time: Fix sparse warnings
+
+From: He Ying <heying24@huawei.com>
+
+[ Upstream commit ce0091a0e06045e70c526c8735f8b866a85e0a45 ]
+
+We found these warnings in arch/powerpc/kernel/time.c as follows:
+ warning: symbol 'decrementer_max' was not declared. Should it be static?
+ warning: symbol 'rtc_lock' was not declared. Should it be static?
+ warning: symbol 'dtl_consumer' was not declared. Should it be static?
+
+Declare 'decrementer_max' in powerpc asm/time.h.
+
+Include linux/mc146818rtc.h in powerpc kernel/time.c where 'rtc_lock' is
+declared. And remove duplicated declaration of 'rtc_lock' in powerpc
+platforms/chrp/time.c because it has included linux/mc146818rtc.h.
+
+Move 'dtl_consumer' definition after "include <asm/dtl.h>" because it is
+declared there.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: He Ying <heying24@huawei.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210324090939.143477-1-heying24@huawei.com
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/time.h | 1 +
+ arch/powerpc/kernel/time.c | 9 ++++-----
+ arch/powerpc/platforms/chrp/time.c | 2 --
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
+index 8c2c3dd4ddbac3..d7212a334f7242 100644
+--- a/arch/powerpc/include/asm/time.h
++++ b/arch/powerpc/include/asm/time.h
+@@ -22,6 +22,7 @@ extern unsigned long tb_ticks_per_jiffy;
+ extern unsigned long tb_ticks_per_usec;
+ extern unsigned long tb_ticks_per_sec;
+ extern struct clock_event_device decrementer_clockevent;
++extern u64 decrementer_max;
+
+
+ extern void generic_calibrate_decr(void);
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 4406d7a89558bb..d3f579f9880173 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -54,8 +54,9 @@
+ #include <linux/of_clk.h>
+ #include <linux/suspend.h>
+ #include <linux/processor.h>
+-#include <asm/trace.h>
++#include <linux/mc146818rtc.h>
+
++#include <asm/trace.h>
+ #include <asm/interrupt.h>
+ #include <asm/io.h>
+ #include <asm/nvram.h>
+@@ -149,10 +150,6 @@ bool tb_invalid;
+ u64 __cputime_usec_factor;
+ EXPORT_SYMBOL(__cputime_usec_factor);
+
+-#ifdef CONFIG_PPC_SPLPAR
+-void (*dtl_consumer)(struct dtl_entry *, u64);
+-#endif
+-
+ static void calc_cputime_factors(void)
+ {
+ struct div_result res;
+@@ -178,6 +175,8 @@ static inline unsigned long read_spurr(unsigned long tb)
+
+ #include <asm/dtl.h>
+
++void (*dtl_consumer)(struct dtl_entry *, u64);
++
+ /*
+ * Scan the dispatch trace log and count up the stolen time.
+ * Should be called with interrupts disabled.
+diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
+index acde7bbe07164e..b94dfd5090d80f 100644
+--- a/arch/powerpc/platforms/chrp/time.c
++++ b/arch/powerpc/platforms/chrp/time.c
+@@ -30,8 +30,6 @@
+
+ #include <platforms/chrp/chrp.h>
+
+-extern spinlock_t rtc_lock;
+-
+ #define NVRAM_AS0 0x74
+ #define NVRAM_AS1 0x75
+ #define NVRAM_DATA 0x77
+--
+2.53.0
+
--- /dev/null
+From ecb18ec7a21ea5336f90c27edc5a4c1cb670df3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2026 15:16:37 +0200
+Subject: powerpc/time: Prepare to stop elapsing in dynticks-idle
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit c8ba971cf8567d49eb5f43ee90c4e50424331c18 ]
+
+Currently the tick subsystem stores the idle cputime accounting in
+private fields, allowing cohabitation with architecture idle vtime
+accounting. The former is fetched on online CPUs, the latter on offline
+CPUs.
+
+For consolidation purpose, architecture vtime accounting will continue
+to account the cputime but will make a break when the idle tick is
+stopped. The dyntick cputime accounting will then be relayed by the tick
+subsystem so that the idle cputime is still seen advancing coherently
+even when the tick isn't there to flush the idle vtime.
+
+Prepare for that and introduce three new APIs which will be used in
+subsequent patches:
+
+ - vtime_dynticks_start() is deemed to be called when idle enters in
+ dyntick mode. The idle cputime that elapsed so far is accumulated.
+
+ - vtime_dynticks_stop() is deemed to be called when idle exits from
+ dyntick mode. The vtime entry clocks are fast-forward to current time
+ so that idle accounting restarts elapsing from now.
+
+ - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
+ fast-forward the clock to current time so that the IRQ time is still
+ accounted by vtime while nohz cputime is paused.
+
+Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
+accounting twice the idle cputime, along with nohz accounting.
+
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Link: https://patch.msgid.link/20260508131647.43868-6-frederic@kernel.org
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
+ include/linux/vtime.h | 6 ++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 65235323bee49c..e4ccacdd95435e 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -451,6 +451,47 @@ void vtime_task_switch(struct task_struct *prev)
+ acct->starttime = acct0->starttime;
+ }
+ }
++
++#ifdef CONFIG_NO_HZ_COMMON
++/**
++ * vtime_reset - Fast forward vtime entry clocks
++ *
++ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
++ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
++ */
++void vtime_reset(void)
++{
++ struct cpu_accounting_data *acct = get_accounting(current);
++
++ acct->starttime = mftb();
++#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
++ acct->startspurr = read_spurr(acct->starttime);
++#endif
++}
++
++/**
++ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
++ *
++ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
++ * is accumulated and the tick subsystem takes over the idle cputime accounting.
++ */
++void vtime_dyntick_start(void)
++{
++ vtime_account_idle(current);
++}
++
++/**
++ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
++ *
++ * Called when idle exits from dyntick mode. The vtime entry clocks are
++ * fast-forward to current time so that idle accounting restarts elapsing from
++ * now.
++ */
++void vtime_dyntick_stop(void)
++{
++ vtime_reset();
++}
++#endif /* CONFIG_NO_HZ_COMMON */
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/include/linux/vtime.h b/include/linux/vtime.h
+index 3684487d01e1c6..7cee518fde3a24 100644
+--- a/include/linux/vtime.h
++++ b/include/linux/vtime.h
+@@ -37,11 +37,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
+ extern void vtime_account_softirq(struct task_struct *tsk);
+ extern void vtime_account_hardirq(struct task_struct *tsk);
+ extern void vtime_flush(struct task_struct *tsk);
++extern void vtime_reset(void);
++extern void vtime_dyntick_start(void);
++extern void vtime_dyntick_stop(void);
+ #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+ static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
+ static inline void vtime_account_softirq(struct task_struct *tsk) { }
+ static inline void vtime_account_hardirq(struct task_struct *tsk) { }
+ static inline void vtime_flush(struct task_struct *tsk) { }
++static inline void vtime_reset(void) { }
++static inline void vtime_dyntick_start(void) { }
++static inline void vtime_dyntick_stop(void) { }
+ #endif
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 74fed396f9c92154405a3605683356dec043e7d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:13:29 +0530
+Subject: powerpc/vtime: Initialize starttime at boot for native accounting
+
+From: Shrikanth Hegde <sshegde@linux.ibm.com>
+
+[ Upstream commit c1c1ffa490fc33591e90852ed0d38804dd20bc36 ]
+
+It was observed that /proc/stat had very large value for one ore more
+CPUs. It was more visible after recent code simplifications around
+cpustats.
+
+System has 240 CPUs.
+
+cat /proc/uptime;
+194.18 46500.55
+cat /proc/stat
+cpu 5966 39 837032887 4650070 164 185 100 0 0 0
+cpu0 108 0 837030890 19109 24 4 23 0 0 0
+
+Since uptime is 194s, system time of each CPU can't be more than 19400.
+Sum of system time of all CPUs can't be more than 19400*240 4656000.
+In fact huge value is close to mftb(). Note mftb doesn't reset on powerVM
+when the LPAR restart. It only resets when whole system resets. The same
+issue exists for kexec too.
+
+This happens since starttime is not setup at init time. Once it is set
+then subsequent vtime_delta will return the right delta.
+
+Fix it by initializing the starttime during CPU initialization. This
+fixes the large times seen.
+
+cat /proc/uptime; cat /proc/stat
+15.78 3694.63
+cpu 6035 35 1347 369479 23 144 49 0 0 0
+cpu0 19 0 38 1508 0 1 14 0 0 0
+
+Now, system time is reported as expected.
+
+Fixes: cf9efce0ce31 ("powerpc: Account time using timebase rather than PURR")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Suggested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260605124329.377533-1-sshegde@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index e4ccacdd95435e..6dc87b4e2819f4 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -452,7 +452,6 @@ void vtime_task_switch(struct task_struct *prev)
+ }
+ }
+
+-#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_reset - Fast forward vtime entry clocks
+ *
+@@ -469,6 +468,7 @@ void vtime_reset(void)
+ #endif
+ }
+
++#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
+ *
+@@ -973,6 +973,7 @@ static void __init set_decrementer_max(void)
+ static void __init init_decrementer_clockevent(void)
+ {
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ void secondary_cpu_time_init(void)
+@@ -988,6 +989,7 @@ void secondary_cpu_time_init(void)
+ /* FIME: Should make unrelatred change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ /* This function is only called on the boot processor */
+--
+2.53.0
+
--- /dev/null
+From 32e0069237c6a728b25c356321f18f609a0228f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 8c28292ed33cf8..4c4dc817bc70c0 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -191,6 +191,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ rwlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3554,6 +3555,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Free up the resources used by a ppp channel.
+ */
+@@ -3569,9 +3582,7 @@ static void ppp_destroy_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3584,6 +3595,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_destroy(ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 233be7dc319c9ccfef6f391bac008a3491024cb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 61ae49219e6baa..9649abeadbbf6f 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -902,7 +902,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From 17abe60d3872ed0b8806718bba8a5de6020d247e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index e6cf2734c684a8..4c309781b4d6b8 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2256,7 +2256,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2289,7 +2289,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From 663af707c9cb3c9883b4f0bce771b2ebc37e8291 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Nov 2023 19:57:24 +0800
+Subject: RDMA/siw: Only check attrs->cap.max_send_wr in siw_create_qp
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit 788bbf4c2fc6e0c35bae9ed5068f484272539d3e ]
+
+We can just check max_send_wr here given both max_send_wr and
+max_recv_wr are defined as u32 type, and we also need to ensure
+num_sqe (derived from max_send_wr) shouldn't be zero.
+
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Link: https://lore.kernel.org/r/20231113115726.12762-16-guoqing.jiang@linux.dev
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: bb27fcc67c42 ("RDMA/siw: publish QP after initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index c83701d04c9558..55a1357a636dcd 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -334,11 +334,10 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ goto err_atomic;
+ }
+ /*
+- * NOTE: we allow for zero element SQ and RQ WQE's SGL's
+- * but not for a QP unable to hold any WQE (SQ + RQ)
++ * NOTE: we don't allow for a QP unable to hold any SQ WQE
+ */
+- if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) {
+- siw_dbg(base_dev, "QP must have send or receive queue\n");
++ if (attrs->cap.max_send_wr == 0) {
++ siw_dbg(base_dev, "QP must have send queue\n");
+ rv = -EINVAL;
+ goto err_atomic;
+ }
+@@ -358,21 +357,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_atomic;
+
+- num_sqe = attrs->cap.max_send_wr;
+- num_rqe = attrs->cap.max_recv_wr;
+
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+ * avoids handling counter wrap around.
+ */
+- if (num_sqe)
+- num_sqe = roundup_pow_of_two(num_sqe);
+- else {
+- /* Zero sized SQ is not supported */
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++ num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr);
++ num_rqe = attrs->cap.max_recv_wr;
+ if (num_rqe)
+ num_rqe = roundup_pow_of_two(num_rqe);
+
+--
+2.53.0
+
--- /dev/null
+From 66038aeabf4731e4fd31c38c7916001a323b2088 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 55a1357a636dcd..817970e3943132 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -300,6 +300,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -353,11 +354,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -375,14 +371,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -408,7 +404,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -423,11 +419,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -436,7 +429,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -448,9 +441,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -460,22 +467,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From b23e6d81f99c5f8020c2dc28bb29fcde20622287 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 17:09:45 +0200
+Subject: sched/vtime: Get rid of generic vtime_task_switch() implementation
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 89d6910cc562ab34d1f1c08f3cf0a9700b8bf2c4 ]
+
+The generic vtime_task_switch() implementation gets built only
+if __ARCH_HAS_VTIME_TASK_SWITCH is not defined, but requires an
+architecture to implement arch_vtime_task_switch() callback at
+the same time, which is confusing.
+
+Further, arch_vtime_task_switch() is implemented for 32-bit PowerPC
+architecture only and vtime_task_switch() generic variant is rather
+superfluous.
+
+Simplify the whole vtime_task_switch() wiring by moving the existing
+generic implementation to PowerPC.
+
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/2cb6e3caada93623f6d4f78ad938ac6cd0e2fda8.1712760275.git.agordeev@linux.ibm.com
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/cputime.h | 13 -------------
+ arch/powerpc/kernel/time.c | 22 ++++++++++++++++++++++
+ kernel/sched/cputime.c | 13 -------------
+ 3 files changed, 22 insertions(+), 26 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
+index a23356c05af193..2e5cc3abd92df5 100644
+--- a/arch/powerpc/include/asm/cputime.h
++++ b/arch/powerpc/include/asm/cputime.h
+@@ -31,23 +31,10 @@
+ #ifdef CONFIG_PPC64
+ #define get_accounting(tsk) (&get_paca()->accounting)
+ #define raw_get_accounting(tsk) (&local_paca->accounting)
+-static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+
+ #else
+ #define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
+ #define raw_get_accounting(tsk) get_accounting(tsk)
+-/*
+- * Called from the context switch with interrupts disabled, to charge all
+- * accumulated times to the current process, and to prepare accounting on
+- * the next process.
+- */
+-static inline void arch_vtime_task_switch(struct task_struct *prev)
+-{
+- struct cpu_accounting_data *acct = get_accounting(current);
+- struct cpu_accounting_data *acct0 = get_accounting(prev);
+-
+- acct->starttime = acct0->starttime;
+-}
+ #endif
+
+ /*
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index d0e59f427fd6f1..65235323bee49c 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -429,6 +429,28 @@ void vtime_flush(struct task_struct *tsk)
+ acct->hardirq_time = 0;
+ acct->softirq_time = 0;
+ }
++
++/*
++ * Called from the context switch with interrupts disabled, to charge all
++ * accumulated times to the current process, and to prepare accounting on
++ * the next process.
++ */
++void vtime_task_switch(struct task_struct *prev)
++{
++ if (is_idle_task(prev))
++ vtime_account_idle(prev);
++ else
++ vtime_account_kernel(prev);
++
++ vtime_flush(prev);
++
++ if (!IS_ENABLED(CONFIG_PPC64)) {
++ struct cpu_accounting_data *acct = get_accounting(current);
++ struct cpu_accounting_data *acct0 = get_accounting(prev);
++
++ acct->starttime = acct0->starttime;
++ }
++}
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
+index e3022598f7b02b..d71c4817996b32 100644
+--- a/kernel/sched/cputime.c
++++ b/kernel/sched/cputime.c
+@@ -406,19 +406,6 @@ static inline void irqtime_account_process_tick(struct task_struct *p, int user_
+ */
+ #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+
+-# ifndef __ARCH_HAS_VTIME_TASK_SWITCH
+-void vtime_task_switch(struct task_struct *prev)
+-{
+- if (is_idle_task(prev))
+- vtime_account_idle(prev);
+- else
+- vtime_account_kernel(prev);
+-
+- vtime_flush(prev);
+- arch_vtime_task_switch(prev);
+-}
+-# endif
+-
+ void vtime_account_irq(struct task_struct *tsk, unsigned int offset)
+ {
+ unsigned int pc = irq_count() - offset;
+--
+2.53.0
+
--- /dev/null
+From 873d57a6547e4d242cf5f7b1819ba213b6a2bf90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index b73eadf644b3ec..c9a811a3248fb1 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -322,7 +322,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
input-ims-pcu-fix-heap-buffer-overflow-in-ims_pcu_pr.patch
input-ims-pcu-fix-logic-error-in-packet-reset.patch
kvm-vmx-make-vmread_error_trampoline-uncallable-from.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-only-check-attrs-cap.max_send_wr-in-siw_cre.patch
+rdma-siw-publish-qp-after-initialization.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-remove-variable-num_processed.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+powerpc-time-fix-sparse-warnings.patch
+powerpc-remove-the-last-remnants-of-cputime_t.patch
+sched-vtime-get-rid-of-generic-vtime_task_switch-imp.patch
+powerpc-time-prepare-to-stop-elapsing-in-dynticks-id.patch
+powerpc-vtime-initialize-starttime-at-boot-for-nativ.patch
+can-j1939-fix-lockless-local-destination-check.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From 14d6cb9941bffc84054d83d546f32624c1b8fa6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 5d80ab4fa08777..3aaa45375d8ba0 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -3721,6 +3721,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3757,13 +3758,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3780,11 +3789,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 2abf3afa75eae1b385b4064a9cf005349bc8d65a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 76b2953725c2d0..696f3aa32adcff 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4451,6 +4451,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4464,7 +4465,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From 9a808e037a032788ff0b1e6acfca1e230f534b10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 1bc2aba69bd732..df9d0431864d39 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -240,7 +240,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 3bd85cc9df1d2fdf0eb11e49cd4f298ee56f860d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index d63480873d0636..3ab7a21a6743d0 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1104,6 +1104,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From b31c8cf6e8e60ccbfdd27da287c2a98dc663f0b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 5b66a66d05a6ec..9cb8bfb9ba96f8 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -116,6 +116,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -124,6 +125,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From 6e019f0409a2f2079a6591327be191dc56d60983 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index a7f91b584ee0cc..2c74da398cf4ed 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -300,7 +300,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 1c83dc0b203b23e98a0a2c3032bb1e42fffa246f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 65fa39275f73f8..5b66a66d05a6ec 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -190,6 +190,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -242,6 +243,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -251,10 +260,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 4c4612551ecefbd4d60d77372affcde6f44fd425 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 47eb89b773cf7f..c954e6001eab17 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6183,6 +6183,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6195,16 +6197,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From d9693b75ea164405d3393706eb60d8ba47b1470c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f993077895d69d0c77420c74581e93c48c6c2775 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index eb7de2d455e1ad..3b2d51df5d9473 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -482,6 +482,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -489,10 +490,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From 3ab040e7bde6b7db358efab48ebf1f1104143122 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index ed4d83775fe705..9c102c25a5332f 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -4332,6 +4332,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From cdfb04e4cb8d4f3ee5ba0673d02f8ecc18e51ec8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 6333b1000f925b..303badbd53d9b0 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -503,11 +503,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 584504bf4489636953642701178910520a646452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index cec66c74e1d22a..536b945e1eeb63 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1292,8 +1292,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 3989e125276729040a74d83c1a4998b5e3905198 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 8faf3731e3499d..ece6ae4a21ed9f 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2261,6 +2261,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
+--
+2.53.0
+
--- /dev/null
+From c571cd2e557ae4a5af4e63c2a18600c51359b324 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 16:15:34 +0530
+Subject: arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
+
+The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the
+compatible string for all CPU nodes to match the actual hardware.
+
+Tegra234 hardware reports:
+ # head /proc/cpuinfo | egrep 'implementer|part'
+ CPU implementer : 0x41
+ CPU part : 0xd42
+
+Which maps to (from arch/arm64/include/asm/cputype.h):
+ #define ARM_CPU_IMP_ARM 0x41
+ #define ARM_CPU_PART_CORTEX_A78AE 0xD42
+
+Fixes: a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 94eff4092b3858..482c913915a774 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -2659,7 +2659,7 @@ cpus {
+ #size-cells = <0>;
+
+ cpu0_0: cpu@0 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00000>;
+
+@@ -2675,7 +2675,7 @@ cpu0_0: cpu@0 {
+ };
+
+ cpu0_1: cpu@100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00100>;
+
+@@ -2691,7 +2691,7 @@ cpu0_1: cpu@100 {
+ };
+
+ cpu0_2: cpu@200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00200>;
+
+@@ -2707,7 +2707,7 @@ cpu0_2: cpu@200 {
+ };
+
+ cpu0_3: cpu@300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00300>;
+
+@@ -2723,7 +2723,7 @@ cpu0_3: cpu@300 {
+ };
+
+ cpu1_0: cpu@10000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10000>;
+
+@@ -2739,7 +2739,7 @@ cpu1_0: cpu@10000 {
+ };
+
+ cpu1_1: cpu@10100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10100>;
+
+@@ -2755,7 +2755,7 @@ cpu1_1: cpu@10100 {
+ };
+
+ cpu1_2: cpu@10200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10200>;
+
+@@ -2771,7 +2771,7 @@ cpu1_2: cpu@10200 {
+ };
+
+ cpu1_3: cpu@10300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10300>;
+
+@@ -2787,7 +2787,7 @@ cpu1_3: cpu@10300 {
+ };
+
+ cpu2_0: cpu@20000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20000>;
+
+@@ -2803,7 +2803,7 @@ cpu2_0: cpu@20000 {
+ };
+
+ cpu2_1: cpu@20100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20100>;
+
+@@ -2819,7 +2819,7 @@ cpu2_1: cpu@20100 {
+ };
+
+ cpu2_2: cpu@20200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20200>;
+
+@@ -2835,7 +2835,7 @@ cpu2_2: cpu@20200 {
+ };
+
+ cpu2_3: cpu@20300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20300>;
+
+--
+2.53.0
+
--- /dev/null
+From 7db6b1576907631e48748371066c37e0ab6fded4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:37 +0530
+Subject: ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
+
+The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was
+claimed with the stale name "AMD ACP6.2 audio" left over from the
+original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
+
+Fixes: 95e43a170bb1 ("ASoC: amd: add Pink Sardine ACP PCI driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 7c9751a7eedc22..c3bce6ed090d79 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -163,7 +163,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ return -ENODEV;
+ }
+
+- ret = pci_request_regions(pci, "AMD ACP6.2 audio");
++ ret = pci_request_regions(pci, "AMD ACP6.3 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+--
+2.53.0
+
--- /dev/null
+From c7891d128642aa1742780f269437f299970b2a06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index 2fb30f89bf7a2c..515310e8eae79b 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From d604d47177e31a03852c687faa3831f816bb1cff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index b486d0bd86c991..6d06b95f1c0137 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -685,11 +685,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From 587bcf2ab5794cdf57a1160cade84591c1ea6f94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index e3263e961045ac..9a4e12a09910a0 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1175,9 +1175,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+@@ -1210,6 +1207,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From 48f7628c1fb9d8d3e6b2c5ea9c52750fb5ae15a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 9a4e12a09910a0..24bc1b755dc748 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -403,8 +403,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From e219400ee3cbc4cdc7987d2fbe4d9d393035a39d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 5b34da23adce7c..09ef7df5c231bf 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -430,7 +430,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From e9664e5cf4e8179fa9d5b0cc5f2694966c20ac9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 06:23:57 +0200
+Subject: bpf, sockmap: Reject unhashed UDP sockets on sockmap update
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 66efd3368ae10d05e08fbe6425b50fdec7186ac7 ]
+
+UDP sockets get SOCK_RCU_FREE set when (auto-)bound. This means
+sk_is_refcounted(unbound) = true, while sk_is_refcounted(bound) = false.
+
+Because sockmap accepts unbound UDP sockets, a BPF program can increment a
+socket's refcount via lookup. If the socket is subsequently bound, the
+transition from unbound to bound causes bpf_sk_release() to skip the
+decrement of the refcount, causing a memory leak.
+
+unreferenced object 0xffff88810bc2eb40 (size 1984):
+ comm "test_progs", pid 2451, jiffies 4295320596
+ hex dump (first 32 bytes):
+ 7f 00 00 01 7f 00 00 01 d2 04 1b b7 04 d2 00 00 ................
+ 02 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace (crc bdee079d):
+ kmem_cache_alloc_noprof+0x557/0x660
+ sk_prot_alloc+0x69/0x240
+ sk_alloc+0x30/0x460
+ inet_create+0x2ce/0xf80
+ __sock_create+0x25b/0x5c0
+ __sys_socket+0x119/0x1d0
+ __x64_sys_socket+0x72/0xd0
+ do_syscall_64+0xa1/0x5f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Instead of special-casing for refcounted sockets, reject unhashed UDP
+sockets during sockmap updates, as there is no benefit to supporting those.
+This effectively reverts the commit under Fixes, with two exceptions:
+
+1. sock_map_sk_state_allowed() maintains a fall-through `return true`.
+2. In the spirit of commit b8b8315e39ff ("bpf, sockmap: Remove unhash
+ handler for BPF sockmap usage"), the proto::unhash BPF handler is not
+ reintroduced.
+
+Historical note: this issue is related to commit 67312adc96b5 ("bpf: reject
+unhashed sockets in bpf_sk_assign").
+
+Fixes: 0c48eefae712 ("sock_map: Lift socket state restriction for datagram sockets")
+Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20260707-sockmap-lookup-udp-leak-v4-2-f878346f27ab@rbox.co
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index f4cca477b0477e..fb10c33acc3fd2 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -542,6 +542,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+ {
+ if (sk_is_tcp(sk))
+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
++ if (sk_is_udp(sk))
++ return sk_hashed(sk);
+ if (sk_is_stream_unix(sk))
+ return (1 << sk->sk_state) & TCPF_ESTABLISHED;
+ return true;
+--
+2.53.0
+
--- /dev/null
+From 7962d2f088268099193e209f504e4f9826943bc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 93916c52b50e94..2e66a0672ba7fa 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -2045,6 +2045,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From 0cf7f7b6a19ecec33e12999d4efa095149bc7c87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 9f4dae426037b8..92933cc5596e0f 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -569,6 +569,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From 14850ce9d691043eab86c76cf646d5fc424e8a0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index e17a166a73c422..57d7b14c3949e6 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -350,6 +350,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -358,8 +370,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2021,8 +2032,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From 5695916a7d687c5725754768756b090421429056 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index 46a174f8aa0076..9a4309c30f0ea8 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -239,7 +239,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From 75dd696fac1da0e256d60eba88f02aff487a693d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index be94f863bdefff..0e237bcf324a83 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -16,9 +16,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -28,9 +28,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From dbab5f62aa6d73e51bb420dea0194795428286f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index f7c72fcc9b5e32..67ab5698a14241 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -655,7 +655,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From 78d5e3beb2c0ad758c2a43e339a4d7d5c4f82aa7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 4782b115e6ec51..1bc715fe3968c3 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -595,9 +595,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f591be8217686431d1d4bb63fd1c265a6b632572 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 242434c09e8d8f..bddb1c607aff62 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1778,6 +1778,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ &mad_send_wr->mad_agent_priv->done_list);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -1796,6 +1814,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From 9fa8f1ab21bfa271981598d1e0b4c0afc59ce457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index c9e1526e749b2b..53e7664eeb0a2a 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1390,7 +1390,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From 456a879be5e489a2ed55ccc2663c285e16913e5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
+index f257e096c8e17f..6a4f1b8a0b13c9 100644
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -400,6 +400,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From 6ad06387379fe0b56802bf04e9dc211a9c55a915 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 2d29d230f56989..6369ff87f4b9f3 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2139,6 +2139,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From 2711b4b006c26710533731de9b5e37f82a533ea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 680366616da240..4d695875ea1b23 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From f2e91699789b507d1938539caed8e22894a9b3c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/ecc-mtk.c b/drivers/mtd/nand/ecc-mtk.c
+index 9f9b201fe706a8..e2fb7596f49d71 100644
+--- a/drivers/mtd/nand/ecc-mtk.c
++++ b/drivers/mtd/nand/ecc-mtk.c
+@@ -115,8 +115,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -128,6 +128,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -304,7 +306,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -404,7 +410,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 46a166e40e824d25c995ffb9f4741043a7d4d3f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index e9a9bb0dee065a..a7b95590f6c96c 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2090,6 +2090,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2139,6 +2141,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 91e1d03b855dc5b61756e74536c72f7db8b19870 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 55a9dff1cc1e6d..ca4c3776f0f045 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -342,14 +342,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From b1d0d5b770f9cd32d0abef129762508d37bf94c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index df72070a3879dd..d3ea1d6da20568 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -192,6 +192,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ rwlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3555,6 +3556,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Free up the resources used by a ppp channel.
+ */
+@@ -3570,9 +3583,7 @@ static void ppp_destroy_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3585,6 +3596,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_destroy(ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 044993dcf65803fb03313be3fd5084fade67689f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:21:05 +0300
+Subject: RDMA/cma: Fix hardware address comparison length in netevent callback
+
+From: Or Gerlitz <ogerlitz@ddn.com>
+
+[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
+
+The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
+
+This breaks IPoIB, which uses 20-byte addresses. By truncating the
+memcmp, the CMA may incorrectly assume the target address is
+unchanged and fails to abort the stalled connection.
+
+Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len
+to correctly evaluate the full address regardless of the link layer.
+
+Fixes: 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
+Signed-off-by: Or Gerlitz <ogerlitz@ddn.com>
+Link: https://patch.msgid.link/20260617-fix-cma-ipoib-v1-1-03f869344304@ddn.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index b5924919e7f06f..e7827352409026 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5190,7 +5190,7 @@ static int cma_netevent_callback(struct notifier_block *self,
+
+ list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
+ if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
+- neigh->ha, ETH_ALEN))
++ neigh->ha, neigh->dev->addr_len))
+ continue;
+ cma_id_get(current_id);
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
+--
+2.53.0
+
--- /dev/null
+From 7d02a08e730d3b394f5f5bc77711026d8430be2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:51 +0800
+Subject: RDMA/erdma: initialize ret for empty receive WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
+
+erdma_post_recv() returns ret after walking the receive work request list.
+If the caller passes an empty list, the loop is skipped and ret is not
+assigned.
+
+Initialize ret to 0 so an empty receive work request list returns success
+instead of stack data.
+
+Fixes: 155055771704 ("RDMA/erdma: Add verbs implementation")
+Link: https://patch.msgid.link/r/20260618041752.481193-1-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_qp.c b/drivers/infiniband/hw/erdma/erdma_qp.c
+index e3b0baa703e681..74cb47ab827e14 100644
+--- a/drivers/infiniband/hw/erdma/erdma_qp.c
++++ b/drivers/infiniband/hw/erdma/erdma_qp.c
+@@ -537,7 +537,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
+ const struct ib_recv_wr *wr = recv_wr;
+ struct erdma_qp *qp = to_eqp(ibqp);
+ unsigned long flags;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&qp->lock, flags);
+
+--
+2.53.0
+
--- /dev/null
+From 3e726fb2a91b1d2b230f65a9201083240297d53a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 862acdf59867a9..ce115dbba13020 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -907,7 +907,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From a9d480d5b5863b38c8fed8c43dee7096ded18111 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index b43ce455050c66..56e3103aa77f91 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2336,7 +2336,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2369,7 +2369,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From 1bd7a9e5455269e64b98367828dce3e87beeb1cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Nov 2023 19:57:24 +0800
+Subject: RDMA/siw: Only check attrs->cap.max_send_wr in siw_create_qp
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit 788bbf4c2fc6e0c35bae9ed5068f484272539d3e ]
+
+We can just check max_send_wr here given both max_send_wr and
+max_recv_wr are defined as u32 type, and we also need to ensure
+num_sqe (derived from max_send_wr) shouldn't be zero.
+
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Link: https://lore.kernel.org/r/20231113115726.12762-16-guoqing.jiang@linux.dev
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: bb27fcc67c42 ("RDMA/siw: publish QP after initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index dce86f5aee1f76..336702bcbfa9f8 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -336,11 +336,10 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ goto err_atomic;
+ }
+ /*
+- * NOTE: we allow for zero element SQ and RQ WQE's SGL's
+- * but not for a QP unable to hold any WQE (SQ + RQ)
++ * NOTE: we don't allow for a QP unable to hold any SQ WQE
+ */
+- if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) {
+- siw_dbg(base_dev, "QP must have send or receive queue\n");
++ if (attrs->cap.max_send_wr == 0) {
++ siw_dbg(base_dev, "QP must have send queue\n");
+ rv = -EINVAL;
+ goto err_atomic;
+ }
+@@ -360,21 +359,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_atomic;
+
+- num_sqe = attrs->cap.max_send_wr;
+- num_rqe = attrs->cap.max_recv_wr;
+
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+ * avoids handling counter wrap around.
+ */
+- if (num_sqe)
+- num_sqe = roundup_pow_of_two(num_sqe);
+- else {
+- /* Zero sized SQ is not supported */
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++ num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr);
++ num_rqe = attrs->cap.max_recv_wr;
+ if (num_rqe)
+ num_rqe = roundup_pow_of_two(num_rqe);
+
+--
+2.53.0
+
--- /dev/null
+From a1689d35d210d8b9ad7fcc1f55abe68eccde7007 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 336702bcbfa9f8..8e89e32435d455 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -302,6 +302,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -355,11 +356,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -377,14 +373,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -410,7 +406,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -425,11 +421,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -438,7 +431,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -450,9 +443,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -462,22 +469,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From 939a042eafd2796f6cce6a03c7de44cfd0e8c884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 8995914916ca6e..cef44fa66fb36b 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -322,7 +322,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
--- /dev/null
+From 3329b7a8386457bff6602788d17811a965abb610 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:27:36 +0530
+Subject: selftests/alsa: Fix memory leak in find_controls error path
+
+From: Malaya Kumar Rout <malayarout91@gmail.com>
+
+[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
+
+In find_controls(), card_data is allocated with malloc() but when
+snd_ctl_open_lconf() fails, the code jumps to next_card without
+freeing the allocated memory. This results in a memory leak for
+each card where snd_ctl_open_lconf() fails.
+
+Add free(card_data) before goto next_card to ensure proper cleanup
+of the allocated memory in the error path.
+
+Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
+Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
+Link: https://patch.msgid.link/20260704105736.94874-1-malayarout91@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/alsa/mixer-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
+index 9ad39db32d1442..960b137789d25e 100644
+--- a/tools/testing/selftests/alsa/mixer-test.c
++++ b/tools/testing/selftests/alsa/mixer-test.c
+@@ -130,6 +130,7 @@ static void find_controls(void)
+ if (err < 0) {
+ ksft_print_msg("Failed to get hctl for card %d: %s\n",
+ card, snd_strerror(err));
++ free(card_data);
+ goto next_card;
+ }
+
+--
+2.53.0
+
input-ims-pcu-fix-heap-buffer-overflow-in-ims_pcu_pr.patch
input-ims-pcu-fix-logic-error-in-packet-reset.patch
mm-refactor-mm_access-to-not-return-null.patch
+arm64-tegra-fix-cpu-compatible-string-to-cortex-a78a.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+rdma-cma-fix-hardware-address-comparison-length-in-n.patch
+rdma-erdma-initialize-ret-for-empty-receive-wr-lists.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-only-check-attrs-cap.max_send_wr-in-siw_cre.patch
+rdma-siw-publish-qp-after-initialization.patch
+selftests-alsa-fix-memory-leak-in-find_controls-erro.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm6-clear-dst.dev-on-error-to-avoid-double-netdev_.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-nl80211-free-rnr-data-on-mbssid-mismatch.patch
+wifi-nl80211-validate-nested-mbssid-ie-blobs.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-amd-ps-fix-wrong-acp-version-string-in-pci_requ.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+bpf-sockmap-reject-unhashed-udp-sockets-on-sockmap-u.patch
+can-j1939-fix-lockless-local-destination-check.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From 6555f0932124c812eebe6f76d5d4bf4931a39da5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index a80c5f07fc718c..05b7b02a6b0352 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3655,6 +3655,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3691,13 +3692,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3714,11 +3723,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From adffc2441343cf4fdf3f06698e8f3d4442a69126 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 5f6c0afe22d49c..fb09d76ea053cb 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4451,6 +4451,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4464,7 +4465,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From 70cff20312ea5aa4a116ec693489b1bab34f0127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index ae899e25581d27..1ebe2f3f6f52ac 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -240,7 +240,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 1d3f38994513f2458f51a5dee9c23e1b22dd5c66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 2a6a8bdfa72484..6f83ea71b76057 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1125,6 +1125,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From 97bb1b16cd1d68b007847946b282f7b9e38fb3fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 647ca369caf994..e3987ba2d40a07 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From 3d95fd52be1cc2bdf9298ca61d88bd5d7618f9d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index dd5bd7826646c2..bb2d19057480b4 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -309,7 +309,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 6490c38b9062432b21c56c9ffb206406dd1aa034 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 656464f2de516c..647ca369caf994 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -188,6 +188,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -240,6 +241,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -249,10 +258,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From d7f555b3b02ea989a6d16fdc518828f5fb1eae42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index b0f23cf1a621b6..a76e94fcb29558 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6183,6 +6183,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6195,16 +6197,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From 643ae62e5951ff5644acd49afab66f4a44f213e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From cc0f1347f0ec57c2e42b3c59aef68b28d7d50286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 6818c9d852e8e5..4224a7c244a3d0 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -593,6 +593,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -600,10 +601,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From 4ed9273a0b8a3e54c206b1322ce3e09b48417f4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 316b5f56b6e53f..bb9dabbf1f22c6 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -5564,6 +5564,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From f0746b366d9985e416be8ab6d91a4319097c03c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 19:22:09 +0800
+Subject: wifi: nl80211: free RNR data on MBSSID mismatch
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
+
+nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR
+entries than MBSSID entries.
+
+The rejected RNR allocation has not been attached to the beacon data yet,
+so free it before returning the error.
+
+Fixes: dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260610112208.1308-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 36a7b9707eabd2..0146d837b8320e 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5631,8 +5631,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (IS_ERR(rnr))
+ return PTR_ERR(rnr);
+
+- if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
++ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
++ kfree(rnr);
+ return -EINVAL;
++ }
+
+ bcn->rnr_ies = rnr;
+ }
+--
+2.53.0
+
--- /dev/null
+From e0b7ac4a2315b11ccf8715313dde4b162edff5b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:55 +0800
+Subject: wifi: nl80211: validate nested MBSSID IE blobs
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
+
+Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed
+information-element stream before storing it for beacon construction.
+
+RNR parsing already validates each nested blob with validate_ie_attr()
+before storing it. Apply the same syntactic IE validation to MBSSID
+entries before counting and copying their data and length pointers.
+
+Fixes: dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-3-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 0146d837b8320e..dd5bd7826646c2 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5433,7 +5433,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
+ }
+
+ static struct cfg80211_mbssid_elems *
+-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
++nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
++ struct netlink_ext_ack *extack)
+ {
+ struct nlattr *nl_elems;
+ struct cfg80211_mbssid_elems *elems;
+@@ -5444,6 +5445,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+ return ERR_PTR(-EINVAL);
+
+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
++ int ret;
++
++ ret = validate_ie_attr(nl_elems, extack);
++ if (ret)
++ return ERR_PTR(ret);
++
+ if (num_elems >= 255)
+ return ERR_PTR(-EINVAL);
+ num_elems++;
+@@ -5615,7 +5622,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
+ struct cfg80211_mbssid_elems *mbssid =
+ nl80211_parse_mbssid_elems(&rdev->wiphy,
+- attrs[NL80211_ATTR_MBSSID_ELEMS]);
++ attrs[NL80211_ATTR_MBSSID_ELEMS],
++ extack);
+
+ if (IS_ERR(mbssid))
+ return PTR_ERR(mbssid);
+--
+2.53.0
+
--- /dev/null
+From 74bcf4e4b0817499115675a21d41e3d1e1d5d537 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 2deb1bb54f24bd..dc7bf54e30bba1 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 00c0504c77d8a5fa155f301078384e936323355a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index a780fb581388b0..dbaef78f43c215 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1295,8 +1295,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From d25d547aff34492c1422a76349f0a9619374f321 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 01:05:16 +0000
+Subject: xfrm6: clear dst.dev on error to avoid double netdev_put in
+ xfrm6_fill_dst()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
+
+On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst()
+releases the device reference with netdev_put() but leaves
+xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev)
+again, so the same net_device reference is released twice, underflowing
+its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for
+<dev> to become free").
+
+Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM
+device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in
+net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
+
+ ref_tracker: reference already released.
+ ref_tracker: allocated in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
+ ...
+ udpv6_sendmsg (net/ipv6/udp.c:1696)
+ ...
+ ref_tracker: freed in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
+ ...
+ WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
+ dst_destroy (net/core/dst.c:115)
+ rcu_core
+ handle_softirqs
+ ...
+
+Fixes: 84c4a9dfbf43 ("xfrm6: release dev before returning error")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index c936e083f5d8ab..c945473f6e5fed 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+ if (!xdst->u.rt6.rt6i_idev) {
+ netdev_put(dev, &xdst->u.dst.dev_tracker);
++ xdst->u.dst.dev = NULL;
+ return -ENODEV;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From cd7bbf5a836a48eaa4bcc04d354441d55a439acb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 12:13:31 +0200
+Subject: accel/ivpu: Fix wrong register read in LNL failure diagnostics
+
+From: Karol Wachowski <karol.wachowski@linux.intel.com>
+
+[ Upstream commit e4159045c2704dfe146f0ccb0445d9d074cd6882 ]
+
+diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of
+VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a
+different register with a different bit layout, so failure diagnostics
+decoded the wrong register and reported a bogus error cause.
+Read the LNL interrupt status register instead.
+
+Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
+Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Link: https://patch.msgid.link/20260710101331.1899505-1-karol.wachowski@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c
+index 4af1b164d85a73..c9e1922aff5e84 100644
+--- a/drivers/accel/ivpu/ivpu_hw_btrs.c
++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c
+@@ -852,7 +852,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev)
+
+ static void diagnose_failure_lnl(struct ivpu_device *vdev)
+ {
+- u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
++ u32 reg = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) {
+ ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
+--
+2.53.0
+
--- /dev/null
+From a9c0ad83b1b23a97b2e9010bd04977a6b72f5d27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 489dd84e20967c..ea2ec3507521ef 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2369,6 +2369,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
+--
+2.53.0
+
--- /dev/null
+From 39ecbd5d7f99db4d678f5d5a5e25f840bf1a5f56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 16:15:34 +0530
+Subject: arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
+
+The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the
+compatible string for all CPU nodes to match the actual hardware.
+
+Tegra234 hardware reports:
+ # head /proc/cpuinfo | egrep 'implementer|part'
+ CPU implementer : 0x41
+ CPU part : 0xd42
+
+Which maps to (from arch/arm64/include/asm/cputype.h):
+ #define ARM_CPU_IMP_ARM 0x41
+ #define ARM_CPU_PART_CORTEX_A78AE 0xD42
+
+Fixes: a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 75428e70a69252..c1d2d91975057a 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -5262,7 +5262,7 @@ cpus {
+ #size-cells = <0>;
+
+ cpu0_0: cpu@0 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00000>;
+
+@@ -5281,7 +5281,7 @@ cpu0_0: cpu@0 {
+ };
+
+ cpu0_1: cpu@100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00100>;
+
+@@ -5300,7 +5300,7 @@ cpu0_1: cpu@100 {
+ };
+
+ cpu0_2: cpu@200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00200>;
+
+@@ -5319,7 +5319,7 @@ cpu0_2: cpu@200 {
+ };
+
+ cpu0_3: cpu@300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00300>;
+
+@@ -5338,7 +5338,7 @@ cpu0_3: cpu@300 {
+ };
+
+ cpu1_0: cpu@10000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10000>;
+
+@@ -5357,7 +5357,7 @@ cpu1_0: cpu@10000 {
+ };
+
+ cpu1_1: cpu@10100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10100>;
+
+@@ -5376,7 +5376,7 @@ cpu1_1: cpu@10100 {
+ };
+
+ cpu1_2: cpu@10200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10200>;
+
+@@ -5395,7 +5395,7 @@ cpu1_2: cpu@10200 {
+ };
+
+ cpu1_3: cpu@10300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10300>;
+
+@@ -5414,7 +5414,7 @@ cpu1_3: cpu@10300 {
+ };
+
+ cpu2_0: cpu@20000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20000>;
+
+@@ -5433,7 +5433,7 @@ cpu2_0: cpu@20000 {
+ };
+
+ cpu2_1: cpu@20100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20100>;
+
+@@ -5452,7 +5452,7 @@ cpu2_1: cpu@20100 {
+ };
+
+ cpu2_2: cpu@20200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20200>;
+
+@@ -5471,7 +5471,7 @@ cpu2_2: cpu@20200 {
+ };
+
+ cpu2_3: cpu@20300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20300>;
+
+--
+2.53.0
+
--- /dev/null
+From 52be7cbed75e9e32641ccd9b3581a926655271f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:37 +0530
+Subject: ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
+
+The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was
+claimed with the stale name "AMD ACP6.2 audio" left over from the
+original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
+
+Fixes: 95e43a170bb1 ("ASoC: amd: add Pink Sardine ACP PCI driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index aec3150ecf5812..eb4b552c942417 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -570,7 +570,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ return -ENODEV;
+ }
+
+- ret = pci_request_regions(pci, "AMD ACP6.2 audio");
++ ret = pci_request_regions(pci, "AMD ACP6.3 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+--
+2.53.0
+
--- /dev/null
+From 5f684bf831ebbe226e272d8f6e6060b9089aa23e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 11:34:30 +0100
+Subject: ASoC: cs42l43: Correct report for forced microphone jack
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]
+
+Currently if the jack is forced to the microphone mode, it will report
+as line in. Correct the report to microphone.
+
+Fixes: fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20260708103430.1395207-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l43-jack.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
+index 3a61f222d85fee..57626db1140a2c 100644
+--- a/sound/soc/codecs/cs42l43-jack.c
++++ b/sound/soc/codecs/cs42l43-jack.c
+@@ -311,6 +311,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
+ #define CS42L43_JACK_ABSENT 0x0
+
+ #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
++#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
+ #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
+ #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
+ #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
+@@ -879,7 +880,7 @@ static const struct cs42l43_jack_override_mode {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+ .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
+ CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
+- .report = CS42L43_JACK_LINEIN,
++ .report = CS42L43_JACK_MICROPHONE,
+ },
+ [CS42L43_JACK_RAW_OPTICAL] = {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+--
+2.53.0
+
--- /dev/null
+From 60ab1f8eb0ba2dfba9aa1158e31c75d4f87f282f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index e0e00ec026dcc4..a9861c5d663745 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From 64de8558d3e36ee254d71bf4e3c5f4fa1a0d34f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index 54561ae598b87a..7daa9e9e0f60e9 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -683,11 +683,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From 43053a1833506811431d3d59f8d22e01aeebb963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 52f5168e4db542..16c1deef389d10 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From acc8e21011d89c6b212f0688fed3471c374c2c5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 97b934fa116e26..74514608a7fada 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From 77debf89ac3b127571ef8451d556024660b9c7ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 74514608a7fada..66db8dd8ec2670 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+ if (unlikely(!qc)) {
+ dev_err(ap->dev, "failed to get qc");
+--
+2.53.0
+
--- /dev/null
+From 50c3a563916660318ff7c185dd625e8d627577bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:25 -0700
+Subject: ata: sata_dwc_460ex: use platform_get_irq()
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]
+
+Replace irq_of_parse_and_map() with platform_get_irq() in both
+sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred
+way to obtain IRQs for platform devices and provides better error
+reporting. Remove the now-unnecessary #include <linux/of_irq.h>.
+
+irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.
+
+Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 16c1deef389d10..97b934fa116e26 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -19,7 +19,6 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/of.h>
+-#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/libata.h>
+@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ struct sata_dwc_device *hsdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *np = dev->of_node;
+
+ hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL);
+ if (!hsdev->dma)
+@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ hsdev->dma->id = pdev->id;
+
+ /* Get SATA DMA interrupt number */
+- hsdev->dma->irq = irq_of_parse_and_map(np, 1);
+- if (!hsdev->dma->irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ hsdev->dma->irq = platform_get_irq(pdev, 1);
++ if (hsdev->dma->irq < 0)
++ return hsdev->dma->irq;
+
+ /* Get physical SATA DMA register base address */
+ hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1);
+@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {
+ static int sata_dwc_probe(struct platform_device *ofdev)
+ {
+ struct device *dev = &ofdev->dev;
+- struct device_node *np = dev->of_node;
+ struct sata_dwc_device *hsdev;
+ u32 idr, versionr;
+ char *ver = (char *)&versionr;
+@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ hsdev->dev = dev;
+
+ /* Get SATA interrupt number */
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ irq = platform_get_irq(ofdev, 0);
++ if (irq < 0)
++ return irq;
+
+ #ifdef CONFIG_SATA_DWC_OLD_DMA
+- if (!of_property_present(np, "dmas")) {
++ if (!of_property_present(dev->of_node, "dmas")) {
+ err = sata_dwc_dma_init_old(ofdev, hsdev);
+ if (err)
+ return err;
+--
+2.53.0
+
--- /dev/null
+From 545986a12260a23b3cad84197f0836544479a002 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 14:22:50 +0800
+Subject: Bluetooth: hci_qca: Clear memdump state on invalid dump size
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bf587a10c33e5571a299742e45bc18960b9912e7 ]
+
+qca_controller_memdump() allocates qca->qca_memdump before processing
+the first dump packet. For a sequence-zero packet it then disables IBS,
+marks memdump collection active, and reads the advertised dump size.
+
+If the controller reports a zero dump size, the error path frees the
+local qca_memdump object and returns without clearing qca->qca_memdump
+or undoing the collection state. A later memdump work item initializes
+its local pointer from qca->qca_memdump and skips allocation when that
+pointer is non-NULL, so it can operate on freed memory. The stale
+collection and IBS-disabled flags can also leave waiters or later
+transmit handling blocked behind an aborted dump.
+
+Clear the saved pointer and memdump state before returning from the
+invalid-size path, matching the cleanup used when hci_devcd_init() fails.
+
+A static analysis checker reported the stale memdump state, and manual
+source review confirmed the invalid-size failure path.
+
+Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index de9fd0e77d398a..524fc638ceb49f 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1070,6 +1070,10 @@ static void qca_controller_memdump(struct work_struct *work)
+ if (!(qca_memdump->ram_dump_size)) {
+ bt_dev_err(hu->hdev, "Rx invalid memdump size");
+ kfree(qca_memdump);
++ qca->qca_memdump = NULL;
++ qca->memdump_state = QCA_MEMDUMP_COLLECTED;
++ clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
++ clear_bit(QCA_IBS_DISABLED, &qca->flags);
+ kfree_skb(skb);
+ mutex_unlock(&qca->hci_memdump_lock);
+ return;
+--
+2.53.0
+
--- /dev/null
+From 3fa8e2956a995627ee6585806f324345cdf2ca9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:41 +0300
+Subject: Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 16cd66443957e4ad42155c6fec401012f600c6f8 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF.
+
+Take hdev->lock for hci_conn lookup and hci_abort_conn(). Don't use RCU
+to ensure the conn is fully initialized at this point.
+
+Fixes: 227a0cdf4a028 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 0c09cb5a78e028..a5945cfd71c5a5 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3012,6 +3012,8 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_unpair_device *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3019,6 +3021,11 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return 0;
+
+@@ -3026,6 +3033,7 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+@@ -3173,6 +3181,8 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_disconnect *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3180,6 +3190,11 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return -ENOTCONN;
+
+@@ -3187,6 +3202,7 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 1f0d466074d8206483ef9fbece1db984e181cdea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:42 +0300
+Subject: Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit da55f570191d5d72f10c607a7043b947eb05ea46 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF. Use of hci_conn in hci_sync callbacks also
+needs to hold refcount to avoid UAF.
+
+Take appropriate locks for hci_conn lookups, and take refcount for
+hci_conn pointers stored in mgmt_pending_cmd so that the pointer stays
+valid.
+
+When accessing conn->state, ensure hdev->lock is held to avoid data
+race.
+
+Fixes: 7b445e220db9 ("Bluetooth: MGMT: Fix holding hci_conn reference while command is queued")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index a5945cfd71c5a5..f472ce8fb978bd 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7425,6 +7425,9 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
+ rp.max_tx_power = HCI_TX_POWER_INVALID;
+ }
+
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
+ &rp, sizeof(rp));
+
+@@ -7439,6 +7442,8 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ int err;
+ __le16 handle;
+
++ hci_dev_lock(hdev);
++
+ /* Make sure we are still connected */
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+@@ -7446,12 +7451,16 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ else
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
+
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ handle = cpu_to_le16(conn->handle);
+
++ hci_dev_unlock(hdev);
++
+ /* Refresh RSSI each time */
+ err = hci_read_rssi_sync(hdev, handle);
+
+@@ -7585,6 +7594,9 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
+ }
+
+ complete:
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
+ sizeof(rp));
+
+@@ -7601,15 +7613,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
+ memset(&hci_cp, 0, sizeof(hci_cp));
+ hci_read_clock_sync(hdev, &hci_cp);
+
++ hci_dev_lock(hdev);
++
+ /* Make sure connection still exists */
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ hci_cp.handle = cpu_to_le16(conn->handle);
+ hci_cp.which = 0x01; /* Piconet clock */
+
++ hci_dev_unlock(hdev);
++
+ return hci_read_clock_sync(hdev, &hci_cp);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 13806c208f009734f7c7271a9fe0d7f95554cf40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 12:15:18 +0800
+Subject: Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 2bf282f8f715f5d05d6f4c49ffb3bd241c5e667e ]
+
+MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter
+update changes an existing LE central connection. The queued work currently
+stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later
+LOAD_CONN_PARAM request can clear disabled parameters and free that entry
+before hci_cmd_sync_work() runs the queued callback.
+
+Do not keep the borrowed hci_conn_params pointer in queued work. Queue the
+hci_conn instead and hold a reference until the queued callback completes.
+When the work runs, revalidate that the connection is still present, look
+up the current hci_conn_params entry, and cancel the update if userspace
+removed that entry while the work was pending.
+
+Copy the interval values from the current params entry under hdev->lock,
+then drop the lock and keep using hci_le_conn_update_sync() to issue the
+update.
+
+Validation reproduced this kernel report:
+BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth]
+Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377
+Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x5f0
+ kasan_report+0xe0/0x110
+ conn_update_sync+0x2a/0xf0 [bluetooth]
+ hci_cmd_sync_work+0x187/0x210 [bluetooth]
+ process_one_work+0x4fd/0xbc0
+ worker_thread+0x2d8/0x570
+ kthread+0x1ad/0x1f0
+ ret_from_fork+0x3c9/0x540
+ ret_from_fork_asm+0x1a/0x30
+
+Allocated by task 466:
+ hci_conn_params_add+0xa6/0x240 [bluetooth]
+ load_conn_param+0x4e1/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Freed by task 474:
+ kfree+0x313/0x590
+ hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth]
+ load_conn_param+0x4bf/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Fixes: 0ece498c27d8c ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection")
+Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 44 +++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 6280fcfcdd0c6a..0c09cb5a78e028 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -8024,14 +8024,36 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
+
+ static int conn_update_sync(struct hci_dev *hdev, void *data)
+ {
+- struct hci_conn_params *params = data;
+- struct hci_conn *conn;
++ struct hci_conn *conn = data;
++ struct hci_conn_params *params;
++ struct hci_conn_params local = {};
+
+- conn = hci_conn_hash_lookup_le(hdev, ¶ms->addr, params->addr_type);
+- if (!conn)
+- return -ECANCELED;
++ hci_dev_lock(hdev);
++
++ if (!hci_conn_valid(hdev, conn) || conn->role != HCI_ROLE_MASTER)
++ goto cancel;
++
++ params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
++ if (!params)
++ goto cancel;
++
++ local.conn_min_interval = params->conn_min_interval;
++ local.conn_max_interval = params->conn_max_interval;
++ local.conn_latency = params->conn_latency;
++ local.supervision_timeout = params->supervision_timeout;
+
+- return hci_le_conn_update_sync(hdev, conn, params);
++ hci_dev_unlock(hdev);
++
++ return hci_le_conn_update_sync(hdev, conn, &local);
++
++cancel:
++ hci_dev_unlock(hdev);
++ return -ECANCELED;
++}
++
++static void conn_update_sync_destroy(struct hci_dev *hdev, void *data, int err)
++{
++ hci_conn_put(data);
+ }
+
+ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+@@ -8141,9 +8163,13 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+ (conn->le_conn_min_interval != min ||
+ conn->le_conn_max_interval != max ||
+ conn->le_conn_latency != latency ||
+- conn->le_supv_timeout != timeout))
+- hci_cmd_sync_queue(hdev, conn_update_sync,
+- hci_param, NULL);
++ conn->le_supv_timeout != timeout)) {
++ hci_conn_get(conn);
++ if (hci_cmd_sync_queue(hdev, conn_update_sync,
++ conn,
++ conn_update_sync_destroy) < 0)
++ hci_conn_put(conn);
++ }
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 20bbffc2d1ff1546ffd400d10e6e8f40548d2991 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 372427747cd649..083a599eec74db 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -413,7 +413,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From 3455fb2d4c77b92b72b831ec98f8fbd299a4b252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 06:23:57 +0200
+Subject: bpf, sockmap: Reject unhashed UDP sockets on sockmap update
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 66efd3368ae10d05e08fbe6425b50fdec7186ac7 ]
+
+UDP sockets get SOCK_RCU_FREE set when (auto-)bound. This means
+sk_is_refcounted(unbound) = true, while sk_is_refcounted(bound) = false.
+
+Because sockmap accepts unbound UDP sockets, a BPF program can increment a
+socket's refcount via lookup. If the socket is subsequently bound, the
+transition from unbound to bound causes bpf_sk_release() to skip the
+decrement of the refcount, causing a memory leak.
+
+unreferenced object 0xffff88810bc2eb40 (size 1984):
+ comm "test_progs", pid 2451, jiffies 4295320596
+ hex dump (first 32 bytes):
+ 7f 00 00 01 7f 00 00 01 d2 04 1b b7 04 d2 00 00 ................
+ 02 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace (crc bdee079d):
+ kmem_cache_alloc_noprof+0x557/0x660
+ sk_prot_alloc+0x69/0x240
+ sk_alloc+0x30/0x460
+ inet_create+0x2ce/0xf80
+ __sock_create+0x25b/0x5c0
+ __sys_socket+0x119/0x1d0
+ __x64_sys_socket+0x72/0xd0
+ do_syscall_64+0xa1/0x5f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Instead of special-casing for refcounted sockets, reject unhashed UDP
+sockets during sockmap updates, as there is no benefit to supporting those.
+This effectively reverts the commit under Fixes, with two exceptions:
+
+1. sock_map_sk_state_allowed() maintains a fall-through `return true`.
+2. In the spirit of commit b8b8315e39ff ("bpf, sockmap: Remove unhash
+ handler for BPF sockmap usage"), the proto::unhash BPF handler is not
+ reintroduced.
+
+Historical note: this issue is related to commit 67312adc96b5 ("bpf: reject
+unhashed sockets in bpf_sk_assign").
+
+Fixes: 0c48eefae712 ("sock_map: Lift socket state restriction for datagram sockets")
+Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20260707-sockmap-lookup-udp-leak-v4-2-f878346f27ab@rbox.co
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 82a14f131d00c6..6440ce16fc6214 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -542,6 +542,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+ {
+ if (sk_is_tcp(sk))
+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
++ if (sk_is_udp(sk))
++ return sk_hashed(sk);
+ if (sk_is_stream_unix(sk))
+ return (1 << sk->sk_state) & TCPF_ESTABLISHED;
+ if (sk_is_vsock(sk) &&
+--
+2.53.0
+
--- /dev/null
+From 2e7001078bfd090f024c8555205b99f2fbe1e430 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 43e8c331168e94..d2a1323e8b1034 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1956,6 +1956,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From da1ecd3bb3658a3edb5ddf72acd7c475c8adcc16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index f4bcb25306606a..01588dd3c7028f 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -556,6 +556,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From c934e6698c7c28c97b55d181aaf5c5bf4de26771 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 6c37562a50f72e..d8dada03b3cd12 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -350,6 +350,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -358,8 +370,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2021,8 +2032,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From 5ca9a66f6d8f168faa05f7182b3ec8f4151f8180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 19:25:39 +0200
+Subject: cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit d2d5c129d07ea8eb91cd8a8633b5774116c4d171 ]
+
+If arch_scale_freq_ref() is not defined for a given arch (like x86, for
+example), cpufreq_update_pressure() will always set cpufreq_pressure to
+zero for all CPUs in the system, which is generally problematic on
+systems with asymmetric capacity [1].
+
+However, in the absence of arch_scale_freq_ref(), it is reasonable
+to assume that cpuinfo.max_freq is the maximum sustainable frequency
+for the given cpufreq policy. Moreover, there are cases in which
+arch_scale_freq_ref() would need to be defined to return essentially
+the cpuinfo.max_freq value anyway (for example, intel_pstate on
+hybrid platforms).
+
+For the above reasons, update cpufreq_update_pressure() to fall back to
+using cpuinfo.max_freq as the reference frequency if zero is returned by
+arch_scale_freq_ref().
+
+Fixes: 75d659317bb1 ("cpufreq: Add a cpufreq pressure feedback for the scheduler")
+Link: https://lore.kernel.org/lkml/CAKfTPtBuRLfYNnR4w--cFZYZy-R8gaPEgVwCcaMmbCcJ2H-muQ@mail.gmail.com/ [1]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
+Tested-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> # cluster scheduling
+Acked-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://patch.msgid.link/5086499.GXAFRqVoOG@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 17df96564ad6f2..2c86539eb4bc38 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -2601,6 +2601,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
+
+ cpu = cpumask_first(policy->related_cpus);
+ max_freq = arch_scale_freq_ref(cpu);
++ if (!max_freq)
++ max_freq = policy->cpuinfo.max_freq;
++
+ capped_freq = policy->max;
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From ad458b4d0569c558ff5817dc6f9e2c017f4db094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index 833987015b8bbc..ed42b9d05a07d5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -257,7 +257,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From c87f07f9bbae55bf5ae7835576982d9884b6de76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index 33351deeea4f0b..07eaf71955c447 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -16,9 +16,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -28,9 +28,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 038a9aa9829cd78d4e0bb131d5167a6d5d540263 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 15:17:59 -0700
+Subject: drm/xe/wopcm: fix WOPCM size for LNL+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit ad87e2476b3b246580f407afc8ffa91d621bc849 ]
+
+Starting on LNL the WOPCM size is 8MB instead of 4, so we need to avoid
+using the [0, 8MB) range of the GGTT as that can be unaccessible from
+the microcontrollers.
+
+Note that the proper long-term fix here is to read the WOPCM size from
+the HW, but that is a more serious rework that would be difficult to
+backport, so we can do that as a follow-up.
+
+Fixes: 9c57bc08652a ("drm/xe/lnl: Drop force_probe requirement")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Shuicheng Lin <shuicheng.lin@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260713221758.3285744-2-daniele.ceraolospurio@intel.com
+(cherry picked from commit 3033b0b24ed0e2f5e56bdd4d9c183417c365a45b)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wopcm.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c
+index d3a99157e52338..b7de817cce8870 100644
+--- a/drivers/gpu/drm/xe/xe_wopcm.c
++++ b/drivers/gpu/drm/xe/xe_wopcm.c
+@@ -47,9 +47,9 @@
+ */
+
+ /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
+-/* FIXME: Larger size require for 2 tile PVC, do a proper probe sooner or later */
++/* FIXME: Larger size require for some platforms, do a proper probe sooner or later */
+ #define DGFX_WOPCM_SIZE SZ_4M
+-/* FIXME: Larger size require for MTL, do a proper probe sooner or later */
++#define LNL_WOPCM_SIZE SZ_8M
+ #define MTL_WOPCM_SIZE SZ_4M
+ #define WOPCM_SIZE SZ_2M
+
+@@ -179,9 +179,14 @@ static int __wopcm_init_regs(struct xe_device *xe, struct xe_gt *gt,
+
+ u32 xe_wopcm_size(struct xe_device *xe)
+ {
+- return IS_DGFX(xe) ? DGFX_WOPCM_SIZE :
+- xe->info.platform == XE_METEORLAKE ? MTL_WOPCM_SIZE :
+- WOPCM_SIZE;
++ if (xe->info.platform >= XE_LUNARLAKE)
++ return LNL_WOPCM_SIZE;
++ else if (IS_DGFX(xe))
++ return DGFX_WOPCM_SIZE;
++ else if (xe->info.platform == XE_METEORLAKE)
++ return MTL_WOPCM_SIZE;
++ else
++ return WOPCM_SIZE;
+ }
+
+ /**
+--
+2.53.0
+
--- /dev/null
+From 6538923b68474dcb45c4a0bc487c3da7417408bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 67fc9e46001b77..62222c9cfc3e6d 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1029,7 +1029,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From 25daa9a4975add00456e21e1cd85ad83517a137f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 21:54:06 +0000
+Subject: firmware: arm_ffa: Respect firmware advertised RX/TX buffer size
+ limits
+
+From: Seth Forshee <sforshee@nvidia.com>
+
+[ Upstream commit 53716a4d745f1dac7aff33f3d1494b701eb2f888 ]
+
+FFA_FEATURES reports the minimum size and alignment boundary required
+for RXTX_MAP. In FF-A v1.2 and later it can also report a maximum buffer
+size, with zero meaning that no maximum is enforced.
+
+The driver only used the minimum value and then rounded it up to PAGE_SIZE
+before invoking RXTX_MAP after commit 83210251fd70 ("firmware: arm_ffa:
+Use the correct buffer size during RXTX_MAP"). On systems where PAGE_SIZE
+is larger than the advertised minimum, this can exceed a non-zero maximum
+reported by firmware. Older implementations do not advertise a maximum and
+may also reject the rounded-up size.
+
+Decode the maximum size and clamp the page-aligned minimum to it when it
+is present. If no maximum is advertised and RXTX_MAP rejects the rounded
+size with INVALID_PARAMETERS, retry with the advertised minimum size.
+Record drv_info->rxtx_bufsz only after RXTX_MAP succeeds so it reflects
+the size registered with firmware.
+
+While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
+consistency.
+
+Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
+Suggested-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Seth Forshee <sforshee@nvidia.com>
+Link: https://patch.msgid.link/20260602-b4-ffa-rxtx-map-fixes-v2-1-7cb06508da84@nvidia.com
+(sudeep.holla: Minor rewording subject and commit message)
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 3b221ba990aa1e..67fc9e46001b77 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -32,6 +32,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
++#include <linux/minmax.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/mutex.h>
+@@ -55,7 +56,9 @@
+ (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
+
+ #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
+-#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
++#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
++#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
++#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
+
+ #define FFA_MAX_NOTIFICATIONS 64
+
+@@ -1855,7 +1858,7 @@ static int __init ffa_init(void)
+ {
+ int ret;
+ u32 buf_sz;
+- size_t rxtx_bufsz = SZ_4K;
++ size_t rxtx_min_bufsz = SZ_4K, rxtx_max_bufsz = 0, rxtx_bufsz;
+
+ ret = ffa_transport_init(&invoke_ffa_fn);
+ if (ret)
+@@ -1878,15 +1881,18 @@ static int __init ffa_init(void)
+ ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
+ if (!ret) {
+ if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
+- rxtx_bufsz = SZ_64K;
++ rxtx_min_bufsz = SZ_64K;
+ else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
+- rxtx_bufsz = SZ_16K;
++ rxtx_min_bufsz = SZ_16K;
+ else
+- rxtx_bufsz = SZ_4K;
++ rxtx_min_bufsz = SZ_4K;
++
++ rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
++ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
++ rxtx_max_bufsz = rxtx_min_bufsz;
+ }
+
+- rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
+- drv_info->rxtx_bufsz = rxtx_bufsz;
++ rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
+ drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
+ if (!drv_info->rx_buffer) {
+ ret = -ENOMEM;
+@@ -1902,10 +1908,17 @@ static int __init ffa_init(void)
+ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+ virt_to_phys(drv_info->rx_buffer),
+ rxtx_bufsz / FFA_PAGE_SIZE);
++ if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
++ rxtx_bufsz = rxtx_min_bufsz;
++ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
++ virt_to_phys(drv_info->rx_buffer),
++ rxtx_bufsz / FFA_PAGE_SIZE);
++ }
+ if (ret) {
+ pr_err("failed to register FFA RxTx buffers\n");
+ goto free_pages;
+ }
++ drv_info->rxtx_bufsz = rxtx_bufsz;
+
+ mutex_init(&drv_info->rx_lock);
+ mutex_init(&drv_info->tx_lock);
+--
+2.53.0
+
--- /dev/null
+From 5b0782b88de5c075214f488c29e8afaf68367d9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index e160ecb22948fc..f042fb8a050265 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -596,9 +596,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 0d9ad6c0da2e7e3bcc03b58964a5ae5785b3e3b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 73f3a0b9a54b5f..96c1fd8039fb59 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1778,6 +1778,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ &mad_send_wr->mad_agent_priv->done_list);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -1796,6 +1814,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From bce11750e000ea0e0ad0cdec12975b73b3de1441 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index ee47b67a087034..3d2df1d435ae10 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1391,7 +1391,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From 9c36eb6c60a6eb7b6a6983611dd20d030a422de7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 22:49:55 +0800
+Subject: ksmbd: pin conn during async oplock break notification
+
+From: Qihang <q.h.hack.winter@gmail.com>
+
+[ Upstream commit aa5d8f3f96aa11a4a54ce993c11ce8af11c546f9 ]
+
+smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn
+pointer in an async ksmbd_work and then queue that work on ksmbd-io. The
+work only increments conn->r_count, which prevents teardown from passing
+the pending-request wait after the increment, but it does not pin the
+struct ksmbd_conn object.
+
+If connection teardown races with an oplock break notification, the last
+conn reference can be dropped before the queued worker finishes. The
+worker then uses the freed conn in ksmbd_conn_write() and
+ksmbd_conn_r_count_dec().
+
+Take a real conn reference when publishing the conn pointer to the async
+work item, and drop it after the notification work has decremented
+r_count. Apply the same lifetime rule to lease break notification, which
+uses the same work->conn pattern.
+
+Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification")
+Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index a019c4496ae433..ff0dbf3f8cbf49 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -705,6 +705,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -740,7 +741,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
+ br_info->open_trunc = opinfo->open_trunc;
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+@@ -814,6 +815,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -853,7 +855,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
+ memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+--
+2.53.0
+
--- /dev/null
+From 4d62b9f8c29cb59f220168314107d634a98617b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
+index ae501024665e1f..6317edbfe4fa43 100644
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -400,6 +400,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From 34162525ce69d234ee3796e6f5c3642c6fb7449f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 719dabb76ea218..98816e51e01a49 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2123,6 +2123,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From da75999363fe2e95f603290ccd5ecc6496d264f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 20:10:42 +0800
+Subject: mtd: fix double free and WARN_ON in add_mtd_device() error paths
+
+From: Xue Lei <Xue.Lei@windriver.com>
+
+[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]
+
+When device_register() or mtd_nvmem_add() fails inside
+add_mtd_device() for a partition, the error handling triggers
+mtd_release() via put_device() or device_unregister(). mtd_release()
+calls release_mtd_partition() which frees the mtd_info structure.
+However, callers such as mtd_add_partition() and add_mtd_partitions()
+also call free_partition() in their error paths, resulting in a double
+free.
+
+Additionally, release_mtd_partition() hits WARN_ON(!list_empty(
+&mtd->part.node)) because the partition node is still linked in the
+parent's partitions list when the release callback fires from the
+add_mtd_device() error path.
+
+Fix this by overriding dev->type and dev->release before put_device()
+in the error paths, so that device_release() invokes a no-op function
+instead of mtd_release(). For the mtd_nvmem_add() failure case,
+device_unregister() is replaced with device_del() to separate the
+device removal from the final kobject reference drop, allowing the
+override to take effect before put_device() is called.
+
+The callers' error paths (list_del + free_partition) remain the sole
+owners of mtd_info lifetime on add_mtd_device() failure, which is the
+expected contract.
+
+The normal partition teardown path is not affected: del_mtd_device()
+goes through kref_put() -> mtd_device_release() -> device_unregister()
+with dev->type still set to &mtd_devtype, so mtd_release() ->
+release_mtd_partition() continues to work correctly for the regular
+removal case.
+
+Reported-by: syzbot+e9c76b56dc05023b8117@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e9c76b56dc05023b8117
+Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
+Signed-off-by: Xue Lei <Xue.Lei@windriver.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 724f917f91bac0..0c8e8eb5f0f3d8 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -104,6 +104,15 @@ static void mtd_release(struct device *dev)
+ device_destroy(&mtd_class, index + 1);
+ }
+
++/*
++ * No-op device release used in add_mtd_device() error paths.
++ * Prevents mtd_release() from being called via device_release(),
++ * which would free the mtd_info that the caller still manages.
++ */
++static void mtd_dev_release_nop(struct device *dev)
++{
++}
++
+ static void mtd_device_release(struct kref *kref)
+ {
+ struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+@@ -746,10 +755,8 @@ int add_mtd_device(struct mtd_info *mtd)
+ mtd_check_of_node(mtd);
+ of_node_get(mtd_get_of_node(mtd));
+ error = device_register(&mtd->dev);
+- if (error) {
+- put_device(&mtd->dev);
++ if (error)
+ goto fail_added;
+- }
+
+ /* Add the nvmem provider */
+ error = mtd_nvmem_add(mtd);
+@@ -787,8 +794,16 @@ int add_mtd_device(struct mtd_info *mtd)
+ return 0;
+
+ fail_nvmem_add:
+- device_unregister(&mtd->dev);
++ device_del(&mtd->dev);
+ fail_added:
++ /*
++ * Clear type and set nop release to prevent mtd_release() ->
++ * release_mtd_partition() -> free_partition() from freeing mtd.
++ * The caller handles cleanup on failure.
++ */
++ mtd->dev.type = NULL;
++ mtd->dev.release = mtd_dev_release_nop;
++ put_device(&mtd->dev);
+ of_node_put(mtd_get_of_node(mtd));
+ idr_remove(&mtd_idr, i);
+ fail_locked:
+--
+2.53.0
+
--- /dev/null
+From ed3080bc69294bbce6bfc8af627048f630af214d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 680366616da240..4d695875ea1b23 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From da5387a962fc05cf7917829686a320be06ddf820 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/ecc-mtk.c b/drivers/mtd/nand/ecc-mtk.c
+index c75bb8b80cc1e1..96703f0a418ea2 100644
+--- a/drivers/mtd/nand/ecc-mtk.c
++++ b/drivers/mtd/nand/ecc-mtk.c
+@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 16aff95c28bfcce92e63281557927df71ddd2e0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 1a0b41fcea8131..bb54e23397e8c6 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2088,6 +2088,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2137,6 +2139,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 67cc5990b6e42c1dae8a7e1f74c0454f2300cc24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index e296714803dc02..74e9b5ea76a555 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -344,14 +344,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 99cd76b3e8d6a351ab289ebb81902dbd26e9aba1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 21:33:09 -0700
+Subject: powerpc/85xx: Add fsl,ifc to common device ids
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 25957f7c3dac3265332d766b71233e3622f17e14 ]
+
+Add fsl,ifc to mpc85xx_common_ids so that of_platform_bus_probe
+creates a platform device for the IFC node even without 'simple-bus'
+in its compatible property. On P1010 and similar platforms the IFC
+node is a direct child of the root, so it must be explicitly matched
+to be populated.
+
+Fixes: 0bf51cc9e9e5 ("powerpc: dts: mpc85xx: remove "simple-bus" compatible from ifc node")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260604043309.91280-1-rosenp@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/85xx/common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
+index 757811155587db..c11deb2f50ed45 100644
+--- a/arch/powerpc/platforms/85xx/common.c
++++ b/arch/powerpc/platforms/85xx/common.c
+@@ -42,6 +42,8 @@ static const struct of_device_id mpc85xx_common_ids[] __initconst = {
+ { .compatible = "fsl,qoriq-pcie-v2.3", },
+ { .compatible = "fsl,qoriq-pcie-v2.2", },
+ { .compatible = "fsl,fman", },
++ /* IFC NAND and NOR controllers */
++ { .compatible = "fsl,ifc", },
+ {},
+ };
+
+--
+2.53.0
+
--- /dev/null
+From bc67335d172b49f378ea40624c4a7f715da419de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2026 15:16:37 +0200
+Subject: powerpc/time: Prepare to stop elapsing in dynticks-idle
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit c8ba971cf8567d49eb5f43ee90c4e50424331c18 ]
+
+Currently the tick subsystem stores the idle cputime accounting in
+private fields, allowing cohabitation with architecture idle vtime
+accounting. The former is fetched on online CPUs, the latter on offline
+CPUs.
+
+For consolidation purpose, architecture vtime accounting will continue
+to account the cputime but will make a break when the idle tick is
+stopped. The dyntick cputime accounting will then be relayed by the tick
+subsystem so that the idle cputime is still seen advancing coherently
+even when the tick isn't there to flush the idle vtime.
+
+Prepare for that and introduce three new APIs which will be used in
+subsequent patches:
+
+ - vtime_dynticks_start() is deemed to be called when idle enters in
+ dyntick mode. The idle cputime that elapsed so far is accumulated.
+
+ - vtime_dynticks_stop() is deemed to be called when idle exits from
+ dyntick mode. The vtime entry clocks are fast-forward to current time
+ so that idle accounting restarts elapsing from now.
+
+ - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
+ fast-forward the clock to current time so that the IRQ time is still
+ accounted by vtime while nohz cputime is paused.
+
+Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
+accounting twice the idle cputime, along with nohz accounting.
+
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Link: https://patch.msgid.link/20260508131647.43868-6-frederic@kernel.org
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
+ include/linux/vtime.h | 6 ++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index ce7f91172ec2b6..c8beb00e6a27c6 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
+ acct->starttime = acct0->starttime;
+ }
+ }
++
++#ifdef CONFIG_NO_HZ_COMMON
++/**
++ * vtime_reset - Fast forward vtime entry clocks
++ *
++ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
++ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
++ */
++void vtime_reset(void)
++{
++ struct cpu_accounting_data *acct = get_accounting(current);
++
++ acct->starttime = mftb();
++#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
++ acct->startspurr = read_spurr(acct->starttime);
++#endif
++}
++
++/**
++ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
++ *
++ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
++ * is accumulated and the tick subsystem takes over the idle cputime accounting.
++ */
++void vtime_dyntick_start(void)
++{
++ vtime_account_idle(current);
++}
++
++/**
++ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
++ *
++ * Called when idle exits from dyntick mode. The vtime entry clocks are
++ * fast-forward to current time so that idle accounting restarts elapsing from
++ * now.
++ */
++void vtime_dyntick_stop(void)
++{
++ vtime_reset();
++}
++#endif /* CONFIG_NO_HZ_COMMON */
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/include/linux/vtime.h b/include/linux/vtime.h
+index 29dd5b91dd7d66..3fc04b849e4e30 100644
+--- a/include/linux/vtime.h
++++ b/include/linux/vtime.h
+@@ -32,11 +32,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
+ extern void vtime_account_softirq(struct task_struct *tsk);
+ extern void vtime_account_hardirq(struct task_struct *tsk);
+ extern void vtime_flush(struct task_struct *tsk);
++extern void vtime_reset(void);
++extern void vtime_dyntick_start(void);
++extern void vtime_dyntick_stop(void);
+ #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+ static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
+ static inline void vtime_account_softirq(struct task_struct *tsk) { }
+ static inline void vtime_account_hardirq(struct task_struct *tsk) { }
+ static inline void vtime_flush(struct task_struct *tsk) { }
++static inline void vtime_reset(void) { }
++static inline void vtime_dyntick_start(void) { }
++static inline void vtime_dyntick_stop(void) { }
+ #endif
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 5bbe93ca196fa142272229eb8166e346b4ac3a10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:13:29 +0530
+Subject: powerpc/vtime: Initialize starttime at boot for native accounting
+
+From: Shrikanth Hegde <sshegde@linux.ibm.com>
+
+[ Upstream commit c1c1ffa490fc33591e90852ed0d38804dd20bc36 ]
+
+It was observed that /proc/stat had very large value for one ore more
+CPUs. It was more visible after recent code simplifications around
+cpustats.
+
+System has 240 CPUs.
+
+cat /proc/uptime;
+194.18 46500.55
+cat /proc/stat
+cpu 5966 39 837032887 4650070 164 185 100 0 0 0
+cpu0 108 0 837030890 19109 24 4 23 0 0 0
+
+Since uptime is 194s, system time of each CPU can't be more than 19400.
+Sum of system time of all CPUs can't be more than 19400*240 4656000.
+In fact huge value is close to mftb(). Note mftb doesn't reset on powerVM
+when the LPAR restart. It only resets when whole system resets. The same
+issue exists for kexec too.
+
+This happens since starttime is not setup at init time. Once it is set
+then subsequent vtime_delta will return the right delta.
+
+Fix it by initializing the starttime during CPU initialization. This
+fixes the large times seen.
+
+cat /proc/uptime; cat /proc/stat
+15.78 3694.63
+cpu 6035 35 1347 369479 23 144 49 0 0 0
+cpu0 19 0 38 1508 0 1 14 0 0 0
+
+Now, system time is reported as expected.
+
+Fixes: cf9efce0ce31 ("powerpc: Account time using timebase rather than PURR")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Suggested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260605124329.377533-1-sshegde@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index c8beb00e6a27c6..c69c0f23f5212a 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -377,7 +377,6 @@ void vtime_task_switch(struct task_struct *prev)
+ }
+ }
+
+-#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_reset - Fast forward vtime entry clocks
+ *
+@@ -394,6 +393,7 @@ void vtime_reset(void)
+ #endif
+ }
+
++#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
+ *
+@@ -927,6 +927,7 @@ static void __init set_decrementer_max(void)
+ static void __init init_decrementer_clockevent(void)
+ {
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ void secondary_cpu_time_init(void)
+@@ -942,6 +943,7 @@ void secondary_cpu_time_init(void)
+ /* FIME: Should make unrelated change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ /* This function is only called on the boot processor */
+--
+2.53.0
+
--- /dev/null
+From dfd5c0865567cf7ec80277635d848d98f07a6caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index c70994c6a265e3..9f787adef3eb38 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -192,6 +192,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ rwlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3555,6 +3556,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Free up the resources used by a ppp channel.
+ */
+@@ -3570,9 +3583,7 @@ static void ppp_destroy_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3585,6 +3596,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(&ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_unregister(&ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From a4d5bde1224f9e1263b18e6dae0d4abf908ce845 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:21:05 +0300
+Subject: RDMA/cma: Fix hardware address comparison length in netevent callback
+
+From: Or Gerlitz <ogerlitz@ddn.com>
+
+[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
+
+The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
+
+This breaks IPoIB, which uses 20-byte addresses. By truncating the
+memcmp, the CMA may incorrectly assume the target address is
+unchanged and fails to abort the stalled connection.
+
+Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len
+to correctly evaluate the full address regardless of the link layer.
+
+Fixes: 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
+Signed-off-by: Or Gerlitz <ogerlitz@ddn.com>
+Link: https://patch.msgid.link/20260617-fix-cma-ipoib-v1-1-03f869344304@ddn.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 52d70eeb0c52ec..a225eae78d3e58 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5231,7 +5231,7 @@ static int cma_netevent_callback(struct notifier_block *self,
+
+ list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
+ if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
+- neigh->ha, ETH_ALEN))
++ neigh->ha, neigh->dev->addr_len))
+ continue;
+ cma_id_get(current_id);
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
+--
+2.53.0
+
--- /dev/null
+From 0d5b0bd4b766029cb385997e9dc4f631537b9728 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:51 +0800
+Subject: RDMA/erdma: initialize ret for empty receive WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
+
+erdma_post_recv() returns ret after walking the receive work request list.
+If the caller passes an empty list, the loop is skipped and ret is not
+assigned.
+
+Initialize ret to 0 so an empty receive work request list returns success
+instead of stack data.
+
+Fixes: 155055771704 ("RDMA/erdma: Add verbs implementation")
+Link: https://patch.msgid.link/r/20260618041752.481193-1-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_qp.c b/drivers/infiniband/hw/erdma/erdma_qp.c
+index 4d1f9114cd97c5..4dfab0c49e5192 100644
+--- a/drivers/infiniband/hw/erdma/erdma_qp.c
++++ b/drivers/infiniband/hw/erdma/erdma_qp.c
+@@ -573,7 +573,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
+ const struct ib_recv_wr *wr = recv_wr;
+ struct erdma_qp *qp = to_eqp(ibqp);
+ unsigned long flags;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&qp->lock, flags);
+
+--
+2.53.0
+
--- /dev/null
+From 531dbf51e2ed6f22a6bafbb97ef0bd715198230f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 1680d0ac071ed1..ae7a3939124f23 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -842,7 +842,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From 422063da335107369283cdf5941aac671ea5411f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 255c6d21756ba4..d8e101fc74ff73 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2367,7 +2367,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2400,7 +2400,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From 0e5b4b0e7d77ce89e7ace8cceb8ee9c6a4c964a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:19:36 +0000
+Subject: RDMA/irdma: Prevent rereg_mr for non-mem regions
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]
+
+When a QP/CQ/SRQ is created, a two step process is used
+where the buffer is allocated in userspace and explicitly
+registered with the normal reg_mr mechanism prior to creating
+the actual QP/CQ/SRQ object.
+
+These special registrations are indicated via an ABI field
+so the driver knows that they do not have a valid mkey and
+to skip the actual CQP command submission.
+
+Since these are real MR objects from the core's perspective,
+it is possible for a user application to invoke rereg_mr on them
+and cause a real CQP op to be emitted with the zero-initialized
+mkey value of 0.
+
+Fix this by preventing rereg_mr on these special regions.
+
+Fixes: 5ac388db27c4 ("RDMA/irdma: Add support to re-register a memory region")
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 92b56338819ef8..255c6d21756ba4 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -3252,6 +3252,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
+ return ERR_PTR(-EOPNOTSUPP);
+
++ if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
++ return ERR_PTR(-EINVAL);
++
+ ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
+ if (ret)
+ return ERR_PTR(ret);
+--
+2.53.0
+
--- /dev/null
+From d5e9c1b8f83ca3801cb14af397549581eaafd4bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index d0c0cde09f1186..8ecff632ab6f3d 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -317,6 +317,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -370,11 +371,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -392,14 +388,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -425,7 +421,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -440,11 +436,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -453,7 +446,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -465,9 +458,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -477,22 +484,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From e35a6d16e9bbf2a5f83633126b83eb48547cac61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:24 +0000
+Subject: RDMA/umem: Add pinned revocable dmabuf import interface
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c ]
+
+Added an interface for importing a pinned but revocable dmabuf.
+This interface can be used by drivers that are capable of revocation
+so that they can import dmabufs from exporters that may require it,
+such as VFIO.
+
+This interface implements a two step process, where drivers will first
+call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and
+map the dmabuf (and provide a functional move_notify/invalidate_mappings
+callback), but will return with the lock still held so that the
+driver can then populate the callback via
+ib_umem_dmabuf_set_revoke_locked() without races from concurrent
+revocations. This scheme also allows for easier integration with drivers
+that may not have actually allocated their internal MR objects at the time
+of the get_pinned_revocable* call.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-4-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 61 +++++++++++++++++++++++++++
+ include/rdma/ib_umem.h | 19 +++++++++
+ 2 files changed, 80 insertions(+)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index f16491bd5f2b11..1206993e2e3e83 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -206,6 +206,10 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+
+ if (umem_dmabuf->revoked)
+ return;
++
++ if (umem_dmabuf->pinned_revoke)
++ umem_dmabuf->pinned_revoke(umem_dmabuf->private);
++
+ ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+ if (umem_dmabuf->pinned) {
+ dma_buf_unpin(umem_dmabuf->attach);
+@@ -214,6 +218,11 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+ umem_dmabuf->revoked = 1;
+ }
+
++static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = {
++ .allow_peer2peer = true,
++ .move_notify = ib_umem_dmabuf_revoke_locked,
++};
++
+ static struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
+ struct device *dma_device,
+@@ -266,6 +275,58 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
+
++/**
++ * ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf
++ * @device: IB device.
++ * @offset: Start offset.
++ * @size: Length.
++ * @fd: dmabuf fd.
++ * @access: Access flags.
++ *
++ * Obtains a umem from a dmabuf for drivers/devices that can support revocation.
++ *
++ * Returns with dma_resv_lock held upon success. The driver must set the revoke
++ * callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked().
++ *
++ * When a revocation occurs, the revoke callback will be called. The driver must
++ * ensure that the region is no longer accessed when the callback returns. Any
++ * subsequent access attempts should also probably cause an AE for MRs.
++ *
++ * If the umem is used for an MR, the driver must ensure that the key remains in
++ * use such that it cannot be obtained by a new region until this region is
++ * fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with
++ * revoke calls, it can use dma_resv_lock.
++ *
++ * If successful, then the revoke callback may be called at any time and will
++ * also be called automatically upon ib_umem_release (serialized). The revoke
++ * callback will be called one time at most.
++ *
++ * Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure.
++ */
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ const struct dma_buf_attach_ops *ops =
++ &ib_umem_dmabuf_attach_pinned_revocable_ops;
++
++ return ib_umem_dmabuf_get_pinned_and_lock(device, device->dma_device,
++ offset, size, fd, access,
++ ops);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_revocable_and_lock);
++
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv)
++{
++ dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
++
++ umem_dmabuf->pinned_revoke = revoke;
++ umem_dmabuf->private = priv;
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_set_revoke_locked);
++
+ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ unsigned long offset,
+ size_t size, int fd,
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 694f7e0876af81..4c5329b504d0cb 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -36,6 +36,7 @@ struct ib_umem_dmabuf {
+ struct scatterlist *last_sg;
+ unsigned long first_sg_offset;
+ unsigned long last_sg_trim;
++ void (*pinned_revoke)(void *priv);
+ void *private;
+ u8 pinned : 1;
+ u8 revoked : 1;
+@@ -124,6 +125,12 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ size_t size, int fd,
+ int access);
+ struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access);
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv);
++struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+ unsigned long offset, size_t size,
+@@ -180,6 +187,18 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
++static inline struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ return ERR_PTR(-EOPNOTSUPP);
++}
++
++static inline void
++ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv) {}
++
+ static inline struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+--
+2.53.0
+
--- /dev/null
+From f998c0296582ff7f15b9646dc0f791450de7741c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 17:30:56 -0700
+Subject: riscv: hwprobe: Avoid uninitialized read in hwprobe_get_cpus()
+
+From: Mark Harris <mark.hsj@gmail.com>
+
+[ Upstream commit 5caae1deee89a6582c761d5dcd4b924b744426cc ]
+
+When cpusetsize < cpumask_size(), hwprobe_get_cpus() did not fully
+initialize its copy of the cpu mask, which could cause non-deterministic
+results from the riscv_hwprobe syscall on a system with more than 8 CPUs
+when the supplied cpu mask is empty. Address this by fully initializing
+the cpu mask.
+
+Fixes: e178bf146e4b ("RISC-V: hwprobe: Introduce which-cpus flag")
+Signed-off-by: Mark Harris <mark.hsj@gmail.com>
+Reviewed-by: Nam Cao <namcao@linutronix.de>
+Reviewed-by: Michael Ellerman <mpe@kernel.org>
+Link: https://patch.msgid.link/20260714003056.73707-1-mark.hsj@gmail.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/sys_hwprobe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
+index fc62548888c587..d273080bec34d8 100644
+--- a/arch/riscv/kernel/sys_hwprobe.c
++++ b/arch/riscv/kernel/sys_hwprobe.c
+@@ -336,6 +336,7 @@ static int hwprobe_get_cpus(struct riscv_hwprobe __user *pairs,
+ if (cpusetsize > cpumask_size())
+ cpusetsize = cpumask_size();
+
++ cpumask_clear(&cpus);
+ ret = copy_from_user(&cpus, cpus_user, cpusetsize);
+ if (ret)
+ return -EFAULT;
+--
+2.53.0
+
--- /dev/null
+From f3f1dced11fa36b35f852be47b10715556bc1ec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:02:14 +0200
+Subject: s390/checksum: Fix csum_partial() without vector facility
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+[ Upstream commit 4bb06b60d982355e22647b3d12d6619419f8c1fa ]
+
+Currently csum_partial() calls csum_copy() with copy=false and dst=NULL.
+On machines without the vector facility, csum_copy() falls back to
+cksm(dst, ...), causing the checksum to be calculated from address zero
+instead of the source buffer.
+
+The VX implementation already checksums data loaded from src. Make the
+fallback do the same by passing src to cksm().
+
+Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/lib/csum-partial.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/lib/csum-partial.c b/arch/s390/lib/csum-partial.c
+index 458abd9bac7025..9d74ceff136c54 100644
+--- a/arch/s390/lib/csum-partial.c
++++ b/arch/s390/lib/csum-partial.c
+@@ -23,7 +23,7 @@ static __always_inline __wsum csum_copy(void *dst, const void *src, int len, __w
+ if (!cpu_has_vx()) {
+ if (copy)
+ memcpy(dst, src, len);
+- return cksm(dst, len, sum);
++ return cksm(src, len, sum);
+ }
+ kernel_fpu_begin(&vxstate, KERNEL_VXR_V16V23);
+ fpu_vlvgf(16, (__force u32)sum, 1);
+--
+2.53.0
+
--- /dev/null
+From 65589fc197720ae32b3049459c74d3a460ffd54e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 13:46:30 -0400
+Subject: scsi: core: wake eh reliably when using scsi_schedule_eh
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit dccf3b1798b70f94e958b3d00b83010399e6fb05 ]
+
+Drivers which use the scsi_schedule_eh function to run the error handler
+currently risk the error handler thread never waking once all commands are
+timed out or inactive. There is no enforced memory order between setting
+the host into error recovery state and counting busy commands. This can
+result in a race with scsi_dec_host_busy where neither CPU sees both
+conditions of all commands inactive and the host error state to request
+waking the error handler.
+
+To fix this, run the scsi_schedule_eh's scsi_eh_wakeup from a new work item
+which will use rcu to ensure scsi_schedule_eh's call to scsi_host_busy will
+occur after the error state is globally visible and will be seen by any
+current scsi_dec_host_busy callers.
+
+Fixes: 6eb045e092ef ("scsi: core: avoid host-wide host_busy counter for scsi_mq")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Link: https://patch.msgid.link/20260615174630.11492-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hosts.c | 2 ++
+ drivers/scsi/scsi_error.c | 22 +++++++++++++++++++++-
+ drivers/scsi/scsi_priv.h | 1 +
+ include/scsi/scsi_host.h | 3 +++
+ 4 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index 5cf13d019a15e9..e617b98ce84cf2 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -343,6 +343,7 @@ static void scsi_host_dev_release(struct device *dev)
+ /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
+ rcu_barrier();
+
++ cancel_work_sync(&shost->eh_work);
+ if (shost->tmf_work_q)
+ destroy_workqueue(shost->tmf_work_q);
+ if (shost->ehandler)
+@@ -408,6 +409,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
+ INIT_LIST_HEAD(&shost->starved_list);
+ init_waitqueue_head(&shost->host_wait);
+ mutex_init(&shost->scan_mutex);
++ INIT_WORK(&shost->eh_work, scsi_rcu_eh_wakeup);
+
+ index = ida_alloc(&host_index_ida, GFP_KERNEL);
+ if (index < 0) {
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 9a89a94784cd0c..03fadefa1cee8e 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -73,6 +73,26 @@ void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy)
+ }
+ }
+
++void scsi_rcu_eh_wakeup(struct work_struct *work)
++{
++ struct Scsi_Host *shost = container_of(work, struct Scsi_Host, eh_work);
++ unsigned long flags;
++ unsigned int busy;
++
++ /*
++ * Ensure any running scsi_dec_host_busy has completed its rcu section
++ * so changes to host state and host_eh_scheduled are visible to all
++ * future calls of scsi_dec_host_busy
++ */
++ synchronize_rcu();
++
++ busy = scsi_host_busy(shost);
++
++ spin_lock_irqsave(shost->host_lock, flags);
++ scsi_eh_wakeup(shost, busy);
++ spin_unlock_irqrestore(shost->host_lock, flags);
++}
++
+ /**
+ * scsi_schedule_eh - schedule EH for SCSI host
+ * @shost: SCSI host to invoke error handling on.
+@@ -88,7 +108,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
+ if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 ||
+ scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) {
+ shost->host_eh_scheduled++;
+- scsi_eh_wakeup(shost, scsi_host_busy(shost));
++ queue_work(shost->tmf_work_q, &shost->eh_work);
+ }
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
+index 9fc397a9ce7a4f..7238d53883be76 100644
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -93,6 +93,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req);
+ extern int scsi_error_handler(void *host);
+ extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd);
+ extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy);
++extern void scsi_rcu_eh_wakeup(struct work_struct *work);
+ extern void scsi_eh_scmd_add(struct scsi_cmnd *);
+ void scsi_eh_ready_devs(struct Scsi_Host *shost,
+ struct list_head *work_q,
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 2b4ab0369ffbe9..990747f803feff 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -718,6 +718,9 @@ struct Scsi_Host {
+ */
+ struct device *dma_dev;
+
++ /* Used for an rcu-synchronizing eh wakeup */
++ struct work_struct eh_work;
++
+ /* Delay for runtime autosuspend */
+ int rpm_autosuspend_delay;
+
+--
+2.53.0
+
--- /dev/null
+From 7099f6185576902bb93608616b93977cad205668 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index dcd288fa1bb6fb..d20c28c3105664 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -319,7 +319,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
--- /dev/null
+From b1fb19de8fb01ead98d1810c76471e95f7b76e48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:27:36 +0530
+Subject: selftests/alsa: Fix memory leak in find_controls error path
+
+From: Malaya Kumar Rout <malayarout91@gmail.com>
+
+[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
+
+In find_controls(), card_data is allocated with malloc() but when
+snd_ctl_open_lconf() fails, the code jumps to next_card without
+freeing the allocated memory. This results in a memory leak for
+each card where snd_ctl_open_lconf() fails.
+
+Add free(card_data) before goto next_card to ensure proper cleanup
+of the allocated memory in the error path.
+
+Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
+Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
+Link: https://patch.msgid.link/20260704105736.94874-1-malayarout91@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/alsa/mixer-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
+index 2a4b2662035efc..2964f02ffd9d3c 100644
+--- a/tools/testing/selftests/alsa/mixer-test.c
++++ b/tools/testing/selftests/alsa/mixer-test.c
+@@ -84,6 +84,7 @@ static void find_controls(void)
+ if (err < 0) {
+ ksft_print_msg("Failed to get hctl for card %d: %s\n",
+ card, snd_strerror(err));
++ free(card_data);
+ goto next_card;
+ }
+
+--
+2.53.0
+
soc-qcom-ice-allow-explicit-votes-on-iface-clock-for.patch
mm-refactor-mm_access-to-not-return-null.patch
posix-cpu-timers-prevent-uaf-caused-by-non-leader-ex.patch
+arm64-tegra-fix-cpu-compatible-string-to-cortex-a78a.patch
+firmware-arm_ffa-respect-firmware-advertised-rx-tx-b.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+rdma-cma-fix-hardware-address-comparison-length-in-n.patch
+rdma-umem-add-pinned-revocable-dmabuf-import-interfa.patch
+rdma-irdma-prevent-rereg_mr-for-non-mem-regions.patch
+rdma-erdma-initialize-ret-for-empty-receive-wr-lists.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-publish-qp-after-initialization.patch
+mtd-fix-double-free-and-warn_on-in-add_mtd_device-er.patch
+selftests-alsa-fix-memory-leak-in-find_controls-erro.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm6-clear-dst.dev-on-error-to-avoid-double-netdev_.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-mac80211-fix-unsol_bcast_probe_resp-double-free.patch
+wifi-mac80211-fix-fils_discovery-double-free-on-allo.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-cfg80211-pass-net_device-to-.set_monitor_channe.patch
+wifi-cfg80211-define-and-use-wiphy-guard.patch
+wifi-cfg80211-convert-pmsr_free_wk-to-wiphy_work-to-.patch
+wifi-nl80211-free-rnr-data-on-mbssid-mismatch.patch
+wifi-cfg80211-derive-s1g-beacon-tsf-from-s1g-fields.patch
+wifi-nl80211-validate-nested-mbssid-ie-blobs.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-amd-ps-fix-wrong-acp-version-string-in-pci_requ.patch
+asoc-cs42l43-correct-report-for-forced-microphone-ja.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+cpufreq-make-cpufreq_update_pressure-fall-back-to-cp.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+udmabuf-ensure-to-perform-cache-synchronisation-in-b.patch
+scsi-core-wake-eh-reliably-when-using-scsi_schedule_.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-use-platform_get_irq.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+accel-ivpu-fix-wrong-register-read-in-lnl-failure-di.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+bluetooth-mgmt-revalidate-load_conn_param-queued-upd.patch
+bluetooth-mgmt-fix-locking-in-unpair_device-disconne.patch
+bluetooth-mgmt-hold-reference-for-hci_conn-in-mgmt_p.patch
+bluetooth-hci_qca-clear-memdump-state-on-invalid-dum.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+powerpc-85xx-add-fsl-ifc-to-common-device-ids.patch
+powerpc-time-prepare-to-stop-elapsing-in-dynticks-id.patch
+powerpc-vtime-initialize-starttime-at-boot-for-nativ.patch
+bpf-sockmap-reject-unhashed-udp-sockets-on-sockmap-u.patch
+s390-checksum-fix-csum_partial-without-vector-facili.patch
+riscv-hwprobe-avoid-uninitialized-read-in-hwprobe_ge.patch
+can-j1939-fix-lockless-local-destination-check.patch
+drm-xe-wopcm-fix-wopcm-size-for-lnl.patch
+smb-move-some-duplicate-definitions-to-common-cifsgl.patch
+ksmbd-pin-conn-during-async-oplock-break-notificatio.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From 201cb945100d190bc06a815237799c43e2dbdfe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index f63361bc1641d5..61309fead04e57 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3482,6 +3482,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3518,13 +3519,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3541,11 +3550,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 6b9ce022a6417b074c455489d898b487f971ec38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Oct 2025 00:17:30 +0800
+Subject: smb: move some duplicate definitions to common/cifsglob.h
+
+From: ZhangGuoDong <zhangguodong@kylinos.cn>
+
+[ Upstream commit d877470b59910b5c50383d634dda3782386bba51 ]
+
+In order to maintain the code more easily, move duplicate definitions to
+new common header file.
+
+Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: aa5d8f3f96aa ("ksmbd: pin conn during async oplock break notification")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 19 +------------------
+ fs/smb/common/cifsglob.h | 30 ++++++++++++++++++++++++++++++
+ fs/smb/server/smb_common.h | 14 +-------------
+ 3 files changed, 32 insertions(+), 31 deletions(-)
+ create mode 100644 fs/smb/common/cifsglob.h
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index dcfadbc20723f0..c054ee44269416 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -25,6 +25,7 @@
+ #include "cifsacl.h"
+ #include <crypto/internal/hash.h>
+ #include <uapi/linux/cifs/cifs_mount.h>
++#include "../common/cifsglob.h"
+ #include "../common/smb2pdu.h"
+ #include "smb2pdu.h"
+ #include <linux/filelock.h>
+@@ -669,12 +670,6 @@ get_rfc1002_length(void *buf)
+ return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
+ }
+
+-static inline void
+-inc_rfc1001_len(void *buf, int count)
+-{
+- be32_add_cpu((__be32 *)buf, count);
+-}
+-
+ struct TCP_Server_Info {
+ struct list_head tcp_ses_list;
+ struct list_head smb_ses_list;
+@@ -986,8 +981,6 @@ compare_mid(__u16 mid, const struct smb_hdr *smb)
+ #define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
+ #define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
+
+-#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
+-
+ /*
+ * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
+ * those values when posix extensions aren't in force. In actuality here, we
+@@ -2094,30 +2087,20 @@ extern mempool_t cifs_io_request_pool;
+ extern mempool_t cifs_io_subrequest_pool;
+
+ /* Operations for different SMB versions */
+-#define SMB1_VERSION_STRING "1.0"
+-#define SMB20_VERSION_STRING "2.0"
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+ extern struct smb_version_operations smb1_operations;
+ extern struct smb_version_values smb1_values;
+ extern struct smb_version_operations smb20_operations;
+ extern struct smb_version_values smb20_values;
+ #endif /* CIFS_ALLOW_INSECURE_LEGACY */
+-#define SMB21_VERSION_STRING "2.1"
+ extern struct smb_version_operations smb21_operations;
+ extern struct smb_version_values smb21_values;
+-#define SMBDEFAULT_VERSION_STRING "default"
+ extern struct smb_version_values smbdefault_values;
+-#define SMB3ANY_VERSION_STRING "3"
+ extern struct smb_version_values smb3any_values;
+-#define SMB30_VERSION_STRING "3.0"
+ extern struct smb_version_operations smb30_operations;
+ extern struct smb_version_values smb30_values;
+-#define SMB302_VERSION_STRING "3.02"
+-#define ALT_SMB302_VERSION_STRING "3.0.2"
+ /*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */
+ extern struct smb_version_values smb302_values;
+-#define SMB311_VERSION_STRING "3.1.1"
+-#define ALT_SMB311_VERSION_STRING "3.11"
+ extern struct smb_version_operations smb311_operations;
+ extern struct smb_version_values smb311_values;
+
+diff --git a/fs/smb/common/cifsglob.h b/fs/smb/common/cifsglob.h
+new file mode 100644
+index 00000000000000..00fd215e3eb547
+--- /dev/null
++++ b/fs/smb/common/cifsglob.h
+@@ -0,0 +1,30 @@
++/* SPDX-License-Identifier: LGPL-2.1 */
++/*
++ *
++ * Copyright (C) International Business Machines Corp., 2002,2008
++ * Author(s): Steve French (sfrench@us.ibm.com)
++ * Jeremy Allison (jra@samba.org)
++ *
++ */
++#ifndef _COMMON_CIFS_GLOB_H
++#define _COMMON_CIFS_GLOB_H
++
++static inline void inc_rfc1001_len(void *buf, int count)
++{
++ be32_add_cpu((__be32 *)buf, count);
++}
++
++#define SMB1_VERSION_STRING "1.0"
++#define SMB20_VERSION_STRING "2.0"
++#define SMB21_VERSION_STRING "2.1"
++#define SMBDEFAULT_VERSION_STRING "default"
++#define SMB3ANY_VERSION_STRING "3"
++#define SMB30_VERSION_STRING "3.0"
++#define SMB302_VERSION_STRING "3.02"
++#define ALT_SMB302_VERSION_STRING "3.0.2"
++#define SMB311_VERSION_STRING "3.1.1"
++#define ALT_SMB311_VERSION_STRING "3.11"
++
++#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
++
++#endif /* _COMMON_CIFS_GLOB_H */
+diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
+index a3d8a905b07e07..a353e187dfd7ad 100644
+--- a/fs/smb/server/smb_common.h
++++ b/fs/smb/server/smb_common.h
+@@ -10,6 +10,7 @@
+
+ #include "glob.h"
+ #include "nterr.h"
++#include "../common/cifsglob.h"
+ #include "../common/smb2pdu.h"
+ #include "smb2pdu.h"
+
+@@ -26,16 +27,8 @@
+ #define SMB311_PROT 6
+ #define BAD_PROT 0xFFFF
+
+-#define SMB1_VERSION_STRING "1.0"
+-#define SMB20_VERSION_STRING "2.0"
+-#define SMB21_VERSION_STRING "2.1"
+-#define SMB30_VERSION_STRING "3.0"
+-#define SMB302_VERSION_STRING "3.02"
+-#define SMB311_VERSION_STRING "3.1.1"
+-
+ #define SMB_ECHO_INTERVAL (60 * HZ)
+
+-#define CIFS_DEFAULT_IOSIZE (64 * 1024)
+ #define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
+
+ #define MAX_STREAM_PROT_LEN 0x00FFFFFF
+@@ -462,9 +455,4 @@ static inline unsigned int get_rfc1002_len(void *buf)
+ {
+ return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
+ }
+-
+-static inline void inc_rfc1001_len(void *buf, int count)
+-{
+- be32_add_cpu((__be32 *)buf, count);
+-}
+ #endif /* __SMB_COMMON_H__ */
+--
+2.53.0
+
--- /dev/null
+From b2236dba4de5fe82fca7b297be9da43657b6a1be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 12:57:25 +0200
+Subject: udmabuf: Ensure to perform cache synchronisation in
+ begin_cpu_udmabuf()
+
+From: Robert Mader <robert.mader@collabora.com>
+
+[ Upstream commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 ]
+
+The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to
+fix cacheline EEXIST warning") says:
+
+> The CPU sync at map/unmap time is also redundant for udmabuf:
+> begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit
+> cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU
+> access is requested through the dma-buf interface.
+
+This, however, does not apply to the first time begin_cpu_udmabuf() is
+called on an udmabuf, in which case the implementation previously relied on
+get_sg_table() to perform the cache synchronisation.
+
+Ensure to call dma_sync_sgtable_for_cpu() in that case as well.
+
+Fixes: 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning")
+Signed-off-by: Robert Mader <robert.mader@collabora.com>
+Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
+Link: https://patch.msgid.link/20260627105725.9083-1-robert.mader@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma-buf/udmabuf.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index 5c92834f3fc86d..b81fd91e30e777 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -207,21 +207,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
+ {
+ struct udmabuf *ubuf = buf->priv;
+ struct device *dev = ubuf->device->this_device;
+- int ret = 0;
+
+ if (!ubuf->sg) {
+ ubuf->sg = get_sg_table(dev, buf, direction);
+ if (IS_ERR(ubuf->sg)) {
++ int ret;
++
+ ret = PTR_ERR(ubuf->sg);
+ ubuf->sg = NULL;
++ return ret;
+ } else {
+ ubuf->sg_dir = direction;
+ }
+- } else {
+- dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
+ }
+
+- return ret;
++ dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
++ return 0;
+ }
+
+ static int end_cpu_udmabuf(struct dma_buf *buf,
+--
+2.53.0
+
--- /dev/null
+From 4040c843abf926d16817742de708e2df1a150c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 71bb8b699731ba..a1b26144607698 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4458,6 +4458,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4471,7 +4472,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From 0b551a5d3f41fd078eeaed53139965b4868008dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index b249f29454f9e1..3c439841578c49 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -205,7 +205,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 927933b48d9b4deb3dedd3103591ac4598d36dd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 46e70f2e39ccf9..556b0d859d2dea 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1174,6 +1174,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From 03f1b49e5d7ad52c6cec34ccac5420ea1e0791f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:55:23 +0530
+Subject: wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock
+
+From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+
+[ Upstream commit 2b0eab425e1f658d8fe1df7590e3b9af5959505e ]
+
+When a netlink socket that owns a PMSR session is closed,
+cfg80211_release_pmsr() clears the request's nl_portid and queues
+pmsr_free_wk to call cfg80211_pmsr_process_abort() asynchronously.
+
+If the interface tears down concurrently, cfg80211_pmsr_wdev_down()
+is called under wiphy_lock and calls cancel_work_sync(&pmsr_free_wk)
+to wait for any running work. The work function acquires wiphy_lock
+via guard(wiphy) before calling process_abort.
+
+This is a deadlock: wdev_down holds wiphy_lock and blocks inside
+cancel_work_sync(); pmsr_free_wk blocks trying to acquire that same
+wiphy_lock. Neither thread can proceed.
+
+The same deadlock is reachable from cfg80211_leave_locked(), which
+calls cfg80211_pmsr_wdev_down() for all interface types under
+wiphy_lock.
+
+Fix this by converting pmsr_free_wk from a plain work_struct to a
+wiphy_work. The wiphy_work dispatcher holds wiphy_lock when running
+work items, so the explicit guard(wiphy) in the work function is no
+longer needed. wiphy_work_cancel() can be called safely while holding
+wiphy_lock - since wiphy_lock prevents the work from running
+concurrently, wiphy_work_cancel() never blocks, eliminating the
+deadlock.
+
+Remove the cancel_work_sync() for pmsr_free_wk from the
+NETDEV_GOING_DOWN handler. cfg80211_leave(), called unconditionally
+just before it, already cancels any pending work under wiphy_lock
+via wiphy_work_cancel() inside cfg80211_pmsr_wdev_down().
+
+Fixes: 6dccbc9f3e1d ("wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down")
+Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260703082523.2629324-1-peddolla.reddy@oss.qualcomm.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 2 +-
+ net/wireless/core.c | 3 +--
+ net/wireless/core.h | 2 +-
+ net/wireless/pmsr.c | 8 +++-----
+ 4 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index a76e0459a8e63b..8dcb218e08047b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6414,7 +6414,7 @@ struct wireless_dev {
+
+ struct list_head pmsr_list;
+ spinlock_t pmsr_lock;
+- struct work_struct pmsr_free_wk;
++ struct wiphy_work pmsr_free_wk;
+
+ unsigned long unprot_beacon_reported;
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 7799cec95a9d99..5bc3e12e7b2de0 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1418,7 +1418,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
+ INIT_LIST_HEAD(&wdev->mgmt_registrations);
+ INIT_LIST_HEAD(&wdev->pmsr_list);
+ spin_lock_init(&wdev->pmsr_lock);
+- INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
++ wiphy_work_init(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
+
+ #ifdef CONFIG_CFG80211_WEXT
+ wdev->wext.default_key = -1;
+@@ -1551,7 +1551,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ }
+ /* since we just did cfg80211_leave() nothing to do there */
+ cancel_work_sync(&wdev->disconnect_wk);
+- cancel_work_sync(&wdev->pmsr_free_wk);
+ break;
+ case NETDEV_DOWN:
+ wiphy_lock(&rdev->wiphy);
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index a60883b6e43105..b02b456cfca379 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -560,7 +560,7 @@ cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len);
+
+ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
+ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
+-void cfg80211_pmsr_free_wk(struct work_struct *work);
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work);
+
+ void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
+ void cfg80211_remove_links(struct wireless_dev *wdev);
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 13801cf35e9fca..d2546c27879fa4 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -625,13 +625,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
+ }
+ }
+
+-void cfg80211_pmsr_free_wk(struct work_struct *work)
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work)
+ {
+ struct wireless_dev *wdev = container_of(work, struct wireless_dev,
+ pmsr_free_wk);
+
+- guard(wiphy)(wdev->wiphy);
+-
+ cfg80211_pmsr_process_abort(wdev);
+ }
+
+@@ -647,7 +645,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+
+- cancel_work_sync(&wdev->pmsr_free_wk);
++ wiphy_work_cancel(wdev->wiphy, &wdev->pmsr_free_wk);
+ if (found)
+ cfg80211_pmsr_process_abort(wdev);
+
+@@ -662,7 +660,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
+ list_for_each_entry(req, &wdev->pmsr_list, list) {
+ if (req->nl_portid == portid) {
+ req->nl_portid = 0;
+- schedule_work(&wdev->pmsr_free_wk);
++ wiphy_work_queue(wdev->wiphy, &wdev->pmsr_free_wk);
+ }
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+--
+2.53.0
+
--- /dev/null
+From 7df3ae365bd25a21cf25aa135ef52fb4b0a4bbea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 09:42:25 +0100
+Subject: wifi: cfg80211: define and use wiphy guard
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit f42d22d3f79639c1b4e41daf28dad2505d6a5a8b ]
+
+Define a guard for the wiphy mutex, and use it in
+most code in cfg80211, though not all due to some
+interaction with RTNL and/or indentation.
+
+Suggested-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://patch.msgid.link/20241122094225.88765cbaab65.I610c9b14f36902e75e1d13f0db29f8bef2298804@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 2b0eab425e1f ("wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 4 +
+ net/wireless/chan.c | 4 +-
+ net/wireless/core.c | 42 +++--
+ net/wireless/mlme.c | 8 +-
+ net/wireless/nl80211.c | 190 +++++++++-------------
+ net/wireless/pmsr.c | 4 +-
+ net/wireless/reg.c | 55 +++----
+ net/wireless/scan.c | 40 +++--
+ net/wireless/sme.c | 12 +-
+ net/wireless/util.c | 7 +-
+ net/wireless/wext-compat.c | 317 +++++++++++++------------------------
+ net/wireless/wext-sme.c | 43 ++---
+ 12 files changed, 278 insertions(+), 448 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index f1710d7af6656b..a76e0459a8e63b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6030,6 +6030,10 @@ static inline void wiphy_unlock(struct wiphy *wiphy)
+ mutex_unlock(&wiphy->mtx);
+ }
+
++DEFINE_GUARD(wiphy, struct wiphy *,
++ mutex_lock(&_T->mtx),
++ mutex_unlock(&_T->mtx))
++
+ struct wiphy_work;
+ typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *);
+
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index eb8826e33d1757..515d40c09e7886 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -1039,10 +1039,10 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
+ continue;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ found = cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan) ||
+ cfg80211_offchan_chain_is_active(rdev, chan);
+- wiphy_unlock(&rdev->wiphy);
+
+ if (found)
+ return true;
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 556b0d859d2dea..7799cec95a9d99 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -191,7 +191,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
+ return err;
+ }
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ if (!wdev->netdev)
+ continue;
+@@ -212,7 +213,6 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
+ continue;
+ nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
+ }
+- wiphy_unlock(&rdev->wiphy);
+
+ return 0;
+ }
+@@ -221,9 +221,9 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
+ {
+ struct cfg80211_registered_device *rdev = data;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ rdev_rfkill_poll(rdev);
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
+@@ -283,7 +283,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
+
+ /* otherwise, check iftype */
+
+- wiphy_lock(wiphy);
++ guard(wiphy)(wiphy);
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_P2P_DEVICE:
+@@ -295,8 +295,6 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
+ default:
+ break;
+ }
+-
+- wiphy_unlock(wiphy);
+ }
+ }
+ EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces);
+@@ -331,9 +329,9 @@ static void cfg80211_event_work(struct work_struct *work)
+ rdev = container_of(work, struct cfg80211_registered_device,
+ event_work);
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ cfg80211_process_rdev_events(rdev);
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
+@@ -347,10 +345,10 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
+ if (wdev->netdev)
+ dev_close(wdev->netdev);
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ cfg80211_leave(rdev, wdev);
+ cfg80211_remove_virtual_intf(rdev, wdev);
+- wiphy_unlock(&rdev->wiphy);
+ }
+ }
+ }
+@@ -423,9 +421,9 @@ static void cfg80211_wiphy_work(struct work_struct *work)
+
+ trace_wiphy_work_worker_start(&rdev->wiphy);
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+ if (rdev->suspended)
+- goto out;
++ return;
+
+ spin_lock_irq(&rdev->wiphy_work_lock);
+ wk = list_first_entry_or_null(&rdev->wiphy_work_list,
+@@ -441,8 +439,6 @@ static void cfg80211_wiphy_work(struct work_struct *work)
+ } else {
+ spin_unlock_irq(&rdev->wiphy_work_lock);
+ }
+-out:
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ /* exported functions */
+@@ -1532,9 +1528,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ break;
+ case NETDEV_REGISTER:
+ if (!wdev->registered) {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ cfg80211_register_wdev(rdev, wdev);
+- wiphy_unlock(&rdev->wiphy);
+ }
+ break;
+ case NETDEV_UNREGISTER:
+@@ -1543,16 +1539,16 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ * so check wdev->registered.
+ */
+ if (wdev->registered && !wdev->registering) {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ _cfg80211_unregister_wdev(wdev, false);
+- wiphy_unlock(&rdev->wiphy);
+ }
+ break;
+ case NETDEV_GOING_DOWN:
+- wiphy_lock(&rdev->wiphy);
+- cfg80211_leave(rdev, wdev);
+- cfg80211_remove_links(wdev);
+- wiphy_unlock(&rdev->wiphy);
++ scoped_guard(wiphy, &rdev->wiphy) {
++ cfg80211_leave(rdev, wdev);
++ cfg80211_remove_links(wdev);
++ }
+ /* since we just did cfg80211_leave() nothing to do there */
+ cancel_work_sync(&wdev->disconnect_wk);
+ cancel_work_sync(&wdev->pmsr_free_wk);
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index 26319522c7abc3..fbdf6acfcb7dc7 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -627,10 +627,10 @@ void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
+ rdev = container_of(wk, struct cfg80211_registered_device,
+ mgmt_registrations_update_wk);
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
+ cfg80211_mgmt_registrations_update(wdev);
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
+@@ -1194,10 +1194,10 @@ cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_radar_event event)
+ {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
+ chandef, event);
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ void cfg80211_background_cac_done_wk(struct work_struct *work)
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 90ff3ee8df6122..0af78812e38efe 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -3632,7 +3632,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ } else
+ wdev = netdev->ieee80211_ptr;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+ /*
+ * end workaround code, by now the rdev is available
+@@ -3645,32 +3645,24 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ rtnl_unlock();
+
+ if (result)
+- goto out;
++ return result;
+
+ if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
+ struct ieee80211_txq_params txq_params;
+ struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
+
+- if (!rdev->ops->set_txq_params) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ if (!rdev->ops->set_txq_params)
++ return -EOPNOTSUPP;
+
+- if (!netdev) {
+- result = -EINVAL;
+- goto out;
+- }
++ if (!netdev)
++ return -EINVAL;
+
+ if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+- netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+- result = -EINVAL;
+- goto out;
+- }
++ netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
++ return -EINVAL;
+
+- if (!netif_running(netdev)) {
+- result = -ENETDOWN;
+- goto out;
+- }
++ if (!netif_running(netdev))
++ return -ENETDOWN;
+
+ nla_for_each_nested(nl_txq_params,
+ info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
+@@ -3681,10 +3673,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ txq_params_policy,
+ info->extack);
+ if (result)
+- goto out;
++ return result;
++
+ result = parse_txq_params(tb, &txq_params);
+ if (result)
+- goto out;
++ return result;
+
+ txq_params.link_id =
+ nl80211_link_id_or_invalid(info->attrs);
+@@ -3700,7 +3693,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ result = rdev_set_txq_params(rdev, netdev,
+ &txq_params);
+ if (result)
+- goto out;
++ return result;
+ }
+ }
+
+@@ -3717,7 +3710,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ if (result)
+- goto out;
++ return result;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
+@@ -3728,19 +3721,15 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
+ txp_wdev = NULL;
+
+- if (!rdev->ops->set_tx_power) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ if (!rdev->ops->set_tx_power)
++ return -EOPNOTSUPP;
+
+ idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
+ type = nla_get_u32(info->attrs[idx]);
+
+ if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
+- (type != NL80211_TX_POWER_AUTOMATIC)) {
+- result = -EINVAL;
+- goto out;
+- }
++ (type != NL80211_TX_POWER_AUTOMATIC))
++ return -EINVAL;
+
+ if (type != NL80211_TX_POWER_AUTOMATIC) {
+ idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
+@@ -3749,7 +3738,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+
+ result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
+ if (result)
+- goto out;
++ return result;
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+@@ -3758,10 +3747,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+
+ if ((!rdev->wiphy.available_antennas_tx &&
+ !rdev->wiphy.available_antennas_rx) ||
+- !rdev->ops->set_antenna) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ !rdev->ops->set_antenna)
++ return -EOPNOTSUPP;
+
+ tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
+ rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+@@ -3769,17 +3756,15 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ /* reject antenna configurations which don't match the
+ * available antenna masks, except for the "all" mask */
+ if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
+- (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
+- result = -EINVAL;
+- goto out;
+- }
++ (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
++ return -EINVAL;
+
+ tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
+ rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
+
+ result = rdev_set_antenna(rdev, tx_ant, rx_ant);
+ if (result)
+- goto out;
++ return result;
+ }
+
+ changed = 0;
+@@ -3801,10 +3786,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
+ frag_threshold = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
+- if (frag_threshold < 256) {
+- result = -EINVAL;
+- goto out;
+- }
++ if (frag_threshold < 256)
++ return -EINVAL;
+
+ if (frag_threshold != (u32) -1) {
+ /*
+@@ -3825,10 +3808,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
+- if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
+- result = -EINVAL;
+- goto out;
+- }
++ if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
++ return -EINVAL;
+
+ coverage_class = nla_get_u8(
+ info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
+@@ -3836,20 +3817,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
+- if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
++ return -EOPNOTSUPP;
+
+ changed |= WIPHY_PARAM_DYN_ACK;
+ }
+
+ if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+- NL80211_EXT_FEATURE_TXQS)) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ NL80211_EXT_FEATURE_TXQS))
++ return -EOPNOTSUPP;
++
+ txq_limit = nla_get_u32(
+ info->attrs[NL80211_ATTR_TXQ_LIMIT]);
+ changed |= WIPHY_PARAM_TXQ_LIMIT;
+@@ -3857,10 +3835,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+
+ if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+- NL80211_EXT_FEATURE_TXQS)) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ NL80211_EXT_FEATURE_TXQS))
++ return -EOPNOTSUPP;
++
+ txq_memory_limit = nla_get_u32(
+ info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
+ changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
+@@ -3868,10 +3845,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+
+ if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+- NL80211_EXT_FEATURE_TXQS)) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ NL80211_EXT_FEATURE_TXQS))
++ return -EOPNOTSUPP;
++
+ txq_quantum = nla_get_u32(
+ info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
+ changed |= WIPHY_PARAM_TXQ_QUANTUM;
+@@ -3883,10 +3859,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ u8 old_coverage_class;
+ u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
+
+- if (!rdev->ops->set_wiphy_params) {
+- result = -EOPNOTSUPP;
+- goto out;
+- }
++ if (!rdev->ops->set_wiphy_params)
++ return -EOPNOTSUPP;
+
+ old_retry_short = rdev->wiphy.retry_short;
+ old_retry_long = rdev->wiphy.retry_long;
+@@ -3924,15 +3898,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
+ rdev->wiphy.txq_limit = old_txq_limit;
+ rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
+ rdev->wiphy.txq_quantum = old_txq_quantum;
+- goto out;
++ return result;
+ }
+ }
+
+- result = 0;
+-
+-out:
+- wiphy_unlock(&rdev->wiphy);
+- return result;
++ return 0;
+ }
+
+ int nl80211_send_chandef(struct sk_buff *msg, const struct cfg80211_chan_def *chandef)
+@@ -4149,22 +4119,22 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
+
+ if_idx = 0;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ if (if_idx < if_start) {
+ if_idx++;
+ continue;
+ }
++
+ if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ rdev, wdev,
+- NL80211_CMD_NEW_INTERFACE) < 0) {
+- wiphy_unlock(&rdev->wiphy);
++ NL80211_CMD_NEW_INTERFACE) < 0)
+ goto out;
+- }
++
+ if_idx++;
+ }
+- wiphy_unlock(&rdev->wiphy);
+
+ if_start = 0;
+ wp_idx++;
+@@ -4489,16 +4459,13 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
+ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
+ {
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+- int ret;
+
+ /* to avoid failing a new interface creation due to pending removal */
+ cfg80211_destroy_ifaces(rdev);
+
+- wiphy_lock(&rdev->wiphy);
+- ret = _nl80211_new_interface(skb, info);
+- wiphy_unlock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+- return ret;
++ return _nl80211_new_interface(skb, info);
+ }
+
+ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
+@@ -10094,7 +10061,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ struct cfg80211_chan_def chandef;
+ enum nl80211_dfs_regions dfs_region;
+ unsigned int cac_time_ms;
+- int err = -EINVAL;
++ int err;
+
+ flush_delayed_work(&rdev->dfs_update_channels_wk);
+
+@@ -10109,35 +10076,29 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ return -EINVAL;
+ }
+
+- wiphy_lock(wiphy);
++ guard(wiphy)(wiphy);
+
+ dfs_region = reg_get_dfs_region(wiphy);
+ if (dfs_region == NL80211_DFS_UNSET)
+- goto unlock;
++ return -EINVAL;
+
+ err = nl80211_parse_chandef(rdev, info, &chandef);
+ if (err)
+- goto unlock;
++ return err;
+
+ err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
+ if (err < 0)
+- goto unlock;
++ return err;
+
+- if (err == 0) {
+- err = -EINVAL;
+- goto unlock;
+- }
++ if (err == 0)
++ return -EINVAL;
+
+- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) {
+- err = -EINVAL;
+- goto unlock;
+- }
++ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
++ return -EINVAL;
+
+- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) {
+- err = cfg80211_start_background_radar_detection(rdev, wdev,
+- &chandef);
+- goto unlock;
+- }
++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND]))
++ return cfg80211_start_background_radar_detection(rdev, wdev,
++ &chandef);
+
+ if (cfg80211_beaconing_iface_active(wdev)) {
+ /* During MLO other link(s) can beacon, only the current link
+@@ -10147,26 +10108,19 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ !wdev->links[link_id].ap.beacon_interval) {
+ /* nothing */
+ } else {
+- err = -EBUSY;
+- goto unlock;
++ return -EBUSY;
+ }
+ }
+
+- if (wdev->links[link_id].cac_started) {
+- err = -EBUSY;
+- goto unlock;
+- }
++ if (wdev->links[link_id].cac_started)
++ return -EBUSY;
+
+ /* CAC start is offloaded to HW and can't be started manually */
+- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) {
+- err = -EOPNOTSUPP;
+- goto unlock;
+- }
++ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
++ return -EOPNOTSUPP;
+
+- if (!rdev->ops->start_radar_detection) {
+- err = -EOPNOTSUPP;
+- goto unlock;
+- }
++ if (!rdev->ops->start_radar_detection)
++ return -EOPNOTSUPP;
+
+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
+ if (WARN_ON(!cac_time_ms))
+@@ -10193,10 +10147,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ wdev->links[link_id].cac_start_time = jiffies;
+ wdev->links[link_id].cac_time_ms = cac_time_ms;
+ }
+-unlock:
+- wiphy_unlock(wiphy);
+
+- return err;
++ return 0;
+ }
+
+ static int nl80211_notify_radar_detection(struct sk_buff *skb,
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index d2b61b6ba58db7..13801cf35e9fca 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -630,9 +630,9 @@ void cfg80211_pmsr_free_wk(struct work_struct *work)
+ struct wireless_dev *wdev = container_of(work, struct wireless_dev,
+ pmsr_free_wk);
+
+- wiphy_lock(wdev->wiphy);
++ guard(wiphy)(wdev->wiphy);
++
+ cfg80211_pmsr_process_abort(wdev);
+- wiphy_unlock(wdev->wiphy);
+ }
+
+ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 9f8428dc418a50..daf51fb56648c4 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2468,11 +2468,11 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
+ struct wireless_dev *wdev;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+- wiphy_lock(wiphy);
++ guard(wiphy)(wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
+ if (!reg_wdev_chan_valid(wiphy, wdev))
+ cfg80211_leave(rdev, wdev);
+- wiphy_unlock(wiphy);
+ }
+
+ static void reg_check_chans_work(struct work_struct *work)
+@@ -2652,13 +2652,11 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
+ return;
+
+ rtnl_lock();
+- wiphy_lock(wiphy);
+-
+- tmp = get_wiphy_regdom(wiphy);
+- rcu_assign_pointer(wiphy->regd, new_regd);
+- rcu_free_regdom(tmp);
+-
+- wiphy_unlock(wiphy);
++ scoped_guard(wiphy, wiphy) {
++ tmp = get_wiphy_regdom(wiphy);
++ rcu_assign_pointer(wiphy->regd, new_regd);
++ rcu_free_regdom(tmp);
++ }
+ rtnl_unlock();
+ }
+ EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
+@@ -2828,9 +2826,9 @@ reg_process_hint_driver(struct wiphy *wiphy,
+
+ tmp = get_wiphy_regdom(wiphy);
+ ASSERT_RTNL();
+- wiphy_lock(wiphy);
+- rcu_assign_pointer(wiphy->regd, regd);
+- wiphy_unlock(wiphy);
++ scoped_guard(wiphy, wiphy) {
++ rcu_assign_pointer(wiphy->regd, regd);
++ }
+ rcu_free_regdom(tmp);
+ }
+
+@@ -3208,9 +3206,9 @@ static void reg_process_self_managed_hints(void)
+ ASSERT_RTNL();
+
+ for_each_rdev(rdev) {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ reg_process_self_managed_hint(&rdev->wiphy);
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ reg_check_channels();
+@@ -3603,14 +3601,12 @@ static bool is_wiphy_all_set_reg_flag(enum ieee80211_regulatory_flags flag)
+ struct wireless_dev *wdev;
+
+ for_each_rdev(rdev) {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+- if (!(wdev->wiphy->regulatory_flags & flag)) {
+- wiphy_unlock(&rdev->wiphy);
++ if (!(wdev->wiphy->regulatory_flags & flag))
+ return false;
+- }
+ }
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ return true;
+@@ -3886,19 +3882,18 @@ static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
+
+ if (!driver_request->intersect) {
+ ASSERT_RTNL();
+- wiphy_lock(request_wiphy);
+- if (request_wiphy->regd)
+- tmp = get_wiphy_regdom(request_wiphy);
+-
+- regd = reg_copy_regd(rd);
+- if (IS_ERR(regd)) {
+- wiphy_unlock(request_wiphy);
+- return PTR_ERR(regd);
++ scoped_guard(wiphy, request_wiphy) {
++ if (request_wiphy->regd)
++ tmp = get_wiphy_regdom(request_wiphy);
++
++ regd = reg_copy_regd(rd);
++ if (IS_ERR(regd))
++ return PTR_ERR(regd);
++
++ rcu_assign_pointer(request_wiphy->regd, regd);
++ rcu_free_regdom(tmp);
+ }
+
+- rcu_assign_pointer(request_wiphy->regd, regd);
+- rcu_free_regdom(tmp);
+- wiphy_unlock(request_wiphy);
+ reset_regdomains(false, rd);
+ return 0;
+ }
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 3fb31f17daf4ae..44973529687486 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -1234,7 +1234,8 @@ void cfg80211_sched_scan_results_wk(struct work_struct *work)
+ rdev = container_of(work, struct cfg80211_registered_device,
+ sched_scan_res_wk);
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
+ if (req->report_results) {
+ req->report_results = false;
+@@ -1249,7 +1250,6 @@ void cfg80211_sched_scan_results_wk(struct work_struct *work)
+ NL80211_CMD_SCHED_SCAN_RESULTS);
+ }
+ }
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
+@@ -1284,9 +1284,9 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped_locked);
+
+ void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
+ {
+- wiphy_lock(wiphy);
++ guard(wiphy)(wiphy);
++
+ cfg80211_sched_scan_stopped_locked(wiphy, reqid);
+- wiphy_unlock(wiphy);
+ }
+ EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
+
+@@ -3558,10 +3558,8 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+ /* translate "Scan for SSID" request */
+ if (wreq) {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+- if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
+- err = -EINVAL;
+- goto out;
+- }
++ if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
++ return -EINVAL;
+ memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
+ creq->ssids[0].ssid_len = wreq->essid_len;
+ }
+@@ -3577,20 +3575,20 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+
+ eth_broadcast_addr(creq->bssid);
+
+- wiphy_lock(&rdev->wiphy);
+-
+- rdev->scan_req = creq;
+- err = rdev_scan(rdev, creq);
+- if (err) {
+- rdev->scan_req = NULL;
+- /* creq will be freed below */
+- } else {
+- nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
+- /* creq now owned by driver */
+- creq = NULL;
+- dev_hold(dev);
++ scoped_guard(wiphy, &rdev->wiphy) {
++ rdev->scan_req = creq;
++ err = rdev_scan(rdev, creq);
++ if (err) {
++ rdev->scan_req = NULL;
++ /* creq will be freed below */
++ } else {
++ nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
++ /* creq now owned by driver */
++ creq = NULL;
++ dev_hold(dev);
++ }
+ }
+- wiphy_unlock(&rdev->wiphy);
++
+ out:
+ kfree(creq);
+ return err;
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index d8250ae17d940b..ab57648ca57748 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -252,7 +252,7 @@ void cfg80211_conn_work(struct work_struct *work)
+ u8 bssid_buf[ETH_ALEN], *bssid = NULL;
+ enum nl80211_timeout_reason treason;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ if (!wdev->netdev)
+@@ -280,8 +280,6 @@ void cfg80211_conn_work(struct work_struct *work)
+ __cfg80211_connect_result(wdev->netdev, &cr, false);
+ }
+ }
+-
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
+@@ -693,13 +691,13 @@ static bool cfg80211_is_all_idle(void)
+ * as chan dfs state, etc.
+ */
+ for_each_rdev(rdev) {
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ if (wdev->conn || wdev->connected ||
+ cfg80211_beaconing_iface_active(wdev))
+ is_all_idle = false;
+ }
+- wiphy_unlock(&rdev->wiphy);
+ }
+
+ return is_all_idle;
+@@ -1586,7 +1584,7 @@ void cfg80211_autodisconnect_wk(struct work_struct *work)
+ container_of(work, struct wireless_dev, disconnect_wk);
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+
+- wiphy_lock(wdev->wiphy);
++ guard(wiphy)(wdev->wiphy);
+
+ if (wdev->conn_owner_nlportid) {
+ switch (wdev->iftype) {
+@@ -1622,6 +1620,4 @@ void cfg80211_autodisconnect_wk(struct work_struct *work)
+ break;
+ }
+ }
+-
+- wiphy_unlock(wdev->wiphy);
+ }
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 5be4ccb8714110..8478f3a0e94021 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -2601,7 +2601,6 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
+ {
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+- int ret;
+
+ wdev = dev->ieee80211_ptr;
+ if (!wdev)
+@@ -2613,11 +2612,9 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr,
+
+ memset(sinfo, 0, sizeof(*sinfo));
+
+- wiphy_lock(&rdev->wiphy);
+- ret = rdev_get_station(rdev, dev, mac_addr, sinfo);
+- wiphy_unlock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+- return ret;
++ return rdev_get_station(rdev, dev, mac_addr, sinfo);
+ }
+ EXPORT_SYMBOL(cfg80211_get_station);
+
+diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
+index 32a695c8a4d2af..186f84b3679bf0 100644
+--- a/net/wireless/wext-compat.c
++++ b/net/wireless/wext-compat.c
+@@ -40,7 +40,6 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
+ struct cfg80211_registered_device *rdev;
+ struct vif_params vifparams;
+ enum nl80211_iftype type;
+- int ret;
+
+ rdev = wiphy_to_rdev(wdev->wiphy);
+
+@@ -63,11 +62,9 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
+
+ memset(&vifparams, 0, sizeof(vifparams));
+
+- wiphy_lock(wdev->wiphy);
+- ret = cfg80211_change_iface(rdev, dev, type, &vifparams);
+- wiphy_unlock(wdev->wiphy);
++ guard(wiphy)(wdev->wiphy);
+
+- return ret;
++ return cfg80211_change_iface(rdev, dev, type, &vifparams);
+ }
+ EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
+
+@@ -262,23 +259,17 @@ int cfg80211_wext_siwrts(struct net_device *dev,
+ u32 orts = wdev->wiphy->rts_threshold;
+ int err;
+
+- wiphy_lock(&rdev->wiphy);
+- if (rts->disabled || !rts->fixed) {
++ guard(wiphy)(&rdev->wiphy);
++ if (rts->disabled || !rts->fixed)
+ wdev->wiphy->rts_threshold = (u32) -1;
+- } else if (rts->value < 0) {
+- err = -EINVAL;
+- goto out;
+- } else {
++ else if (rts->value < 0)
++ return -EINVAL;
++ else
+ wdev->wiphy->rts_threshold = rts->value;
+- }
+
+ err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD);
+-
+ if (err)
+ wdev->wiphy->rts_threshold = orts;
+-
+-out:
+- wiphy_unlock(&rdev->wiphy);
+ return err;
+ }
+ EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
+@@ -308,12 +299,12 @@ int cfg80211_wext_siwfrag(struct net_device *dev,
+ u32 ofrag = wdev->wiphy->frag_threshold;
+ int err;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ if (frag->disabled || !frag->fixed) {
+ wdev->wiphy->frag_threshold = (u32) -1;
+ } else if (frag->value < 256) {
+- err = -EINVAL;
+- goto out;
++ return -EINVAL;
+ } else {
+ /* Fragment length must be even, so strip LSB. */
+ wdev->wiphy->frag_threshold = frag->value & ~0x1;
+@@ -322,9 +313,6 @@ int cfg80211_wext_siwfrag(struct net_device *dev,
+ err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD);
+ if (err)
+ wdev->wiphy->frag_threshold = ofrag;
+-out:
+- wiphy_unlock(&rdev->wiphy);
+-
+ return err;
+ }
+ EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
+@@ -360,7 +348,8 @@ static int cfg80211_wext_siwretry(struct net_device *dev,
+ (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
+ return -EINVAL;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ if (retry->flags & IW_RETRY_LONG) {
+ wdev->wiphy->retry_long = retry->value;
+ changed |= WIPHY_PARAM_RETRY_LONG;
+@@ -379,7 +368,6 @@ static int cfg80211_wext_siwretry(struct net_device *dev,
+ wdev->wiphy->retry_short = oshort;
+ wdev->wiphy->retry_long = olong;
+ }
+- wiphy_unlock(&rdev->wiphy);
+
+ return err;
+ }
+@@ -587,9 +575,9 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
+ struct iw_point *erq = &wrqu->encoding;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+- int idx, err;
+- bool remove = false;
+ struct key_params params;
++ bool remove = false;
++ int idx;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_ADHOC)
+@@ -601,11 +589,9 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
+ !rdev->ops->set_default_key)
+ return -EOPNOTSUPP;
+
+- wiphy_lock(&rdev->wiphy);
+- if (wdev->valid_links) {
+- err = -EOPNOTSUPP;
+- goto out;
+- }
++ guard(wiphy)(&rdev->wiphy);
++ if (wdev->valid_links)
++ return -EOPNOTSUPP;
+
+ idx = erq->flags & IW_ENCODE_INDEX;
+ if (idx == 0) {
+@@ -613,8 +599,7 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
+ if (idx < 0)
+ idx = 0;
+ } else if (idx < 1 || idx > 4) {
+- err = -EINVAL;
+- goto out;
++ return -EINVAL;
+ } else {
+ idx--;
+ }
+@@ -623,7 +608,8 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
+ remove = true;
+ else if (erq->length == 0) {
+ /* No key data - just set the default TX key index */
+- err = 0;
++ int err = 0;
++
+ if (wdev->connected ||
+ (wdev->iftype == NL80211_IFTYPE_ADHOC &&
+ wdev->u.ibss.current_bss))
+@@ -631,28 +617,22 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
+ true);
+ if (!err)
+ wdev->wext.default_key = idx;
+- goto out;
++ return err;
+ }
+
+ memset(¶ms, 0, sizeof(params));
+ params.key = keybuf;
+ params.key_len = erq->length;
+- if (erq->length == 5) {
++ if (erq->length == 5)
+ params.cipher = WLAN_CIPHER_SUITE_WEP40;
+- } else if (erq->length == 13) {
++ else if (erq->length == 13)
+ params.cipher = WLAN_CIPHER_SUITE_WEP104;
+- } else if (!remove) {
+- err = -EINVAL;
+- goto out;
+- }
+-
+- err = cfg80211_set_encryption(rdev, dev, false, NULL, remove,
+- wdev->wext.default_key == -1,
+- idx, ¶ms);
+-out:
+- wiphy_unlock(&rdev->wiphy);
++ else if (!remove)
++ return -EINVAL;
+
+- return err;
++ return cfg80211_set_encryption(rdev, dev, false, NULL, remove,
++ wdev->wext.default_key == -1,
++ idx, ¶ms);
+ }
+
+ static int cfg80211_wext_siwencodeext(struct net_device *dev,
+@@ -668,7 +648,6 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev,
+ bool remove = false;
+ struct key_params params;
+ u32 cipher;
+- int ret;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_ADHOC)
+@@ -743,16 +722,13 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev,
+ params.seq_len = 6;
+ }
+
+- wiphy_lock(wdev->wiphy);
+- ret = cfg80211_set_encryption(
+- rdev, dev,
+- !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
+- addr, remove,
+- ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+- idx, ¶ms);
+- wiphy_unlock(wdev->wiphy);
++ guard(wiphy)(wdev->wiphy);
+
+- return ret;
++ return cfg80211_set_encryption(rdev, dev,
++ !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
++ addr, remove,
++ ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
++ idx, ¶ms);
+ }
+
+ static int cfg80211_wext_giwencode(struct net_device *dev,
+@@ -803,61 +779,41 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
+ struct cfg80211_chan_def chandef = {
+ .width = NL80211_CHAN_WIDTH_20_NOHT,
+ };
+- int freq, ret;
++ int freq;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
+- break;
++ return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
+- break;
++ return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
+ case NL80211_IFTYPE_MONITOR:
+ freq = cfg80211_wext_freq(wextfreq);
+- if (freq < 0) {
+- ret = freq;
+- break;
+- }
+- if (freq == 0) {
+- ret = -EINVAL;
+- break;
+- }
++ if (freq < 0)
++ return freq;
++ if (freq == 0)
++ return -EINVAL;
++
+ chandef.center_freq1 = freq;
+ chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
+- if (!chandef.chan) {
+- ret = -EINVAL;
+- break;
+- }
+- ret = cfg80211_set_monitor_channel(rdev, dev, &chandef);
+- break;
++ if (!chandef.chan)
++ return -EINVAL;
++ return cfg80211_set_monitor_channel(rdev, dev, &chandef);
+ case NL80211_IFTYPE_MESH_POINT:
+ freq = cfg80211_wext_freq(wextfreq);
+- if (freq < 0) {
+- ret = freq;
+- break;
+- }
+- if (freq == 0) {
+- ret = -EINVAL;
+- break;
+- }
++ if (freq < 0)
++ return freq;
++ if (freq == 0)
++ return -EINVAL;
+ chandef.center_freq1 = freq;
+ chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
+- if (!chandef.chan) {
+- ret = -EINVAL;
+- break;
+- }
+- ret = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
+- break;
++ if (!chandef.chan)
++ return -EINVAL;
++ return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+-
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_giwfreq(struct net_device *dev,
+@@ -870,35 +826,26 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
+ struct cfg80211_chan_def chandef = {};
+ int ret;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
+- break;
++ return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+- break;
++ return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+ case NL80211_IFTYPE_MONITOR:
+- if (!rdev->ops->get_channel) {
+- ret = -EINVAL;
+- break;
+- }
++ if (!rdev->ops->get_channel)
++ return -EINVAL;
+
+ ret = rdev_get_channel(rdev, wdev, 0, &chandef);
+ if (ret)
+- break;
++ return ret;
+ freq->m = chandef.chan->center_freq;
+ freq->e = 6;
+- ret = 0;
+- break;
++ return ret;
+ default:
+- ret = -EINVAL;
+- break;
++ return -EINVAL;
+ }
+-
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_siwtxpower(struct net_device *dev,
+@@ -909,7 +856,6 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+ enum nl80211_tx_power_setting type;
+ int dbm = 0;
+- int ret;
+
+ if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
+ return -EINVAL;
+@@ -951,11 +897,9 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
+ return 0;
+ }
+
+- wiphy_lock(&rdev->wiphy);
+- ret = rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
+- wiphy_unlock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+- return ret;
++ return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
+ }
+
+ static int cfg80211_wext_giwtxpower(struct net_device *dev,
+@@ -974,9 +918,9 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
+ if (!rdev->ops->get_tx_power)
+ return -EOPNOTSUPP;
+
+- wiphy_lock(&rdev->wiphy);
+- err = rdev_get_tx_power(rdev, wdev, &val);
+- wiphy_unlock(&rdev->wiphy);
++ scoped_guard(wiphy, &rdev->wiphy) {
++ err = rdev_get_tx_power(rdev, wdev, &val);
++ }
+ if (err)
+ return err;
+
+@@ -1218,9 +1162,9 @@ static int cfg80211_wext_siwpower(struct net_device *dev,
+ timeout = wrq->value / 1000;
+ }
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ err = rdev_set_power_mgmt(rdev, dev, ps, timeout);
+- wiphy_unlock(&rdev->wiphy);
+ if (err)
+ return err;
+
+@@ -1253,8 +1197,8 @@ static int cfg80211_wext_siwrate(struct net_device *dev,
+ struct cfg80211_bitrate_mask mask;
+ u32 fixed, maxrate;
+ struct ieee80211_supported_band *sband;
+- int band, ridx, ret;
+ bool match = false;
++ int band, ridx;
+
+ if (!rdev->ops->set_bitrate_mask)
+ return -EOPNOTSUPP;
+@@ -1292,14 +1236,12 @@ static int cfg80211_wext_siwrate(struct net_device *dev,
+ if (!match)
+ return -EINVAL;
+
+- wiphy_lock(&rdev->wiphy);
+- if (dev->ieee80211_ptr->valid_links)
+- ret = -EOPNOTSUPP;
+- else
+- ret = rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask);
+- wiphy_unlock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
+
+- return ret;
++ if (dev->ieee80211_ptr->valid_links)
++ return -EOPNOTSUPP;
++
++ return rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask);
+ }
+
+ static int cfg80211_wext_giwrate(struct net_device *dev,
+@@ -1328,9 +1270,9 @@ static int cfg80211_wext_giwrate(struct net_device *dev,
+ if (err)
+ return err;
+
+- wiphy_lock(&rdev->wiphy);
+- err = rdev_get_station(rdev, dev, addr, &sinfo);
+- wiphy_unlock(&rdev->wiphy);
++ scoped_guard(wiphy, &rdev->wiphy) {
++ err = rdev_get_station(rdev, dev, addr, &sinfo);
++ }
+ if (err)
+ return err;
+
+@@ -1429,23 +1371,17 @@ static int cfg80211_wext_siwap(struct net_device *dev,
+ struct sockaddr *ap_addr = &wrqu->ap_addr;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+- int ret;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+- break;
++ return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
+- break;
++ return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_giwap(struct net_device *dev,
+@@ -1455,23 +1391,17 @@ static int cfg80211_wext_giwap(struct net_device *dev,
+ struct sockaddr *ap_addr = &wrqu->ap_addr;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+- int ret;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+- break;
++ return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
+- break;
++ return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_siwessid(struct net_device *dev,
+@@ -1481,23 +1411,17 @@ static int cfg80211_wext_siwessid(struct net_device *dev,
+ struct iw_point *data = &wrqu->data;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+- int ret;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+- break;
++ return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
+- break;
++ return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_giwessid(struct net_device *dev,
+@@ -1507,26 +1431,20 @@ static int cfg80211_wext_giwessid(struct net_device *dev,
+ struct iw_point *data = &wrqu->data;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+- int ret;
+
+ data->flags = 0;
+ data->length = 0;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+- ret = cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+- break;
++ return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+ case NL80211_IFTYPE_STATION:
+- ret = cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
+- break;
++ return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static int cfg80211_wext_siwpmksa(struct net_device *dev,
+@@ -1537,7 +1455,6 @@ static int cfg80211_wext_siwpmksa(struct net_device *dev,
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+ struct cfg80211_pmksa cfg_pmksa;
+ struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
+- int ret;
+
+ memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
+
+@@ -1547,39 +1464,27 @@ static int cfg80211_wext_siwpmksa(struct net_device *dev,
+ cfg_pmksa.bssid = pmksa->bssid.sa_data;
+ cfg_pmksa.pmkid = pmksa->pmkid;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (pmksa->cmd) {
+ case IW_PMKSA_ADD:
+- if (!rdev->ops->set_pmksa) {
+- ret = -EOPNOTSUPP;
+- break;
+- }
++ if (!rdev->ops->set_pmksa)
++ return -EOPNOTSUPP;
+
+- ret = rdev_set_pmksa(rdev, dev, &cfg_pmksa);
+- break;
++ return rdev_set_pmksa(rdev, dev, &cfg_pmksa);
+ case IW_PMKSA_REMOVE:
+- if (!rdev->ops->del_pmksa) {
+- ret = -EOPNOTSUPP;
+- break;
+- }
++ if (!rdev->ops->del_pmksa)
++ return -EOPNOTSUPP;
+
+- ret = rdev_del_pmksa(rdev, dev, &cfg_pmksa);
+- break;
++ return rdev_del_pmksa(rdev, dev, &cfg_pmksa);
+ case IW_PMKSA_FLUSH:
+- if (!rdev->ops->flush_pmksa) {
+- ret = -EOPNOTSUPP;
+- break;
+- }
++ if (!rdev->ops->flush_pmksa)
++ return -EOPNOTSUPP;
+
+- ret = rdev_flush_pmksa(rdev, dev);
+- break;
++ return rdev_flush_pmksa(rdev, dev);
+ default:
+- ret = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return ret;
+ }
+
+ static const iw_handler cfg80211_handlers[] = {
+diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
+index 8edd9ada69d0bd..573b6b15a446ec 100644
+--- a/net/wireless/wext-sme.c
++++ b/net/wireless/wext-sme.c
+@@ -302,8 +302,8 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
+ struct iw_point *data = &wrqu->data;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
++ int ie_len = data->length;
+ u8 *ie = extra;
+- int ie_len = data->length, err;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION)
+ return -EOPNOTSUPP;
+@@ -311,39 +311,31 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
+ if (!ie_len)
+ ie = NULL;
+
+- wiphy_lock(wdev->wiphy);
++ guard(wiphy)(wdev->wiphy);
+
+ /* no change */
+- err = 0;
+ if (wdev->wext.ie_len == ie_len &&
+ memcmp(wdev->wext.ie, ie, ie_len) == 0)
+- goto out;
++ return 0;
+
+ if (ie_len) {
+ ie = kmemdup(extra, ie_len, GFP_KERNEL);
+- if (!ie) {
+- err = -ENOMEM;
+- goto out;
+- }
+- } else
++ if (!ie)
++ return -ENOMEM;
++ } else {
+ ie = NULL;
++ }
+
+ kfree(wdev->wext.ie);
+ wdev->wext.ie = ie;
+ wdev->wext.ie_len = ie_len;
+
+- if (wdev->conn) {
+- err = cfg80211_disconnect(rdev, dev,
+- WLAN_REASON_DEAUTH_LEAVING, false);
+- if (err)
+- goto out;
+- }
++ if (wdev->conn)
++ return cfg80211_disconnect(rdev, dev,
++ WLAN_REASON_DEAUTH_LEAVING, false);
+
+ /* userspace better not think we'll reconnect */
+- err = 0;
+- out:
+- wiphy_unlock(wdev->wiphy);
+- return err;
++ return 0;
+ }
+
+ int cfg80211_wext_siwmlme(struct net_device *dev,
+@@ -353,7 +345,6 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ struct cfg80211_registered_device *rdev;
+- int err;
+
+ if (!wdev)
+ return -EOPNOTSUPP;
+@@ -366,17 +357,13 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
+ if (mlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+- wiphy_lock(&rdev->wiphy);
++ guard(wiphy)(&rdev->wiphy);
++
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ case IW_MLME_DISASSOC:
+- err = cfg80211_disconnect(rdev, dev, mlme->reason_code, true);
+- break;
++ return cfg80211_disconnect(rdev, dev, mlme->reason_code, true);
+ default:
+- err = -EOPNOTSUPP;
+- break;
++ return -EOPNOTSUPP;
+ }
+- wiphy_unlock(&rdev->wiphy);
+-
+- return err;
+ }
+--
+2.53.0
+
--- /dev/null
+From 77c4f802d7206e268a3c4a60413fc39bea572390 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 00:19:46 +0800
+Subject: wifi: cfg80211: derive S1G beacon TSF from S1G fields
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 4e5a4641e7b4763656336b7891d01359aaf363cd ]
+
+cfg80211_inform_bss_frame_data() parses S1G beacons with the extension
+frame layout, but still reads the TSF from the regular probe response
+layout after the S1G branch. For S1G beacons that reads bytes at the
+regular management-frame timestamp offset instead of the S1G timestamp.
+
+Use the 32-bit S1G beacon timestamp and the S1G Beacon Compatibility
+element's TSF completion field when informing an S1G BSS. Keep the
+regular management-frame timestamp read in the non-S1G branch.
+
+Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Tested-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Reviewed-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Link: https://patch.msgid.link/20260611161943.91069-6-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 44973529687486..b249f29454f9e1 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3262,14 +3262,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ bssid = ext->u.s1g_beacon.sa;
+ capability = le16_to_cpu(compat->compat_info);
+ beacon_interval = le16_to_cpu(compat->beacon_int);
++ tsf = le32_to_cpu(ext->u.s1g_beacon.timestamp);
++ tsf |= (u64)le32_to_cpu(compat->tsf_completion) << 32;
+ } else {
+ bssid = mgmt->bssid;
+ beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
+ capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
++ tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+ }
+
+- tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+-
+ if (ieee80211_is_probe_resp(mgmt->frame_control))
+ ftype = CFG80211_BSS_FTYPE_PRESP;
+ else if (ext)
+--
+2.53.0
+
--- /dev/null
+From 841cf7964c622070e8551f0abfa6ecab2894361a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 10:25:47 +0200
+Subject: wifi: cfg80211: pass net_device to .set_monitor_channel
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 9c4f830927750a2bf9fd9426a5257f0fdce3b662 ]
+
+Preparation for allowing multiple monitor interfaces with different channels
+on a multi-radio wiphy.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/35fa652dbfebf93343f8b9a08fdef0467a2a02dc.1728462320.git-series.nbd@nbd.name
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 2b0eab425e1f ("wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/cfg80211.c | 1 +
+ drivers/net/wireless/marvell/libertas/cfg.c | 1 +
+ drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++-
+ include/net/cfg80211.h | 1 +
+ net/mac80211/cfg.c | 1 +
+ net/wireless/chan.c | 3 ++-
+ net/wireless/core.h | 1 +
+ net/wireless/nl80211.c | 2 +-
+ net/wireless/rdev-ops.h | 5 +++--
+ net/wireless/trace.h | 10 ++++++----
+ net/wireless/wext-compat.c | 2 +-
+ 11 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
+index e8f1d30a8d73c5..a1a0a9223e74ac 100644
+--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
++++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
+@@ -1493,6 +1493,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+ }
+
+ static int wil_cfg80211_set_channel(struct wiphy *wiphy,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
+index 37bb788f83e36e..309556541a83ed 100644
+--- a/drivers/net/wireless/marvell/libertas/cfg.c
++++ b/drivers/net/wireless/marvell/libertas/cfg.c
+@@ -486,6 +486,7 @@ static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t ie_len)
+ */
+
+ static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ struct lbs_private *priv = wiphy_priv(wiphy);
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index eb37b228d54ea0..9977be0020fe76 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -231,6 +231,7 @@ struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
+ }
+
+ static int set_channel(struct wiphy *wiphy,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ struct wilc *wl = wiphy_priv(wiphy);
+@@ -1424,7 +1425,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
+ struct wilc_vif *vif = netdev_priv(dev);
+ int ret;
+
+- ret = set_channel(wiphy, &settings->chandef);
++ ret = set_channel(wiphy, dev, &settings->chandef);
+ if (ret != 0)
+ netdev_err(dev, "Error in setting channel\n");
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 96121dc14e8263..f1710d7af6656b 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4699,6 +4699,7 @@ struct cfg80211_ops {
+ struct ieee80211_channel *chan);
+
+ int (*set_monitor_channel)(struct wiphy *wiphy,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef);
+
+ int (*scan)(struct wiphy *wiphy,
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index b9ed82b8321a6a..cfd02f48935450 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -893,6 +893,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+ }
+
+ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index c4f3fefeb35444..eb8826e33d1757 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -1634,6 +1634,7 @@ bool cfg80211_reg_check_beaconing(struct wiphy *wiphy,
+ EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
+
+ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ if (!rdev->ops->set_monitor_channel)
+@@ -1641,7 +1642,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
+ if (!cfg80211_has_monitors_only(rdev))
+ return -EBUSY;
+
+- return rdev_set_monitor_channel(rdev, chandef);
++ return rdev_set_monitor_channel(rdev, dev, chandef);
+ }
+
+ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index d4b26cbe3342d0..a60883b6e43105 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -517,6 +517,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
+ }
+
+ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef);
+
+ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 15a8237f79bffa..90ff3ee8df6122 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -3568,7 +3568,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
+ case NL80211_IFTYPE_MESH_POINT:
+ return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
+ case NL80211_IFTYPE_MONITOR:
+- return cfg80211_set_monitor_channel(rdev, &chandef);
++ return cfg80211_set_monitor_channel(rdev, dev, &chandef);
+ default:
+ break;
+ }
+diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
+index f5adbf6b5c846c..adb6105bbb7d1d 100644
+--- a/net/wireless/rdev-ops.h
++++ b/net/wireless/rdev-ops.h
+@@ -445,11 +445,12 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,
+
+ static inline int
+ rdev_set_monitor_channel(struct cfg80211_registered_device *rdev,
++ struct net_device *dev,
+ struct cfg80211_chan_def *chandef)
+ {
+ int ret;
+- trace_rdev_set_monitor_channel(&rdev->wiphy, chandef);
+- ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chandef);
++ trace_rdev_set_monitor_channel(&rdev->wiphy, dev, chandef);
++ ret = rdev->ops->set_monitor_channel(&rdev->wiphy, dev, chandef);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+ }
+diff --git a/net/wireless/trace.h b/net/wireless/trace.h
+index 945013185c9860..68bbf3a778ce1f 100644
+--- a/net/wireless/trace.h
++++ b/net/wireless/trace.h
+@@ -1339,19 +1339,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel,
+ );
+
+ TRACE_EVENT(rdev_set_monitor_channel,
+- TP_PROTO(struct wiphy *wiphy,
++ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_chan_def *chandef),
+- TP_ARGS(wiphy, chandef),
++ TP_ARGS(wiphy, netdev, chandef),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
++ NETDEV_ENTRY
+ CHAN_DEF_ENTRY
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
++ NETDEV_ASSIGN;
+ CHAN_DEF_ASSIGN(chandef);
+ ),
+- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
+- WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
++ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
++ WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
+ );
+
+ TRACE_EVENT(rdev_auth,
+diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
+index 3af11dae0942ae..32a695c8a4d2af 100644
+--- a/net/wireless/wext-compat.c
++++ b/net/wireless/wext-compat.c
+@@ -830,7 +830,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
+ ret = -EINVAL;
+ break;
+ }
+- ret = cfg80211_set_monitor_channel(rdev, &chandef);
++ ret = cfg80211_set_monitor_channel(rdev, dev, &chandef);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ freq = cfg80211_wext_freq(wextfreq);
+--
+2.53.0
+
--- /dev/null
+From 8108710b4cb9784576e07a25b79a29681c193c2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index fd14a3c2eab45b..06563f60848705 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From c40f1be27715d634efd6c7a93b2631c35e68e2e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 1702616d9e1c9a..b54da0f83247a9 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -312,7 +312,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 20f0e3de3b8083932eb9d49686ba02caec4c5032 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index d2546c27879fa4..fd14a3c2eab45b 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -196,6 +196,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -248,6 +249,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -257,10 +266,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 2a3d00838a25c50bf592d82cd625a821fe2d8813 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index fe75941c584d15..95778dfdfa6d81 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6167,6 +6167,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6179,16 +6181,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From a75d4833af94b0f61887c16fdc03daf006485c6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From da55bbb6a3d87f3650ef5f3a6c5854afa4b665b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:32 -0700
+Subject: wifi: mac80211: fix fils_discovery double free on alloc failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 286e52a799fa158bdbd77da1426c4d93f9a6e7ad ]
+
+ieee80211_set_fils_discovery() calls kfree_rcu() on the old template
+before allocating the replacement. If the kzalloc() then fails, it
+returns -ENOMEM while link->u.ap.fils_discovery still points at the
+object already queued for freeing. A later update or AP teardown
+(ieee80211_stop_ap()) re-queues that same rcu_head; the second free is
+caught by KASAN when the RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800c065280 by task swapper/0/0
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-96 of size 96
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-2-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 981f316df9cd9e..b9ed82b8321a6a 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -977,9 +977,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ fd->max_interval = params->max_interval;
+
+ old = sdata_dereference(link->u.ap.fils_discovery, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+-
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+ if (!new)
+@@ -991,6 +988,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_FILS_DISCOVERY;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From c05ecc94382d54b996553be55a70fc3975616dfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:31 -0700
+Subject: wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc
+ failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 1d067abcd37062426c59ec73dbc4e87a63f33fea ]
+
+ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old
+template before allocating the replacement. If the kzalloc() then fails,
+it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points
+at the object already queued for freeing. A later update or AP teardown
+re-queues that same rcu_head; the second free is caught by KASAN when the
+RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800d06f300 by task exploit/145
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-128 of size 128
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 0abb687fd58d5c..981f316df9cd9e 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1010,8 +1010,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ link_conf->unsol_bcast_probe_resp_interval = params->interval;
+
+ old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+@@ -1024,6 +1022,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From aced6dcd068d212ed15eaba321b2e7527cd0e325 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 7e1b6a9d9f3ad8..7a79b40d23b36b 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -590,6 +590,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -597,10 +598,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From 8eeca5782fb027401d74da3039e2060f7d83190b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index e992e59b591892..63fae67c816225 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -6605,6 +6605,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From ff4e822f3898e1175f5a465c21d683066c6af39c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 19:22:09 +0800
+Subject: wifi: nl80211: free RNR data on MBSSID mismatch
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
+
+nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR
+entries than MBSSID entries.
+
+The rejected RNR allocation has not been attached to the beacon data yet,
+so free it before returning the error.
+
+Fixes: dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260610112208.1308-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 0af78812e38efe..60e00a24bc249a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5711,8 +5711,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (IS_ERR(rnr))
+ return PTR_ERR(rnr);
+
+- if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
++ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
++ kfree(rnr);
+ return -EINVAL;
++ }
+
+ bcn->rnr_ies = rnr;
+ }
+--
+2.53.0
+
--- /dev/null
+From e2df574aac651b9f169d1a42b43cfa4160145509 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:55 +0800
+Subject: wifi: nl80211: validate nested MBSSID IE blobs
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
+
+Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed
+information-element stream before storing it for beacon construction.
+
+RNR parsing already validates each nested blob with validate_ie_attr()
+before storing it. Apply the same syntactic IE validation to MBSSID
+entries before counting and copying their data and length pointers.
+
+Fixes: dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-3-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 60e00a24bc249a..1702616d9e1c9a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5513,7 +5513,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
+ }
+
+ static struct cfg80211_mbssid_elems *
+-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
++nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
++ struct netlink_ext_ack *extack)
+ {
+ struct nlattr *nl_elems;
+ struct cfg80211_mbssid_elems *elems;
+@@ -5524,6 +5525,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+ return ERR_PTR(-EINVAL);
+
+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
++ int ret;
++
++ ret = validate_ie_attr(nl_elems, extack);
++ if (ret)
++ return ERR_PTR(ret);
++
+ if (num_elems >= 255)
+ return ERR_PTR(-EINVAL);
+ num_elems++;
+@@ -5695,7 +5702,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
+ struct cfg80211_mbssid_elems *mbssid =
+ nl80211_parse_mbssid_elems(&rdev->wiphy,
+- attrs[NL80211_ATTR_MBSSID_ELEMS]);
++ attrs[NL80211_ATTR_MBSSID_ELEMS],
++ extack);
+
+ if (IS_ERR(mbssid))
+ return PTR_ERR(mbssid);
+--
+2.53.0
+
--- /dev/null
+From 631075b811c2966a440bb55654e31b80df10ab20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 2deb1bb54f24bd..dc7bf54e30bba1 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 1926c3b31486e8f99512e2186e11b8ff8149a699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index f74e45a34b70df..e033390e77855c 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1329,8 +1329,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 1c4738fc6785be94388c67976211b05c61403d2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 01:05:16 +0000
+Subject: xfrm6: clear dst.dev on error to avoid double netdev_put in
+ xfrm6_fill_dst()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
+
+On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst()
+releases the device reference with netdev_put() but leaves
+xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev)
+again, so the same net_device reference is released twice, underflowing
+its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for
+<dev> to become free").
+
+Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM
+device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in
+net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
+
+ ref_tracker: reference already released.
+ ref_tracker: allocated in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
+ ...
+ udpv6_sendmsg (net/ipv6/udp.c:1696)
+ ...
+ ref_tracker: freed in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
+ ...
+ WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
+ dst_destroy (net/core/dst.c:115)
+ rcu_core
+ handle_softirqs
+ ...
+
+Fixes: 84c4a9dfbf43 ("xfrm6: release dev before returning error")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 125ea9a5b8a082..3b749475f6ed65 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+ if (!xdst->u.rt6.rt6i_idev) {
+ netdev_put(dev, &xdst->u.dst.dev_tracker);
++ xdst->u.dst.dev = NULL;
+ return -ENODEV;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From ec2be4ebe29381d69855593c14309b0d65defc80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 08:13:05 -0700
+Subject: accel/amdxdna: Fix use-after-free of mm_struct in job scheduler
+
+From: Lizhi Hou <lizhi.hou@amd.com>
+
+[ Upstream commit faebb7ba1ac65fa5810b640df02ce04e509fdc11 ]
+
+amdxdna_cmd_submit() stores current->mm in job->mm without holding any
+reference. aie2_sched_job_run() later access job->mm from the DRM
+scheduler worker thread. With only a raw pointer and no structural
+reference, the mm_struct can be freed before the scheduler runs the job.
+
+Fix this by calling mmgrab() to hold a structural mm_count reference for
+the lifetime of the job, paired with mmdrop() in every cleanup path.
+
+Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
+Reviewed-by: Max Zhen <max.zhen@amd.com>
+Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
+Link: https://patch.msgid.link/20260716151305.1595780-1-lizhi.hou@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/amdxdna/amdxdna_ctx.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c
+index cfee89681ff3cf..347e046d2a0fba 100644
+--- a/drivers/accel/amdxdna/amdxdna_ctx.c
++++ b/drivers/accel/amdxdna/amdxdna_ctx.c
+@@ -393,6 +393,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job)
+ amdxdna_arg_bos_put(job);
+ amdxdna_gem_put_obj(job->cmd_bo);
+ dma_fence_put(job->fence);
++ mmdrop(job->mm);
+ }
+
+ int amdxdna_cmd_submit(struct amdxdna_client *client,
+@@ -443,6 +444,7 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
+
+ job->hwctx = hwctx;
+ job->mm = current->mm;
++ mmgrab(job->mm);
+
+ job->fence = amdxdna_fence_create(hwctx);
+ if (!job->fence) {
+@@ -475,6 +477,8 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
+ cmd_put:
+ amdxdna_gem_put_obj(job->cmd_bo);
+ free_job:
++ if (job->mm)
++ mmdrop(job->mm);
+ kfree(job);
+ return ret;
+ }
+--
+2.53.0
+
--- /dev/null
+From 8ecc0a58c6ddc06e466591cba89b0a08baac02c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 12:13:31 +0200
+Subject: accel/ivpu: Fix wrong register read in LNL failure diagnostics
+
+From: Karol Wachowski <karol.wachowski@linux.intel.com>
+
+[ Upstream commit e4159045c2704dfe146f0ccb0445d9d074cd6882 ]
+
+diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of
+VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a
+different register with a different bit layout, so failure diagnostics
+decoded the wrong register and reported a bogus error cause.
+Read the LNL interrupt status register instead.
+
+Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
+Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Link: https://patch.msgid.link/20260710101331.1899505-1-karol.wachowski@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c
+index aa33f562d29c12..e9786204feca43 100644
+--- a/drivers/accel/ivpu/ivpu_hw_btrs.c
++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c
+@@ -845,7 +845,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev)
+
+ static void diagnose_failure_lnl(struct ivpu_device *vdev)
+ {
+- u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
++ u32 reg = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) {
+ ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
+--
+2.53.0
+
--- /dev/null
+From ebcdd88f5a72c7b268446e6381c72fabbcf63a5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 1b4cfc2b68f9dc..3d81b003a5109b 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2380,6 +2380,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
+--
+2.53.0
+
--- /dev/null
+From 22169e3929e3816300cac3f41ba1e6fd00620abe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 16:15:34 +0530
+Subject: arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
+
+The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the
+compatible string for all CPU nodes to match the actual hardware.
+
+Tegra234 hardware reports:
+ # head /proc/cpuinfo | egrep 'implementer|part'
+ CPU implementer : 0x41
+ CPU part : 0xd42
+
+Which maps to (from arch/arm64/include/asm/cputype.h):
+ #define ARM_CPU_IMP_ARM 0x41
+ #define ARM_CPU_PART_CORTEX_A78AE 0xD42
+
+Fixes: a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 5b245977d6a037..345587fa1d9ad0 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -5345,7 +5345,7 @@ cpus {
+ #size-cells = <0>;
+
+ cpu0_0: cpu@0 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00000>;
+
+@@ -5364,7 +5364,7 @@ cpu0_0: cpu@0 {
+ };
+
+ cpu0_1: cpu@100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00100>;
+
+@@ -5383,7 +5383,7 @@ cpu0_1: cpu@100 {
+ };
+
+ cpu0_2: cpu@200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00200>;
+
+@@ -5402,7 +5402,7 @@ cpu0_2: cpu@200 {
+ };
+
+ cpu0_3: cpu@300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00300>;
+
+@@ -5421,7 +5421,7 @@ cpu0_3: cpu@300 {
+ };
+
+ cpu1_0: cpu@10000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10000>;
+
+@@ -5440,7 +5440,7 @@ cpu1_0: cpu@10000 {
+ };
+
+ cpu1_1: cpu@10100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10100>;
+
+@@ -5459,7 +5459,7 @@ cpu1_1: cpu@10100 {
+ };
+
+ cpu1_2: cpu@10200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10200>;
+
+@@ -5478,7 +5478,7 @@ cpu1_2: cpu@10200 {
+ };
+
+ cpu1_3: cpu@10300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10300>;
+
+@@ -5497,7 +5497,7 @@ cpu1_3: cpu@10300 {
+ };
+
+ cpu2_0: cpu@20000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20000>;
+
+@@ -5516,7 +5516,7 @@ cpu2_0: cpu@20000 {
+ };
+
+ cpu2_1: cpu@20100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20100>;
+
+@@ -5535,7 +5535,7 @@ cpu2_1: cpu@20100 {
+ };
+
+ cpu2_2: cpu@20200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20200>;
+
+@@ -5554,7 +5554,7 @@ cpu2_2: cpu@20200 {
+ };
+
+ cpu2_3: cpu@20300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20300>;
+
+--
+2.53.0
+
--- /dev/null
+From 1fb97d6b9bed1d5c877197781c430f3b0095bf44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 15:52:55 +0530
+Subject: arm64: tegra: Remove fallback compatible for GPCDMA
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit ee7863e43228a3143398dc5bbb943c9a735a8fca ]
+
+Remove the fallback compatible string "nvidia,tegra186-gpcdma" for GPCDMA
+in Tegra264. Tegra186 compatible cannot work on Tegra264 because of the
+register offset changes and absence of the reset property.
+
+Fixes: 65ef237e4810 ("arm64: tegra: Add Tegra264 support")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+index 872a69553e3c82..b16d380209a50a 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+@@ -50,7 +50,7 @@ timer@8000000 {
+ };
+
+ gpcdma: dma-controller@8400000 {
+- compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma";
++ compatible = "nvidia,tegra264-gpcdma";
+ reg = <0x0 0x08400000 0x0 0x210000>;
+ interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.53.0
+
--- /dev/null
+From ccc922ef8f86a5210e67a78b7044f9d160a886be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:36 +0530
+Subject: ASoC: amd: ps: disable MSI on resume in ACP PCI driver
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 5893013efabb056399a01e267f410cf76eba25eb ]
+
+BIOS/firmware may re-enable MSI in PCI config space during system
+level resume even though this driver only uses legacy INTx interrupts.
+If MSI is left enabled with stale address/data registers, the device
+will write interrupts to a bogus address causing IOMMU IO_PAGE_FAULT
+and interrupt delivery failure.
+
+Clear the MSI Enable bit before reinitializing the ACP hardware on
+system level resume.
+
+Fixes: 491628388005 ("ASoC: amd: ps: add callback functions for acp pci driver pm ops")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-2-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index c62299b2920417..34efb42be768fb 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -683,8 +683,37 @@ static int snd_acp_runtime_resume(struct device *dev)
+ return acp_hw_runtime_resume(dev);
+ }
+
++static void acp_disable_msi_on_resume(struct pci_dev *pdev)
++{
++ u16 control;
++
++ if (!pdev->msi_cap)
++ return;
++
++ pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &control);
++ if (control & PCI_MSI_FLAGS_ENABLE) {
++ dev_warn(&pdev->dev,
++ "ACP: MSI unexpectedly enabled after resume (flags=0x%04x), disabling\n",
++ control);
++ control &= ~PCI_MSI_FLAGS_ENABLE;
++ pci_write_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, control);
++ }
++}
++
+ static int snd_acp_resume(struct device *dev)
+ {
++ struct pci_dev *pdev = to_pci_dev(dev);
++
++ /*
++ * BIOS/firmware may re-enable MSI in PCI config space during
++ * system resume even though this driver only uses legacy INTx
++ * interrupts. If MSI is left enabled with stale address/data
++ * registers, the device will write interrupts to a bogus address
++ * causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.
++ * Explicitly clear the MSI Enable bit before reinitializing
++ * the ACP hardware.
++ */
++ acp_disable_msi_on_resume(pdev);
+ return acp_hw_resume(dev);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f0a526e2c0f97b713749c1b5b7f15e8e391a4ebf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:37 +0530
+Subject: ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
+
+The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was
+claimed with the stale name "AMD ACP6.2 audio" left over from the
+original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
+
+Fixes: 95e43a170bb1 ("ASoC: amd: add Pink Sardine ACP PCI driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 34efb42be768fb..8f37c250d4b895 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -595,7 +595,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ return -ENODEV;
+ }
+
+- ret = pci_request_regions(pci, "AMD ACP6.2 audio");
++ ret = pci_request_regions(pci, "AMD ACP6.3 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+--
+2.53.0
+
--- /dev/null
+From b81b43034a70f0c65427aceec64eb7fae330169a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:38 +0530
+Subject: ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit dec5aaa27603e1d7b426ce3504af6d1a62e4d444 ]
+
+The condition 'irq_flag | wake_irq_flag' uses bitwise OR to combine two
+integer flags that are used as booleans. Replace with logical OR '||' to
+correctly express the intended boolean check.
+
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Fixes: 7f91f012c1df0 ("ASoC: amd: ps: fix for irq handler return status")
+Link: https://patch.msgid.link/20260707060130.2514138-4-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 8f37c250d4b895..cf06d4ae299b51 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -248,7 +248,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
+ if (sdw_dma_irq_flag)
+ return IRQ_WAKE_THREAD;
+
+- if (irq_flag | wake_irq_flag)
++ if (irq_flag || wake_irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+--
+2.53.0
+
--- /dev/null
+From e40563c9c4dbfd3cc456842151b8458eae1e3cac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 11:34:30 +0100
+Subject: ASoC: cs42l43: Correct report for forced microphone jack
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]
+
+Currently if the jack is forced to the microphone mode, it will report
+as line in. Correct the report to microphone.
+
+Fixes: fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20260708103430.1395207-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l43-jack.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
+index ecba6c79523840..36fb67059e0652 100644
+--- a/sound/soc/codecs/cs42l43-jack.c
++++ b/sound/soc/codecs/cs42l43-jack.c
+@@ -310,6 +310,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
+ #define CS42L43_JACK_ABSENT 0x0
+
+ #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
++#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
+ #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
+ #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
+ #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
+@@ -871,7 +872,7 @@ static const struct cs42l43_jack_override_mode {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+ .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
+ CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
+- .report = CS42L43_JACK_LINEIN,
++ .report = CS42L43_JACK_MICROPHONE,
+ },
+ [CS42L43_JACK_RAW_OPTICAL] = {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+--
+2.53.0
+
--- /dev/null
+From 7dd4077e63cb3788a5526bfac6a44fc8f774924f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index e0e00ec026dcc4..a9861c5d663745 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From ca998965196564c302c5f85f854a2bbf537c00f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index 8e00dcc09d0c28..795c66cb47134e 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -675,11 +675,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From 1935ba20ba3c331f966222aeb753b781a0fac26d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 7a4f59202156ec..4029e082577fe1 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From 81ce6f1555511424aeac0ad1fed203d191529c98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 639eab75210f29..d3472bfc606ffc 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From f4c361e679256c00d9e5154147a53b1d052eeeef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index d3472bfc606ffc..36cc28b8986509 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+ if (unlikely(!qc)) {
+ dev_err(ap->dev, "failed to get qc");
+--
+2.53.0
+
--- /dev/null
+From bef03e3a63b02f4077b15404f33fad34451edc0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:25 -0700
+Subject: ata: sata_dwc_460ex: use platform_get_irq()
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]
+
+Replace irq_of_parse_and_map() with platform_get_irq() in both
+sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred
+way to obtain IRQs for platform devices and provides better error
+reporting. Remove the now-unnecessary #include <linux/of_irq.h>.
+
+irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.
+
+Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 4029e082577fe1..639eab75210f29 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -19,7 +19,6 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/of.h>
+-#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/libata.h>
+@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ struct sata_dwc_device *hsdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *np = dev->of_node;
+
+ hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL);
+ if (!hsdev->dma)
+@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ hsdev->dma->id = pdev->id;
+
+ /* Get SATA DMA interrupt number */
+- hsdev->dma->irq = irq_of_parse_and_map(np, 1);
+- if (!hsdev->dma->irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ hsdev->dma->irq = platform_get_irq(pdev, 1);
++ if (hsdev->dma->irq < 0)
++ return hsdev->dma->irq;
+
+ /* Get physical SATA DMA register base address */
+ hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1);
+@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {
+ static int sata_dwc_probe(struct platform_device *ofdev)
+ {
+ struct device *dev = &ofdev->dev;
+- struct device_node *np = dev->of_node;
+ struct sata_dwc_device *hsdev;
+ u32 idr, versionr;
+ char *ver = (char *)&versionr;
+@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ hsdev->dev = dev;
+
+ /* Get SATA interrupt number */
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ irq = platform_get_irq(ofdev, 0);
++ if (irq < 0)
++ return irq;
+
+ #ifdef CONFIG_SATA_DWC_OLD_DMA
+- if (!of_property_present(np, "dmas")) {
++ if (!of_property_present(dev->of_node, "dmas")) {
+ err = sata_dwc_dma_init_old(ofdev, hsdev);
+ if (err)
+ return err;
+--
+2.53.0
+
--- /dev/null
+From 4c415a68cb5d4050914a41ee8646c0e6c1d324e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 14:22:50 +0800
+Subject: Bluetooth: hci_qca: Clear memdump state on invalid dump size
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bf587a10c33e5571a299742e45bc18960b9912e7 ]
+
+qca_controller_memdump() allocates qca->qca_memdump before processing
+the first dump packet. For a sequence-zero packet it then disables IBS,
+marks memdump collection active, and reads the advertised dump size.
+
+If the controller reports a zero dump size, the error path frees the
+local qca_memdump object and returns without clearing qca->qca_memdump
+or undoing the collection state. A later memdump work item initializes
+its local pointer from qca->qca_memdump and skips allocation when that
+pointer is non-NULL, so it can operate on freed memory. The stale
+collection and IBS-disabled flags can also leave waiters or later
+transmit handling blocked behind an aborted dump.
+
+Clear the saved pointer and memdump state before returning from the
+invalid-size path, matching the cleanup used when hci_devcd_init() fails.
+
+A static analysis checker reported the stale memdump state, and manual
+source review confirmed the invalid-size failure path.
+
+Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index c649a3f702c042..b510b03dae870f 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1083,6 +1083,10 @@ static void qca_controller_memdump(struct work_struct *work)
+ if (!(qca_memdump->ram_dump_size)) {
+ bt_dev_err(hu->hdev, "Rx invalid memdump size");
+ kfree(qca_memdump);
++ qca->qca_memdump = NULL;
++ qca->memdump_state = QCA_MEMDUMP_COLLECTED;
++ clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
++ clear_bit(QCA_IBS_DISABLED, &qca->flags);
+ kfree_skb(skb);
+ mutex_unlock(&qca->hci_memdump_lock);
+ return;
+--
+2.53.0
+
--- /dev/null
+From bd174f5559e4720fd3022438ffd02a2958c47df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:40 +0300
+Subject: Bluetooth: hci_sync: extend conn_hash lookup critical sections
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit d5efd6e4b8b0634af6843178fe1a7dd2b2178a3d ]
+
+Using RCU-protected pointers outside the critical sections without
+refcount is incorrect and may result to UAF.
+
+Extend critical section to cover both hci_conn_hash lookup and use of
+the returned conn.
+
+Add surrounding rcu_read_lock() also when return value is not used, in
+preparation for RCU lockdep requirement to hci_lookup_le_connect().
+
+This avoids concurrent deletion of the conn before we are done
+dereferencing it.
+
+Also, make sure to hold hdev->lock when accessing hdev->accept_list.
+
+Fixes: 6d0417e4e1cf ("Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 42 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 39 insertions(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index a8404027724de8..651caa4a05d36e 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -1054,14 +1054,19 @@ static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
+ * In this kind of scenario skip the update and let the random
+ * address be updated at the next cycle.
+ */
++ rcu_read_lock();
++
+ if (bacmp(&hdev->random_addr, BDADDR_ANY) &&
+ (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
+ hci_lookup_le_connect(hdev))) {
+ bt_dev_dbg(hdev, "Deferring random address update");
+ hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
++ rcu_read_unlock();
+ return 0;
+ }
+
++ rcu_read_unlock();
++
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RANDOM_ADDR,
+ 6, rpa, HCI_CMD_TIMEOUT);
+ }
+@@ -2647,12 +2652,17 @@ static int hci_pause_addr_resolution(struct hci_dev *hdev)
+ /* Cannot disable addr resolution if scanning is enabled or
+ * when initiating an LE connection.
+ */
++ rcu_read_lock();
++
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+ hci_lookup_le_connect(hdev)) {
++ rcu_read_unlock();
+ bt_dev_err(hdev, "Command not allowed when scan/LE connect");
+ return -EPERM;
+ }
+
++ rcu_read_unlock();
++
+ /* Cannot disable addr resolution if advertising is enabled. */
+ err = hci_pause_advertising_sync(hdev);
+ if (err) {
+@@ -2790,6 +2800,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
+ struct hci_conn *conn;
+
++ rcu_read_lock();
++
+ conn = hci_conn_hash_lookup_create_pa_sync(hdev);
+ if (conn) {
+ struct conn_params pa;
+@@ -2799,6 +2811,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ bacpy(&pa.addr, &conn->dst);
+ pa.addr_type = conn->dst_type;
+
++ rcu_read_unlock();
++
+ /* Clear first since there could be addresses left
+ * behind.
+ */
+@@ -2808,6 +2822,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ err = hci_le_add_accept_list_sync(hdev, &pa,
+ &num_entries);
+ goto done;
++ } else {
++ rcu_read_unlock();
+ }
+ }
+
+@@ -2818,10 +2834,13 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ * the controller.
+ */
+ list_for_each_entry_safe(b, t, &hdev->le_accept_list, list) {
+- if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type))
++ rcu_read_lock();
++
++ if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) {
++ rcu_read_unlock();
+ continue;
++ }
+
+- /* Pointers not dereferenced, no locks needed */
+ pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns,
+ &b->bdaddr,
+ b->bdaddr_type);
+@@ -2829,6 +2848,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ &b->bdaddr,
+ b->bdaddr_type);
+
++ rcu_read_unlock();
++
+ /* If the device is not likely to connect or report,
+ * remove it from the acceptlist.
+ */
+@@ -2955,6 +2976,8 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
+ if (sent) {
+ struct hci_conn *conn;
+
++ rcu_read_lock();
++
+ conn = hci_conn_hash_lookup_ba(hdev, PA_LINK,
+ &sent->bdaddr);
+ if (conn) {
+@@ -2979,8 +3002,12 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
+ phy++;
+ }
+
++ rcu_read_unlock();
++
+ if (num_phy)
+ goto done;
++ } else {
++ rcu_read_unlock();
+ }
+ }
+ }
+@@ -3231,12 +3258,16 @@ int hci_update_passive_scan_sync(struct hci_dev *hdev)
+ /* If there is at least one pending LE connection, we should
+ * keep the background scan running.
+ */
++ bool exists;
+
+ /* If controller is connecting, we should not start scanning
+ * since some controllers are not able to scan and connect at
+ * the same time.
+ */
+- if (hci_lookup_le_connect(hdev))
++ rcu_read_lock();
++ exists = hci_lookup_le_connect(hdev);
++ rcu_read_unlock();
++ if (exists)
+ return 0;
+
+ bt_dev_dbg(hdev, "start background scanning");
+@@ -3451,6 +3482,7 @@ int hci_write_fast_connectable_sync(struct hci_dev *hdev, bool enable)
+ }
+
+ static bool disconnected_accept_list_entries(struct hci_dev *hdev)
++ __must_hold(&hdev->lock)
+ {
+ struct bdaddr_list *b;
+
+@@ -3491,12 +3523,16 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ if (hdev->scanning_paused)
+ return 0;
+
++ hci_dev_lock(hdev);
++
+ if (hci_dev_test_flag(hdev, HCI_CONNECTABLE) ||
+ disconnected_accept_list_entries(hdev))
+ scan = SCAN_PAGE;
+ else
+ scan = SCAN_DISABLED;
+
++ hci_dev_unlock(hdev);
++
+ if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
+ scan |= SCAN_INQUIRY;
+
+--
+2.53.0
+
--- /dev/null
+From 388f30bacb0a8e5a3b42914f547ded7cd8ebea97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:41 +0300
+Subject: Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 16cd66443957e4ad42155c6fec401012f600c6f8 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF.
+
+Take hdev->lock for hci_conn lookup and hci_abort_conn(). Don't use RCU
+to ensure the conn is fully initialized at this point.
+
+Fixes: 227a0cdf4a028 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 4c8b172e85d006..0ef1192e5e452e 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3082,6 +3082,8 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_unpair_device *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3089,6 +3091,11 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return 0;
+
+@@ -3096,6 +3103,7 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+@@ -3243,6 +3251,8 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_disconnect *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3250,6 +3260,11 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return -ENOTCONN;
+
+@@ -3257,6 +3272,7 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From b98ea4835443e40bf36e6911cf7dcbf88f67fcfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:42 +0300
+Subject: Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit da55f570191d5d72f10c607a7043b947eb05ea46 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF. Use of hci_conn in hci_sync callbacks also
+needs to hold refcount to avoid UAF.
+
+Take appropriate locks for hci_conn lookups, and take refcount for
+hci_conn pointers stored in mgmt_pending_cmd so that the pointer stays
+valid.
+
+When accessing conn->state, ensure hdev->lock is held to avoid data
+race.
+
+Fixes: 7b445e220db9 ("Bluetooth: MGMT: Fix holding hci_conn reference while command is queued")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 0ef1192e5e452e..79eb605be2804c 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7325,6 +7325,9 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
+ rp.max_tx_power = HCI_TX_POWER_INVALID;
+ }
+
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
+ &rp, sizeof(rp));
+
+@@ -7339,6 +7342,8 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ int err;
+ __le16 handle;
+
++ hci_dev_lock(hdev);
++
+ /* Make sure we are still connected */
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+@@ -7346,12 +7351,16 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ else
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
+
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ handle = cpu_to_le16(conn->handle);
+
++ hci_dev_unlock(hdev);
++
+ /* Refresh RSSI each time */
+ err = hci_read_rssi_sync(hdev, handle);
+
+@@ -7485,6 +7494,9 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
+ }
+
+ complete:
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
+ sizeof(rp));
+
+@@ -7501,15 +7513,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
+ memset(&hci_cp, 0, sizeof(hci_cp));
+ hci_read_clock_sync(hdev, &hci_cp);
+
++ hci_dev_lock(hdev);
++
+ /* Make sure connection still exists */
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ hci_cp.handle = cpu_to_le16(conn->handle);
+ hci_cp.which = 0x01; /* Piconet clock */
+
++ hci_dev_unlock(hdev);
++
+ return hci_read_clock_sync(hdev, &hci_cp);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 6709dfd15a30e38b2f47b9898dbece5c60b0baf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 12:15:18 +0800
+Subject: Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 2bf282f8f715f5d05d6f4c49ffb3bd241c5e667e ]
+
+MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter
+update changes an existing LE central connection. The queued work currently
+stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later
+LOAD_CONN_PARAM request can clear disabled parameters and free that entry
+before hci_cmd_sync_work() runs the queued callback.
+
+Do not keep the borrowed hci_conn_params pointer in queued work. Queue the
+hci_conn instead and hold a reference until the queued callback completes.
+When the work runs, revalidate that the connection is still present, look
+up the current hci_conn_params entry, and cancel the update if userspace
+removed that entry while the work was pending.
+
+Copy the interval values from the current params entry under hdev->lock,
+then drop the lock and keep using hci_le_conn_update_sync() to issue the
+update.
+
+Validation reproduced this kernel report:
+BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth]
+Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377
+Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x5f0
+ kasan_report+0xe0/0x110
+ conn_update_sync+0x2a/0xf0 [bluetooth]
+ hci_cmd_sync_work+0x187/0x210 [bluetooth]
+ process_one_work+0x4fd/0xbc0
+ worker_thread+0x2d8/0x570
+ kthread+0x1ad/0x1f0
+ ret_from_fork+0x3c9/0x540
+ ret_from_fork_asm+0x1a/0x30
+
+Allocated by task 466:
+ hci_conn_params_add+0xa6/0x240 [bluetooth]
+ load_conn_param+0x4e1/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Freed by task 474:
+ kfree+0x313/0x590
+ hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth]
+ load_conn_param+0x4bf/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Fixes: 0ece498c27d8c ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection")
+Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 44 +++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 410910f64c1c49..4c8b172e85d006 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7924,14 +7924,36 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
+
+ static int conn_update_sync(struct hci_dev *hdev, void *data)
+ {
+- struct hci_conn_params *params = data;
+- struct hci_conn *conn;
++ struct hci_conn *conn = data;
++ struct hci_conn_params *params;
++ struct hci_conn_params local = {};
+
+- conn = hci_conn_hash_lookup_le(hdev, ¶ms->addr, params->addr_type);
+- if (!conn)
+- return -ECANCELED;
++ hci_dev_lock(hdev);
++
++ if (!hci_conn_valid(hdev, conn) || conn->role != HCI_ROLE_MASTER)
++ goto cancel;
++
++ params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
++ if (!params)
++ goto cancel;
++
++ local.conn_min_interval = params->conn_min_interval;
++ local.conn_max_interval = params->conn_max_interval;
++ local.conn_latency = params->conn_latency;
++ local.supervision_timeout = params->supervision_timeout;
+
+- return hci_le_conn_update_sync(hdev, conn, params);
++ hci_dev_unlock(hdev);
++
++ return hci_le_conn_update_sync(hdev, conn, &local);
++
++cancel:
++ hci_dev_unlock(hdev);
++ return -ECANCELED;
++}
++
++static void conn_update_sync_destroy(struct hci_dev *hdev, void *data, int err)
++{
++ hci_conn_put(data);
+ }
+
+ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+@@ -8041,9 +8063,13 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+ (conn->le_conn_min_interval != min ||
+ conn->le_conn_max_interval != max ||
+ conn->le_conn_latency != latency ||
+- conn->le_supv_timeout != timeout))
+- hci_cmd_sync_queue(hdev, conn_update_sync,
+- hci_param, NULL);
++ conn->le_supv_timeout != timeout)) {
++ hci_conn_get(conn);
++ if (hci_cmd_sync_queue(hdev, conn_update_sync,
++ conn,
++ conn_update_sync_destroy) < 0)
++ hci_conn_put(conn);
++ }
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 103e94ee11876df59d78882d3f385a804e1077da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 86a48d009d1ba2..afab479ac89448 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -413,7 +413,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From c3c1459465ebd5f82daa1c053b57917a83cc13c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 06:23:57 +0200
+Subject: bpf, sockmap: Reject unhashed UDP sockets on sockmap update
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 66efd3368ae10d05e08fbe6425b50fdec7186ac7 ]
+
+UDP sockets get SOCK_RCU_FREE set when (auto-)bound. This means
+sk_is_refcounted(unbound) = true, while sk_is_refcounted(bound) = false.
+
+Because sockmap accepts unbound UDP sockets, a BPF program can increment a
+socket's refcount via lookup. If the socket is subsequently bound, the
+transition from unbound to bound causes bpf_sk_release() to skip the
+decrement of the refcount, causing a memory leak.
+
+unreferenced object 0xffff88810bc2eb40 (size 1984):
+ comm "test_progs", pid 2451, jiffies 4295320596
+ hex dump (first 32 bytes):
+ 7f 00 00 01 7f 00 00 01 d2 04 1b b7 04 d2 00 00 ................
+ 02 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace (crc bdee079d):
+ kmem_cache_alloc_noprof+0x557/0x660
+ sk_prot_alloc+0x69/0x240
+ sk_alloc+0x30/0x460
+ inet_create+0x2ce/0xf80
+ __sock_create+0x25b/0x5c0
+ __sys_socket+0x119/0x1d0
+ __x64_sys_socket+0x72/0xd0
+ do_syscall_64+0xa1/0x5f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Instead of special-casing for refcounted sockets, reject unhashed UDP
+sockets during sockmap updates, as there is no benefit to supporting those.
+This effectively reverts the commit under Fixes, with two exceptions:
+
+1. sock_map_sk_state_allowed() maintains a fall-through `return true`.
+2. In the spirit of commit b8b8315e39ff ("bpf, sockmap: Remove unhash
+ handler for BPF sockmap usage"), the proto::unhash BPF handler is not
+ reintroduced.
+
+Historical note: this issue is related to commit 67312adc96b5 ("bpf: reject
+unhashed sockets in bpf_sk_assign").
+
+Fixes: 0c48eefae712 ("sock_map: Lift socket state restriction for datagram sockets")
+Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20260707-sockmap-lookup-udp-leak-v4-2-f878346f27ab@rbox.co
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 5947b38e4f8b6f..70bbc78fb079f7 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -542,6 +542,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+ {
+ if (sk_is_tcp(sk))
+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
++ if (sk_is_udp(sk))
++ return sk_hashed(sk);
+ if (sk_is_stream_unix(sk))
+ return (1 << sk->sk_state) & TCPF_ESTABLISHED;
+ if (sk_is_vsock(sk) &&
+--
+2.53.0
+
--- /dev/null
+From 4682a68a4c4295fcfc9bb5346e066e9d085ab158 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 14:40:17 -0700
+Subject: btrfs: fallback to transaction csum tree on a commit root csum miss
+
+From: Boris Burkov <boris@bur.io>
+
+[ Upstream commit 3dcd50730814e5220072d2b26d0587af6bfb6dbe ]
+
+We have been running with commit root csums enabled for some time and
+have noticed a slight uptick in zero csum errors. Investigating those
+revealed that they were same transaction reads of extents that were just
+relocated, but the extent map generation was long ago.
+
+It turns out that relocation intentionally does not update the extent
+generation (replace_file_extents()), but must write a new csum since the
+data has moved, so we must account for this with commit root csum reading.
+
+Luckily this is a short lived condition: after the relocation transaction
+the commit root will once again have the csum. So we can add a generic
+fallback to the lookup to try again with the transaction csum root.
+
+Fixes: f07b855c56b1 ("btrfs: try to search for data csums in commit root")
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Boris Burkov <boris@bur.io>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/file-item.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
+index a2f851eaadca06..9b19b33e85b687 100644
+--- a/fs/btrfs/file-item.c
++++ b/fs/btrfs/file-item.c
+@@ -350,6 +350,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;
+ int ret = 0;
+ u32 bio_offset = 0;
++ bool using_commit_root = false;
+
+ if ((inode->flags & BTRFS_INODE_NODATASUM) ||
+ test_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state))
+@@ -423,6 +424,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * from across transactions.
+ */
+ if (bbio->csum_search_commit_root) {
++ using_commit_root = true;
+ path->search_commit_root = true;
+ path->skip_locking = true;
+ down_read(&fs_info->commit_root_sem);
+@@ -455,6 +457,28 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * assume this is the case.
+ */
+ if (count == 0) {
++ /*
++ * If an extent is relocated in the current transaction
++ * then relocation writes a new csum without updating
++ * the extent map generation. Until the next commit, we
++ * will see a hole in that case, so we need to fallback
++ * to searching the transaction csum root.
++ *
++ * Note that a commit root lookup of a referenced extent can
++ * only miss, not return a stale csum. A freed extent's csum
++ * is deleted in the same transaction and its bytenr is not
++ * reusable until that transaction has committed and the
++ * extent is unpinned.
++ */
++ if (using_commit_root) {
++ up_read(&fs_info->commit_root_sem);
++ using_commit_root = false;
++ path->search_commit_root = false;
++ path->skip_locking = false;
++ btrfs_release_path(path);
++ continue;
++ }
++
+ memset(csum_dst, 0, csum_size);
+ count = 1;
+
+@@ -473,7 +497,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ bio_offset += count * sectorsize;
+ }
+
+- if (bbio->csum_search_commit_root)
++ if (using_commit_root)
+ up_read(&fs_info->commit_root_sem);
+ return ret;
+ }
+--
+2.53.0
+
--- /dev/null
+From 60d215f225a2032a43dd753403713225c06217ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index fc76013b1a3e01..ea68328d289cba 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1857,6 +1857,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From bf749f2fdd002d98273707f500af4488e493c66c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index ab873bd6719209..9828da12765f5c 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -554,6 +554,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From 4465c4ee97df08c5f2f06664b0ded2b4939da058 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 16:00:04 +0000
+Subject: btrfs: use bool type for btrfs_path members used as booleans
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit d7fe41044b3ac8f9b5965de499a13ac9ae947e79 ]
+
+Many fields of struct btrfs_path are used as booleans but their type is
+an unsigned int (of one 1 bit width to save space). Change the type to
+bool keeping the :1 suffix so that they combine with the previous u8
+fields in order to save space. This makes the code more clear by using
+explicit true/false and more in line with the preferred style, preserving
+the size of the structure.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 3dcd50730814 ("btrfs: fallback to transaction csum tree on a commit root csum miss")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/backref.c | 16 ++++++++--------
+ fs/btrfs/block-group.c | 8 ++++----
+ fs/btrfs/ctree.c | 28 ++++++++++++++--------------
+ fs/btrfs/ctree.h | 16 ++++++++--------
+ fs/btrfs/defrag.c | 4 ++--
+ fs/btrfs/dev-replace.c | 4 ++--
+ fs/btrfs/extent-tree.c | 8 ++++----
+ fs/btrfs/file-item.c | 12 ++++++------
+ fs/btrfs/free-space-cache.c | 4 ++--
+ fs/btrfs/free-space-tree.c | 4 ++--
+ fs/btrfs/inode-item.c | 2 +-
+ fs/btrfs/inode.c | 4 ++--
+ fs/btrfs/qgroup.c | 4 ++--
+ fs/btrfs/raid-stripe-tree.c | 4 ++--
+ fs/btrfs/relocation.c | 8 ++++----
+ fs/btrfs/scrub.c | 20 ++++++++++----------
+ fs/btrfs/send.c | 14 +++++++-------
+ fs/btrfs/tree-log.c | 20 ++++++++++----------
+ fs/btrfs/volumes.c | 6 +++---
+ fs/btrfs/xattr.c | 2 +-
+ 20 files changed, 94 insertions(+), 94 deletions(-)
+
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index e050d0938dc45f..0c47b4570a7bf8 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -1408,12 +1408,12 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,
+ if (!path)
+ return -ENOMEM;
+ if (!ctx->trans) {
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ }
+
+ if (ctx->time_seq == BTRFS_SEQ_LAST)
+- path->skip_locking = 1;
++ path->skip_locking = true;
+
+ again:
+ head = NULL;
+@@ -1560,7 +1560,7 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,
+
+ btrfs_release_path(path);
+
+- ret = add_missing_keys(ctx->fs_info, &preftrees, path->skip_locking == 0);
++ ret = add_missing_keys(ctx->fs_info, &preftrees, !path->skip_locking);
+ if (ret)
+ goto out;
+
+@@ -2833,8 +2833,8 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_inf
+ }
+
+ /* Current backref iterator only supports iteration in commit root */
+- ret->path->search_commit_root = 1;
+- ret->path->skip_locking = 1;
++ ret->path->search_commit_root = true;
++ ret->path->skip_locking = true;
+ ret->fs_info = fs_info;
+
+ return ret;
+@@ -3307,8 +3307,8 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
+ level = cur->level + 1;
+
+ /* Search the tree to find parent blocks referring to the block */
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ path->lowest_level = level;
+ ret = btrfs_search_slot(NULL, root, tree_key, path, 0, 0);
+ path->lowest_level = 0;
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 1e57f7d04c47ec..e6bac34ebe83d6 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -613,8 +613,8 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
+ extent_root = btrfs_extent_root(fs_info, max_t(u64, block_group->start,
+ BTRFS_SUPER_INFO_OFFSET));
+
+- path->skip_locking = 1;
+- path->search_commit_root = 1;
++ path->skip_locking = true;
++ path->search_commit_root = true;
+ path->reada = READA_FORWARD;
+
+ search_offset = index * div_u64(block_group->length, max_index);
+@@ -744,8 +744,8 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
+ * root to add free space. So we skip locking and search the commit
+ * root, since its read-only
+ */
+- path->skip_locking = 1;
+- path->search_commit_root = 1;
++ path->skip_locking = true;
++ path->search_commit_root = true;
+ path->reada = READA_FORWARD;
+
+ key.objectid = last;
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index 27e2adc2ee717b..0f2e9f33dd0cbc 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1709,9 +1709,9 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root,
+ level = btrfs_header_level(b);
+ /*
+ * Ensure that all callers have set skip_locking when
+- * p->search_commit_root = 1.
++ * p->search_commit_root is true.
+ */
+- ASSERT(p->skip_locking == 1);
++ ASSERT(p->skip_locking);
+
+ goto out;
+ }
+@@ -3858,10 +3858,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
+ }
+ btrfs_release_path(path);
+
+- path->keep_locks = 1;
+- path->search_for_split = 1;
++ path->keep_locks = true;
++ path->search_for_split = true;
+ ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+- path->search_for_split = 0;
++ path->search_for_split = false;
+ if (ret > 0)
+ ret = -EAGAIN;
+ if (ret < 0)
+@@ -3888,11 +3888,11 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
+ if (ret)
+ goto err;
+
+- path->keep_locks = 0;
++ path->keep_locks = false;
+ btrfs_unlock_up_safe(path, 1);
+ return 0;
+ err:
+- path->keep_locks = 0;
++ path->keep_locks = false;
+ return ret;
+ }
+
+@@ -4610,11 +4610,11 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
+ u32 nritems;
+ int level;
+ int ret = 1;
+- int keep_locks = path->keep_locks;
++ const bool keep_locks = path->keep_locks;
+
+ ASSERT(!path->nowait);
+ ASSERT(path->lowest_level == 0);
+- path->keep_locks = 1;
++ path->keep_locks = true;
+ again:
+ cur = btrfs_read_lock_root_node(root);
+ level = btrfs_header_level(cur);
+@@ -4704,7 +4704,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
+ * 0 is returned if another key is found, < 0 if there are any errors
+ * and 1 is returned if there are no higher keys in the tree
+ *
+- * path->keep_locks should be set to 1 on the search made before
++ * path->keep_locks should be set to true on the search made before
+ * calling this function.
+ */
+ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
+@@ -4803,13 +4803,13 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
+ next = NULL;
+ btrfs_release_path(path);
+
+- path->keep_locks = 1;
++ path->keep_locks = true;
+
+ if (time_seq) {
+ ret = btrfs_search_old_slot(root, &key, path, time_seq);
+ } else {
+ if (path->need_commit_sem) {
+- path->need_commit_sem = 0;
++ path->need_commit_sem = false;
+ need_commit_sem = true;
+ if (path->nowait) {
+ if (!down_read_trylock(&fs_info->commit_root_sem)) {
+@@ -4822,7 +4822,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
+ }
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ }
+- path->keep_locks = 0;
++ path->keep_locks = false;
+
+ if (ret < 0)
+ goto done;
+@@ -4961,7 +4961,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
+ if (need_commit_sem) {
+ int ret2;
+
+- path->need_commit_sem = 1;
++ path->need_commit_sem = true;
+ ret2 = finish_need_commit_sem_search(path);
+ up_read(&fs_info->commit_root_sem);
+ if (ret2)
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 16dd11c4853130..692370fc07b280 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -65,21 +65,21 @@ struct btrfs_path {
+ * set by btrfs_split_item, tells search_slot to keep all locks
+ * and to force calls to keep space in the nodes
+ */
+- unsigned int search_for_split:1;
++ bool search_for_split:1;
+ /* Keep some upper locks as we walk down. */
+- unsigned int keep_locks:1;
+- unsigned int skip_locking:1;
+- unsigned int search_commit_root:1;
+- unsigned int need_commit_sem:1;
+- unsigned int skip_release_on_error:1;
++ bool keep_locks:1;
++ bool skip_locking:1;
++ bool search_commit_root:1;
++ bool need_commit_sem:1;
++ bool skip_release_on_error:1;
+ /*
+ * Indicate that new item (btrfs_search_slot) is extending already
+ * existing item and ins_len contains only the data size and not item
+ * header (ie. sizeof(struct btrfs_item) is not included).
+ */
+- unsigned int search_for_extension:1;
++ bool search_for_extension:1;
+ /* Stop search if any locks need to be taken (for read) */
+- unsigned int nowait:1;
++ bool nowait:1;
+ };
+
+ #define BTRFS_PATH_AUTO_FREE(path_name) \
+diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c
+index a4cc1bc6356227..2e3c011d410a6f 100644
+--- a/fs/btrfs/defrag.c
++++ b/fs/btrfs/defrag.c
+@@ -472,7 +472,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ memcpy(&key, &root->defrag_progress, sizeof(key));
+ }
+
+- path->keep_locks = 1;
++ path->keep_locks = true;
+
+ ret = btrfs_search_forward(root, &key, path, BTRFS_OLDEST_GENERATION);
+ if (ret < 0)
+@@ -515,7 +515,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ /*
+ * Now that we reallocated the node we can find the next key. Note that
+ * btrfs_find_next_key() can release our path and do another search
+- * without COWing, this is because even with path->keep_locks = 1,
++ * without COWing, this is because even with path->keep_locks == true,
+ * btrfs_search_slot() / ctree.c:unlock_up() does not keeps a lock on a
+ * node when path->slots[node_level - 1] does not point to the last
+ * item or a slot beyond the last item (ctree.c:unlock_up()). Therefore
+diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
+index a4eaef60549eed..b6c7da8e1bc8b1 100644
+--- a/fs/btrfs/dev-replace.c
++++ b/fs/btrfs/dev-replace.c
+@@ -489,8 +489,8 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
+ }
+
+ path->reada = READA_FORWARD;
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ key.objectid = src_dev->devid;
+ key.type = BTRFS_DEV_EXTENT_KEY;
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 6ef7cc116bfcca..d2d96f366dac31 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -788,7 +788,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
+ want = extent_ref_type(parent, owner);
+ if (insert) {
+ extra_size = btrfs_extent_inline_ref_size(want);
+- path->search_for_extension = 1;
++ path->search_for_extension = true;
+ } else
+ extra_size = -1;
+
+@@ -954,7 +954,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
+
+ if (!path->keep_locks) {
+ btrfs_release_path(path);
+- path->keep_locks = 1;
++ path->keep_locks = true;
+ goto again;
+ }
+
+@@ -975,11 +975,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
+ *ref_ret = (struct btrfs_extent_inline_ref *)ptr;
+ out:
+ if (path->keep_locks) {
+- path->keep_locks = 0;
++ path->keep_locks = false;
+ btrfs_unlock_up_safe(path, 1);
+ }
+ if (insert)
+- path->search_for_extension = 0;
++ path->search_for_extension = false;
+ return ret;
+ }
+
+diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
+index 4b7c40f05e8f9e..a2f851eaadca06 100644
+--- a/fs/btrfs/file-item.c
++++ b/fs/btrfs/file-item.c
+@@ -394,8 +394,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * between reading the free space cache and updating the csum tree.
+ */
+ if (btrfs_is_free_space_inode(inode)) {
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ }
+
+ /*
+@@ -423,8 +423,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * from across transactions.
+ */
+ if (bbio->csum_search_commit_root) {
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ down_read(&fs_info->commit_root_sem);
+ }
+
+@@ -1168,10 +1168,10 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
+ }
+
+ btrfs_release_path(path);
+- path->search_for_extension = 1;
++ path->search_for_extension = true;
+ ret = btrfs_search_slot(trans, root, &file_key, path,
+ csum_size, 1);
+- path->search_for_extension = 0;
++ path->search_for_extension = false;
+ if (ret < 0)
+ goto out;
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 9828da12765f5c..7ee3d8f05c1a21 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -971,8 +971,8 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+ path = btrfs_alloc_path();
+ if (!path)
+ return 0;
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ /*
+ * We must pass a path with search_commit_root set to btrfs_iget in
+diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
+index c3734892d6548b..f9ffb1c8988d90 100644
+--- a/fs/btrfs/free-space-tree.c
++++ b/fs/btrfs/free-space-tree.c
+@@ -1699,8 +1699,8 @@ int btrfs_load_free_space_tree(struct btrfs_caching_control *caching_ctl)
+ * Just like caching_thread() doesn't want to deadlock on the extent
+ * tree, we don't want to deadlock on the free space tree.
+ */
+- path->skip_locking = 1;
+- path->search_commit_root = 1;
++ path->skip_locking = true;
++ path->search_commit_root = true;
+ path->reada = READA_FORWARD;
+
+ info = btrfs_search_free_space_info(NULL, block_group, path, 0);
+diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
+index 7e14e1bbcf389b..b73e1dd97208a8 100644
+--- a/fs/btrfs/inode-item.c
++++ b/fs/btrfs/inode-item.c
+@@ -312,7 +312,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
+ if (!path)
+ return -ENOMEM;
+
+- path->skip_release_on_error = 1;
++ path->skip_release_on_error = true;
+ ret = btrfs_insert_empty_item(trans, root, path, &key,
+ ins_len);
+ if (ret == -EEXIST) {
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 30a34cd905ba48..36f75c6a8344d4 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -7170,8 +7170,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
+ * point the commit_root has everything we need.
+ */
+ if (btrfs_is_free_space_inode(inode)) {
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ }
+
+ ret = btrfs_lookup_file_extent(NULL, root, path, objectid, start, 0);
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 261aa65019207f..b4c6cbbcd168e6 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -3882,8 +3882,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
+ * Rescan should only search for commit root, and any later difference
+ * should be recorded by qgroup
+ */
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ while (!ret && !(stopped = rescan_should_stop(fs_info))) {
+ trans = btrfs_start_transaction(fs_info->fs_root, 0);
+diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
+index cc6f6095cc9fd0..f6f02463dd1a9b 100644
+--- a/fs/btrfs/raid-stripe-tree.c
++++ b/fs/btrfs/raid-stripe-tree.c
+@@ -394,8 +394,8 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
+ return -ENOMEM;
+
+ if (stripe->rst_search_commit_root) {
+- path->skip_locking = 1;
+- path->search_commit_root = 1;
++ path->skip_locking = true;
++ path->search_commit_root = true;
+ }
+
+ ret = btrfs_search_slot(NULL, stripe_root, &stripe_key, path, 0, 0);
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index ea68328d289cba..86430435d3acc7 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -3176,8 +3176,8 @@ static int __add_tree_block(struct reloc_control *rc,
+ key.offset = blocksize;
+ }
+
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ ret = btrfs_search_slot(NULL, rc->extent_root, &key, path, 0, 0);
+ if (ret < 0)
+ return ret;
+@@ -3369,8 +3369,8 @@ int find_next_extent(struct reloc_control *rc, struct btrfs_path *path,
+ key.type = BTRFS_EXTENT_ITEM_KEY;
+ key.offset = 0;
+
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+ ret = btrfs_search_slot(NULL, rc->extent_root, &key, path,
+ 0, 0);
+ if (ret < 0)
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 16936d17166eef..368f1d44449351 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -463,10 +463,10 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx(
+ refcount_set(&sctx->refs, 1);
+ sctx->is_dev_replace = is_dev_replace;
+ sctx->fs_info = fs_info;
+- sctx->extent_path.search_commit_root = 1;
+- sctx->extent_path.skip_locking = 1;
+- sctx->csum_path.search_commit_root = 1;
+- sctx->csum_path.skip_locking = 1;
++ sctx->extent_path.search_commit_root = true;
++ sctx->extent_path.skip_locking = true;
++ sctx->csum_path.search_commit_root = true;
++ sctx->csum_path.skip_locking = true;
+ for (i = 0; i < SCRUB_TOTAL_STRIPES; i++) {
+ int ret;
+
+@@ -2103,10 +2103,10 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
+ * as the data stripe bytenr may be smaller than previous extent. Thus
+ * we have to use our own extent/csum paths.
+ */
+- extent_path.search_commit_root = 1;
+- extent_path.skip_locking = 1;
+- csum_path.search_commit_root = 1;
+- csum_path.skip_locking = 1;
++ extent_path.search_commit_root = true;
++ extent_path.skip_locking = true;
++ csum_path.search_commit_root = true;
++ csum_path.skip_locking = true;
+
+ for (int i = 0; i < data_stripes; i++) {
+ int stripe_index;
+@@ -2630,8 +2630,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
+ return -ENOMEM;
+
+ path->reada = READA_FORWARD;
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ key.objectid = scrub_dev->devid;
+ key.type = BTRFS_DEV_EXTENT_KEY;
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index 04473387ee8bf0..34a57f11e4bb9c 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -633,9 +633,9 @@ static struct btrfs_path *alloc_path_for_send(void)
+ path = btrfs_alloc_path();
+ if (!path)
+ return NULL;
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
+- path->need_commit_sem = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
++ path->need_commit_sem = true;
+ return path;
+ }
+
+@@ -7643,10 +7643,10 @@ static int btrfs_compare_trees(struct btrfs_root *left_root,
+ goto out;
+ }
+
+- left_path->search_commit_root = 1;
+- left_path->skip_locking = 1;
+- right_path->search_commit_root = 1;
+- right_path->skip_locking = 1;
++ left_path->search_commit_root = true;
++ left_path->skip_locking = true;
++ right_path->search_commit_root = true;
++ right_path->skip_locking = true;
+
+ /*
+ * Strategy: Go to the first items of both trees. Then do
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index a0e12b4fb95614..f84065b69464c7 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -602,9 +602,9 @@ static int overwrite_item(struct walk_control *wc)
+ insert:
+ btrfs_release_path(wc->subvol_path);
+ /* try to insert the key into the destination tree */
+- wc->subvol_path->skip_release_on_error = 1;
++ wc->subvol_path->skip_release_on_error = true;
+ ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &wc->log_key, item_size);
+- wc->subvol_path->skip_release_on_error = 0;
++ wc->subvol_path->skip_release_on_error = false;
+
+ dst_eb = wc->subvol_path->nodes[0];
+ dst_slot = wc->subvol_path->slots[0];
+@@ -5734,8 +5734,8 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
+ search_path = btrfs_alloc_path();
+ if (!search_path)
+ return -ENOMEM;
+- search_path->search_commit_root = 1;
+- search_path->skip_locking = 1;
++ search_path->search_commit_root = true;
++ search_path->skip_locking = true;
+
+ while (cur_offset < item_size) {
+ u64 parent;
+@@ -6052,8 +6052,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
+ key.type = BTRFS_INODE_ITEM_KEY;
+ key.offset = 0;
+
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (WARN_ON_ONCE(ret > 0)) {
+@@ -6073,8 +6073,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
+ }
+
+ btrfs_release_path(path);
+- path->search_commit_root = 0;
+- path->skip_locking = 0;
++ path->search_commit_root = false;
++ path->skip_locking = false;
+
+ return ret;
+ }
+@@ -7232,8 +7232,8 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+- path->skip_locking = 1;
+- path->search_commit_root = 1;
++ path->skip_locking = true;
++ path->search_commit_root = true;
+
+ key.objectid = ino;
+ key.type = BTRFS_INODE_REF_KEY;
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 630fb5885692b1..863f69b9cf14bd 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1839,8 +1839,8 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
+ }
+
+ path->reada = READA_FORWARD;
+- path->search_commit_root = 1;
+- path->skip_locking = 1;
++ path->search_commit_root = true;
++ path->skip_locking = true;
+
+ key.objectid = device->devid;
+ key.type = BTRFS_DEV_EXTENT_KEY;
+@@ -7627,7 +7627,7 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
+ * chunk tree, to keep it simple, just skip locking on the chunk tree.
+ */
+ ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
+- path->skip_locking = 1;
++ path->skip_locking = true;
+
+ /*
+ * Read all device items, and then all the chunk items. All
+diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
+index b6f01d6c79e7f3..b6e91e8fb7e388 100644
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -97,7 +97,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+- path->skip_release_on_error = 1;
++ path->skip_release_on_error = true;
+
+ if (!value) {
+ di = btrfs_lookup_xattr(trans, root, path,
+--
+2.53.0
+
--- /dev/null
+From b8109ce34ff7d62d1ce7304795aec5816801c679 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 8656ab388c83e6..9ec929bc0c0da4 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -350,6 +350,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -358,8 +370,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2017,8 +2028,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From fb1b444827869f2be258864c66f0d754c63685e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:23 +0200
+Subject: can: raw: add locking for raw flags bitfield
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 1e5185c090589f4146d728ab36417d8a5419f127 ]
+
+With commit 890e5198a6e5 ("can: raw: use bitfields to store flags in
+struct raw_sock") the formerly separate integer values have been integrated
+into a single bitfield. This led to a read-modify-write operation when
+changing a flag in raw_setsockopt() which now needs a locking to prevent
+concurrent access.
+
+Instead of adding a lock/unlock hell in each of the flag manipulations this
+patch introduces a wrapper for a new raw_setsockopt_locked() function
+analogue to the isotp_setsockopt[_locked]() approach in net/can/isotp.c
+
+Fixes: 890e5198a6e5 ("can: raw: use bitfields to store flags in struct raw_sock")
+Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
+Closes: https://lore.kernel.org/linux-can/20260503112200.22727-1-eulgyukim@snu.ac.kr/
+Tested-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
+Tested-by: Vincent Mailhol <mailhol@kernel.org>
+Link: https://patch.msgid.link/20260504111928.41856-1-socketcan@hartkopp.net
+[mkl: use Closes tag instead of Link]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 66 +++++++++++++++++++++++----------------------------
+ 1 file changed, 30 insertions(+), 36 deletions(-)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 263e7167d2f529..365559d19dc323 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -560,8 +560,8 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
+ return RAW_MIN_NAMELEN;
+ }
+
+-static int raw_setsockopt(struct socket *sock, int level, int optname,
+- sockptr_t optval, unsigned int optlen)
++static int raw_setsockopt_locked(struct socket *sock, int optname,
++ sockptr_t optval, unsigned int optlen)
+ {
+ struct sock *sk = sock->sk;
+ struct raw_sock *ro = raw_sk(sk);
+@@ -573,9 +573,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ int flag;
+ int err = 0;
+
+- if (level != SOL_CAN_RAW)
+- return -EINVAL;
+-
+ switch (optname) {
+ case CAN_RAW_FILTER:
+ if (optlen % sizeof(struct can_filter) != 0)
+@@ -596,17 +593,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ return -EFAULT;
+ }
+
+- rtnl_lock();
+- lock_sock(sk);
+-
+ dev = ro->dev;
+- if (ro->bound && dev) {
+- if (dev->reg_state != NETREG_REGISTERED) {
+- if (count > 1)
+- kfree(filter);
+- err = -ENODEV;
+- goto out_fil;
+- }
++ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED) {
++ if (count > 1)
++ kfree(filter);
++ return -ENODEV;
+ }
+
+ if (ro->bound) {
+@@ -620,7 +611,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ if (err) {
+ if (count > 1)
+ kfree(filter);
+- goto out_fil;
++ return err;
+ }
+
+ /* remove old filter registrations */
+@@ -640,11 +631,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ }
+ ro->filter = filter;
+ ro->count = count;
+-
+- out_fil:
+- release_sock(sk);
+- rtnl_unlock();
+-
+ break;
+
+ case CAN_RAW_ERR_FILTER:
+@@ -656,16 +642,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+
+ err_mask &= CAN_ERR_MASK;
+
+- rtnl_lock();
+- lock_sock(sk);
+-
+ dev = ro->dev;
+- if (ro->bound && dev) {
+- if (dev->reg_state != NETREG_REGISTERED) {
+- err = -ENODEV;
+- goto out_err;
+- }
+- }
++ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED)
++ return -ENODEV;
+
+ /* remove current error mask */
+ if (ro->bound) {
+@@ -674,7 +653,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ err_mask);
+
+ if (err)
+- goto out_err;
++ return err;
+
+ /* remove old err_mask registration */
+ raw_disable_errfilter(sock_net(sk), dev, sk,
+@@ -683,11 +662,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+
+ /* link new err_mask to the socket */
+ ro->err_mask = err_mask;
+-
+- out_err:
+- release_sock(sk);
+- rtnl_unlock();
+-
+ break;
+
+ case CAN_RAW_LOOPBACK:
+@@ -767,6 +741,26 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ return err;
+ }
+
++static int raw_setsockopt(struct socket *sock, int level, int optname,
++ sockptr_t optval, unsigned int optlen)
++{
++ struct sock *sk = sock->sk;
++ int err;
++
++ if (level != SOL_CAN_RAW)
++ return -EINVAL;
++
++ rtnl_lock();
++ lock_sock(sk);
++
++ err = raw_setsockopt_locked(sock, optname, optval, optlen);
++
++ release_sock(sk);
++ rtnl_unlock();
++
++ return err;
++}
++
+ static int raw_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen)
+ {
+--
+2.53.0
+
--- /dev/null
+From 1b4cd226c425467cf0aa973b27c15bd20810686d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 19:25:39 +0200
+Subject: cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit d2d5c129d07ea8eb91cd8a8633b5774116c4d171 ]
+
+If arch_scale_freq_ref() is not defined for a given arch (like x86, for
+example), cpufreq_update_pressure() will always set cpufreq_pressure to
+zero for all CPUs in the system, which is generally problematic on
+systems with asymmetric capacity [1].
+
+However, in the absence of arch_scale_freq_ref(), it is reasonable
+to assume that cpuinfo.max_freq is the maximum sustainable frequency
+for the given cpufreq policy. Moreover, there are cases in which
+arch_scale_freq_ref() would need to be defined to return essentially
+the cpuinfo.max_freq value anyway (for example, intel_pstate on
+hybrid platforms).
+
+For the above reasons, update cpufreq_update_pressure() to fall back to
+using cpuinfo.max_freq as the reference frequency if zero is returned by
+arch_scale_freq_ref().
+
+Fixes: 75d659317bb1 ("cpufreq: Add a cpufreq pressure feedback for the scheduler")
+Link: https://lore.kernel.org/lkml/CAKfTPtBuRLfYNnR4w--cFZYZy-R8gaPEgVwCcaMmbCcJ2H-muQ@mail.gmail.com/ [1]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
+Tested-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> # cluster scheduling
+Acked-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://patch.msgid.link/5086499.GXAFRqVoOG@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index a70df77f9b7d11..ced96d9e254ee4 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -2584,6 +2584,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
+
+ cpu = cpumask_first(policy->related_cpus);
+ max_freq = arch_scale_freq_ref(cpu);
++ if (!max_freq)
++ max_freq = policy->cpuinfo.max_freq;
++
+ capped_freq = policy->max;
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 8fcd1113346ecc3b538ae26ea697913096d274ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 21:36:25 +0200
+Subject: dpll: fix NULL pointer dereference in dpll_msg_add_pin_ref_sync()
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit d2e914a4a0d0f753dbae830264850d044026167c ]
+
+When a dpll_pin is shared across multiple dpll_device instances and
+those devices are being unregistered (e.g. during driver module removal),
+a NULL pointer dereference can occur in dpll_msg_add_pin_ref_sync().
+
+This happens under the following conditions:
+ - A pin is registered with two or more dpll devices (dpll_A, dpll_B)
+ - The pin has ref_sync pairs with other pins
+ - During unregistration of dpll_A's pins, a ref_sync partner pin is
+ unregistered first, removing it from dpll_A->pin_refs
+ - But since the partner pin is still registered with dpll_B, its
+ dpll_refs is not empty, so dpll_pin_ref_sync_pair_del() does NOT
+ run and the partner stays in the pin's ref_sync_pins xarray
+ - When the pin itself is then unregistered from dpll_A, the delete
+ notification calls dpll_msg_add_pin_ref_sync() which finds the
+ partner in ref_sync_pins, passes dpll_pin_available() (partner is
+ still registered with dpll_B), but dpll_pin_on_dpll_priv(dpll_A,
+ partner) returns NULL because partner was already removed from
+ dpll_A->pin_refs
+ - The NULL priv pointer is passed to the driver's ref_sync_get
+ callback, which dereferences it
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000034
+ Oops: Oops: 0000 [#1] SMP NOPTI
+ RIP: 0010:zl3073x_dpll_input_pin_ref_sync_get+0x73/0x80 [zl3073x]
+ Call Trace:
+ dpll_msg_add_pin_ref_sync+0xb8/0x200
+ dpll_cmd_pin_get_one+0x3b6/0x4b0
+ dpll_pin_event_send+0x72/0x140
+ __dpll_pin_unregister+0x5a/0x2b0
+ dpll_pin_unregister+0x49/0x70
+
+Fix this by skipping ref_sync pins whose priv pointer cannot be resolved
+for the current dpll device.
+
+Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20260710193625.1378822-1-ivecera@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/dpll_netlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
+index de8b065280d15d..eb23ee401aaef8 100644
+--- a/drivers/dpll/dpll_netlink.c
++++ b/drivers/dpll/dpll_netlink.c
+@@ -486,6 +486,9 @@ dpll_msg_add_pin_ref_sync(struct sk_buff *msg, struct dpll_pin *pin,
+ if (!dpll_pin_available(ref_sync_pin))
+ continue;
+ ref_sync_pin_priv = dpll_pin_on_dpll_priv(dpll, ref_sync_pin);
++ /* Pin may have been unregistered from this dpll already */
++ if (!ref_sync_pin_priv)
++ continue;
+ if (WARN_ON(!ops->ref_sync_get))
+ return -EOPNOTSUPP;
+ ret = ops->ref_sync_get(pin, pin_priv, ref_sync_pin,
+--
+2.53.0
+
--- /dev/null
+From 4961a8f4a362d21fc182c1f9381bbc33ce9de051 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index 833987015b8bbc..ed42b9d05a07d5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -257,7 +257,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From d20f79d2e94584c0ea1adefbb118ca8f570270ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index 33351deeea4f0b..07eaf71955c447 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -16,9 +16,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -28,9 +28,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 5863741f59e6d8e1109884611d7272af269d1f17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 23:33:49 +0300
+Subject: drm/i915/wm: clear the plane ddb_y entries on plane disable
+
+From: Vinod Govindapillai <vinod.govindapillai@intel.com>
+
+[ Upstream commit e89978c1cff54e265345c66e1177d19ea5a8bc00 ]
+
+The UV/Y plane DDB entriess are never cleared on
+sk_wm_plane_disable_noatomic() and can leave stale DDB state
+for NV12 planes on pre-Gen11 devices
+
+Fixes: d34b59d5ba41 ("drm/i915: Add skl_wm_plane_disable_noatomic()")
+Assisted-by: Copilot:claude-sonnet-4.6
+Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
+Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
+Link: https://patch.msgid.link/20260615203355.218578-2-vinod.govindapillai@intel.com
+(cherry picked from commit 60f68a6ba298fd1e971a2d91576304bee89a16fc)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/skl_watermark.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
+index a5862998bf1447..eb54fffc698864 100644
+--- a/drivers/gpu/drm/i915/display/skl_watermark.c
++++ b/drivers/gpu/drm/i915/display/skl_watermark.c
+@@ -3815,7 +3815,7 @@ void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc,
+ return;
+
+ skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
+- skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
++ skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb_y[plane->id], 0, 0);
+
+ crtc_state->wm.skl.plane_min_ddb[plane->id] = 0;
+ crtc_state->wm.skl.plane_interim_ddb[plane->id] = 0;
+--
+2.53.0
+
--- /dev/null
+From 019e8c37c65e6ecdd8f3ac9e374d7df3a2dcfb09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 16:29:12 +0800
+Subject: drm/panthor: Check debugfs GEM lock initialization
+
+From: Linmao Li <lilinmao@kylinos.cn>
+
+[ Upstream commit 022e901333c3054656a640794e842bab7af5a75c ]
+
+drmm_mutex_init() can fail while registering the managed cleanup action.
+When that happens, drmm_add_action_or_reset() destroys the mutex before
+returning the error. Continuing initialization would therefore leave the
+debugfs GEM object list with an unusable lock.
+
+Propagate the error as is already done for the other managed mutexes in
+panthor_device_init().
+
+Fixes: a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS")
+Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://patch.msgid.link/20260713082912.321021-1-lilinmao@kylinos.cn
+Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_device.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
+index 962a10e00848ef..cdf82d83de7abe 100644
+--- a/drivers/gpu/drm/panthor/panthor_device.c
++++ b/drivers/gpu/drm/panthor/panthor_device.c
+@@ -182,7 +182,10 @@ int panthor_device_init(struct panthor_device *ptdev)
+ return ret;
+
+ #ifdef CONFIG_DEBUG_FS
+- drmm_mutex_init(&ptdev->base, &ptdev->gems.lock);
++ ret = drmm_mutex_init(&ptdev->base, &ptdev->gems.lock);
++ if (ret)
++ return ret;
++
+ INIT_LIST_HEAD(&ptdev->gems.node);
+ #endif
+
+--
+2.53.0
+
--- /dev/null
+From b76da5fcd731e219b22f12dd45f16ff21d62b48a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Nov 2025 14:22:07 +0100
+Subject: drm/xe: Allow the caller to pass guc_buf_cache size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Winiarski <michal.winiarski@intel.com>
+
+[ Upstream commit dca2701a6277399f9d255f09b4c34d9a7171c09b ]
+
+An upcoming change will use GuC buffer cache as a place where GuC
+migration data will be stored, and the memory requirement for that is
+larger than indirect data.
+Allow the caller to pass the size based on the intended usecase.
+
+Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Link: https://patch.msgid.link/20251112132220.516975-12-michal.winiarski@intel.com
+Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
+Stable-dep-of: 56441f9e08ad ("drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_buf.c | 44 ++++++++++++++++++++++++---------
+ drivers/gpu/drm/xe/xe_guc_buf.h | 1 +
+ 2 files changed, 34 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_buf.c b/drivers/gpu/drm/xe/xe_guc_buf.c
+index 502ca3a4ee6064..989c546d05689d 100644
+--- a/drivers/gpu/drm/xe/xe_guc_buf.c
++++ b/drivers/gpu/drm/xe/xe_guc_buf.c
+@@ -13,6 +13,8 @@
+ #include "xe_guc_buf.h"
+ #include "xe_sa.h"
+
++#define XE_GUC_BUF_CACHE_DEFAULT_SIZE SZ_8K
++
+ static struct xe_guc *cache_to_guc(struct xe_guc_buf_cache *cache)
+ {
+ return container_of(cache, struct xe_guc, buf);
+@@ -23,21 +25,12 @@ static struct xe_gt *cache_to_gt(struct xe_guc_buf_cache *cache)
+ return guc_to_gt(cache_to_guc(cache));
+ }
+
+-/**
+- * xe_guc_buf_cache_init() - Initialize the GuC Buffer Cache.
+- * @cache: the &xe_guc_buf_cache to initialize
+- *
+- * The Buffer Cache allows to obtain a reusable buffer that can be used to pass
+- * indirect H2G data to GuC without a need to create a ad-hoc allocation.
+- *
+- * Return: 0 on success or a negative error code on failure.
+- */
+-int xe_guc_buf_cache_init(struct xe_guc_buf_cache *cache)
++static int guc_buf_cache_init(struct xe_guc_buf_cache *cache, u32 size)
+ {
+ struct xe_gt *gt = cache_to_gt(cache);
+ struct xe_sa_manager *sam;
+
+- sam = __xe_sa_bo_manager_init(gt_to_tile(gt), SZ_8K, 0, sizeof(u32));
++ sam = __xe_sa_bo_manager_init(gt_to_tile(gt), size, 0, sizeof(u32));
+ if (IS_ERR(sam))
+ return PTR_ERR(sam);
+ cache->sam = sam;
+@@ -48,6 +41,35 @@ int xe_guc_buf_cache_init(struct xe_guc_buf_cache *cache)
+ return 0;
+ }
+
++/**
++ * xe_guc_buf_cache_init() - Initialize the GuC Buffer Cache.
++ * @cache: the &xe_guc_buf_cache to initialize
++ *
++ * The Buffer Cache allows to obtain a reusable buffer that can be used to pass
++ * data to GuC or read data from GuC without a need to create a ad-hoc allocation.
++ *
++ * Return: 0 on success or a negative error code on failure.
++ */
++int xe_guc_buf_cache_init(struct xe_guc_buf_cache *cache)
++{
++ return guc_buf_cache_init(cache, XE_GUC_BUF_CACHE_DEFAULT_SIZE);
++}
++
++/**
++ * xe_guc_buf_cache_init_with_size() - Initialize the GuC Buffer Cache.
++ * @cache: the &xe_guc_buf_cache to initialize
++ * @size: size in bytes
++ *
++ * Like xe_guc_buf_cache_init(), except it allows the caller to make the cache
++ * buffer larger, allowing to accommodate larger objects.
++ *
++ * Return: 0 on success or a negative error code on failure.
++ */
++int xe_guc_buf_cache_init_with_size(struct xe_guc_buf_cache *cache, u32 size)
++{
++ return guc_buf_cache_init(cache, max(XE_GUC_BUF_CACHE_DEFAULT_SIZE, size));
++}
++
+ /**
+ * xe_guc_buf_cache_dwords() - Number of dwords the GuC Buffer Cache supports.
+ * @cache: the &xe_guc_buf_cache to query
+diff --git a/drivers/gpu/drm/xe/xe_guc_buf.h b/drivers/gpu/drm/xe/xe_guc_buf.h
+index 0d67604d96bdd7..8204e589625013 100644
+--- a/drivers/gpu/drm/xe/xe_guc_buf.h
++++ b/drivers/gpu/drm/xe/xe_guc_buf.h
+@@ -12,6 +12,7 @@
+ #include "xe_guc_buf_types.h"
+
+ int xe_guc_buf_cache_init(struct xe_guc_buf_cache *cache);
++int xe_guc_buf_cache_init_with_size(struct xe_guc_buf_cache *cache, u32 size);
+ u32 xe_guc_buf_cache_dwords(struct xe_guc_buf_cache *cache);
+ struct xe_guc_buf xe_guc_buf_reserve(struct xe_guc_buf_cache *cache, u32 dwords);
+ struct xe_guc_buf xe_guc_buf_from_data(struct xe_guc_buf_cache *cache,
+--
+2.53.0
+
--- /dev/null
+From 9ed4608b529ad9ac9038c01670054875f1cd47d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 12:07:44 +0000
+Subject: drm/xe/sa: Shadow buffer support in the sub-allocator pool
+
+From: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+
+[ Upstream commit 1f2cf5295cdba71818288c9e495b4ef5097565ed ]
+
+The existing sub-allocator is limited to managing a single buffer object.
+This enhancement introduces shadow buffer functionality to support
+scenarios requiring dual buffer management.
+
+The changes include added shadow buffer object creation capability,
+Management for both primary and shadow buffers, and appropriate locking
+mechanisms for thread-safe operations.
+
+This enables more flexible buffer allocation strategies in scenarios where
+shadow buffering is required.
+
+Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Suggested-by: Matthew Brost <matthew.brost@intel.com>
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20251118120745.3460172-2-satyanarayana.k.v.p@intel.com
+Stable-dep-of: 56441f9e08ad ("drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_buf.c | 2 +-
+ drivers/gpu/drm/xe/xe_sa.c | 67 +++++++++++++++++++++++++++-
+ drivers/gpu/drm/xe/xe_sa.h | 20 ++++++++-
+ drivers/gpu/drm/xe/xe_sa_types.h | 3 ++
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 3 ++
+ 5 files changed, 91 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_buf.c b/drivers/gpu/drm/xe/xe_guc_buf.c
+index 989c546d05689d..3de6377ae2d521 100644
+--- a/drivers/gpu/drm/xe/xe_guc_buf.c
++++ b/drivers/gpu/drm/xe/xe_guc_buf.c
+@@ -30,7 +30,7 @@ static int guc_buf_cache_init(struct xe_guc_buf_cache *cache, u32 size)
+ struct xe_gt *gt = cache_to_gt(cache);
+ struct xe_sa_manager *sam;
+
+- sam = __xe_sa_bo_manager_init(gt_to_tile(gt), size, 0, sizeof(u32));
++ sam = __xe_sa_bo_manager_init(gt_to_tile(gt), size, 0, sizeof(u32), 0);
+ if (IS_ERR(sam))
+ return PTR_ERR(sam);
+ cache->sam = sam;
+diff --git a/drivers/gpu/drm/xe/xe_sa.c b/drivers/gpu/drm/xe/xe_sa.c
+index fedd017d6dd36a..d9e0d30f8135e9 100644
+--- a/drivers/gpu/drm/xe/xe_sa.c
++++ b/drivers/gpu/drm/xe/xe_sa.c
+@@ -29,6 +29,7 @@ static void xe_sa_bo_manager_fini(struct drm_device *drm, void *arg)
+ kvfree(sa_manager->cpu_ptr);
+
+ sa_manager->bo = NULL;
++ sa_manager->shadow = NULL;
+ }
+
+ /**
+@@ -37,12 +38,14 @@ static void xe_sa_bo_manager_fini(struct drm_device *drm, void *arg)
+ * @size: number of bytes to allocate
+ * @guard: number of bytes to exclude from suballocations
+ * @align: alignment for each suballocated chunk
++ * @flags: flags for suballocator
+ *
+ * Prepares the suballocation manager for suballocations.
+ *
+ * Return: a pointer to the &xe_sa_manager or an ERR_PTR on failure.
+ */
+-struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u32 guard, u32 align)
++struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size,
++ u32 guard, u32 align, u32 flags)
+ {
+ struct xe_device *xe = tile_to_xe(tile);
+ struct xe_sa_manager *sa_manager;
+@@ -79,6 +82,26 @@ struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u3
+ memset(sa_manager->cpu_ptr, 0, bo->ttm.base.size);
+ }
+
++ if (flags & XE_SA_BO_MANAGER_FLAG_SHADOW) {
++ struct xe_bo *shadow;
++
++ ret = drmm_mutex_init(&xe->drm, &sa_manager->swap_guard);
++ if (ret)
++ return ERR_PTR(ret);
++
++ shadow = xe_managed_bo_create_pin_map(xe, tile, size,
++ XE_BO_FLAG_VRAM_IF_DGFX(tile) |
++ XE_BO_FLAG_GGTT |
++ XE_BO_FLAG_GGTT_INVALIDATE |
++ XE_BO_FLAG_PINNED_NORESTORE);
++ if (IS_ERR(shadow)) {
++ drm_err(&xe->drm, "Failed to prepare %uKiB BO for SA manager (%pe)\n",
++ size / SZ_1K, shadow);
++ return ERR_CAST(shadow);
++ }
++ sa_manager->shadow = shadow;
++ }
++
+ drm_suballoc_manager_init(&sa_manager->base, managed_size, align);
+ ret = drmm_add_action_or_reset(&xe->drm, xe_sa_bo_manager_fini,
+ sa_manager);
+@@ -88,6 +111,48 @@ struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u3
+ return sa_manager;
+ }
+
++/**
++ * xe_sa_bo_swap_shadow() - Swap the SA BO with shadow BO.
++ * @sa_manager: the XE sub allocator manager
++ *
++ * Swaps the sub-allocator primary buffer object with shadow buffer object.
++ *
++ * Return: None.
++ */
++void xe_sa_bo_swap_shadow(struct xe_sa_manager *sa_manager)
++{
++ struct xe_device *xe = tile_to_xe(sa_manager->bo->tile);
++
++ xe_assert(xe, sa_manager->shadow);
++ lockdep_assert_held(&sa_manager->swap_guard);
++
++ swap(sa_manager->bo, sa_manager->shadow);
++ if (!sa_manager->bo->vmap.is_iomem)
++ sa_manager->cpu_ptr = sa_manager->bo->vmap.vaddr;
++}
++
++/**
++ * xe_sa_bo_sync_shadow() - Sync the SA Shadow BO with primary BO.
++ * @sa_bo: the sub-allocator buffer object.
++ *
++ * Synchronize sub-allocator shadow buffer object with primary buffer object.
++ *
++ * Return: None.
++ */
++void xe_sa_bo_sync_shadow(struct drm_suballoc *sa_bo)
++{
++ struct xe_sa_manager *sa_manager = to_xe_sa_manager(sa_bo->manager);
++ struct xe_device *xe = tile_to_xe(sa_manager->bo->tile);
++
++ xe_assert(xe, sa_manager->shadow);
++ lockdep_assert_held(&sa_manager->swap_guard);
++
++ xe_map_memcpy_to(xe, &sa_manager->shadow->vmap,
++ drm_suballoc_soffset(sa_bo),
++ xe_sa_bo_cpu_addr(sa_bo),
++ drm_suballoc_size(sa_bo));
++}
++
+ /**
+ * __xe_sa_bo_new() - Make a suballocation but use custom gfp flags.
+ * @sa_manager: the &xe_sa_manager
+diff --git a/drivers/gpu/drm/xe/xe_sa.h b/drivers/gpu/drm/xe/xe_sa.h
+index 99dbf0eea54025..90ffa93a000ce4 100644
+--- a/drivers/gpu/drm/xe/xe_sa.h
++++ b/drivers/gpu/drm/xe/xe_sa.h
+@@ -14,12 +14,14 @@
+ struct dma_fence;
+ struct xe_tile;
+
+-struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u32 guard, u32 align);
++#define XE_SA_BO_MANAGER_FLAG_SHADOW BIT(0)
++struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size,
++ u32 guard, u32 align, u32 flags);
+ struct drm_suballoc *__xe_sa_bo_new(struct xe_sa_manager *sa_manager, u32 size, gfp_t gfp);
+
+ static inline struct xe_sa_manager *xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u32 align)
+ {
+- return __xe_sa_bo_manager_init(tile, size, SZ_4K, align);
++ return __xe_sa_bo_manager_init(tile, size, SZ_4K, align, 0);
+ }
+
+ /**
+@@ -68,4 +70,18 @@ static inline void *xe_sa_bo_cpu_addr(struct drm_suballoc *sa)
+ drm_suballoc_soffset(sa);
+ }
+
++void xe_sa_bo_swap_shadow(struct xe_sa_manager *sa_manager);
++void xe_sa_bo_sync_shadow(struct drm_suballoc *sa_bo);
++
++/**
++ * xe_sa_bo_swap_guard() - Retrieve the SA BO swap guard within sub-allocator.
++ * @sa_manager: the &xe_sa_manager
++ *
++ * Return: Sub alloctor swap guard mutex.
++ */
++static inline struct mutex *xe_sa_bo_swap_guard(struct xe_sa_manager *sa_manager)
++{
++ return &sa_manager->swap_guard;
++}
++
+ #endif
+diff --git a/drivers/gpu/drm/xe/xe_sa_types.h b/drivers/gpu/drm/xe/xe_sa_types.h
+index cb7238799dcb20..1085c9c37d6b61 100644
+--- a/drivers/gpu/drm/xe/xe_sa_types.h
++++ b/drivers/gpu/drm/xe/xe_sa_types.h
+@@ -12,6 +12,9 @@ struct xe_bo;
+ struct xe_sa_manager {
+ struct drm_suballoc_manager base;
+ struct xe_bo *bo;
++ struct xe_bo *shadow;
++ /** @swap_guard: Timeline guard updating @bo and @shadow */
++ struct mutex swap_guard;
+ void *cpu_ptr;
+ bool is_iomem;
+ };
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+index 739a3eb180b53c..1a7d767632dadf 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+@@ -160,9 +160,12 @@ static int alloc_bb_pool(struct xe_tile *tile, struct xe_sriov_vf_ccs_ctx *ctx)
+ offset = 0;
+ xe_map_memset(xe, &sa_manager->bo->vmap, offset, MI_NOOP,
+ bb_pool_size);
++ xe_map_memset(xe, &sa_manager->shadow->vmap, offset, MI_NOOP,
++ bb_pool_size);
+
+ offset = bb_pool_size - sizeof(u32);
+ xe_map_wr(xe, &sa_manager->bo->vmap, offset, u32, MI_BATCH_BUFFER_END);
++ xe_map_wr(xe, &sa_manager->shadow->vmap, offset, u32, MI_BATCH_BUFFER_END);
+
+ ctx->mem.ccs_bb_pool = sa_manager;
+
+--
+2.53.0
+
--- /dev/null
+From c2cefd16b8e59282a2e881419b34f12dcecc4c0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:24:40 -0700
+Subject: drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 56441f9e08ad68697295b8835266d2bc48ab59b5 ]
+
+xe_bo_move() attaches VF CCS read/write batch buffers (BBs) to a BO
+after it transitions NULL/SYSTEM -> TT, and detaches them after it
+transitions TT -> SYSTEM. Both operations were done synchronously on
+the CPU immediately after building the move's copy/clear fence,
+without waiting for that fence to signal. This creates two races with
+VF migration:
+
+- Attach happens too late relative to the copy job it is meant to
+ protect. If the copy job is submitted before the CCS BBs are
+ attached, a VF migration event that pauses execution mid-copy can
+ observe partially copied CCS metadata without the attach state
+ needed to correctly save/restore it.
+
+- Detach happens too early relative to the copy job that moves data
+ out of TT. The CCS BBs are torn down right after the copy fence is
+ obtained, while the actual blit may still be in flight. A VF
+ migration event that pauses execution mid-copy can then race the
+ save/restore path against the still-running blit, and the CCS BBs
+ it would need to make sense of the paused state have already been
+ removed.
+
+Fix both races:
+
+- Move the attach call to before the copy/clear job is submitted, so
+ the CCS BBs are already registered by the time the copy runs. On
+ attach failure, unwind and bail out of the move. xe_migrate_ccs_rw_copy()
+ now takes the destination resource explicitly, since bo->ttm.resource
+ is not updated to the new resource until after the move commits.
+
+- Detach only after explicitly waiting for the copy fence to signal,
+ instead of tearing down the CCS BBs immediately after obtaining it.
+
+While here, also fix xe_sriov_vf_ccs_attach_bo() to properly unwind and
+propagate errors: the per-context loop previously never broke out on
+error, silently discarding earlier failures. Unwind by clearing each
+attached context directly via xe_migrate_ccs_rw_copy_clear() instead of
+reusing xe_sriov_vf_ccs_detach_bo(), which requires both contexts to be
+attached before it will clean up either one.
+
+Fixes: 864690cf4dd6 ("drm/xe/vf: Attach and detach CCS copy commands with BO")
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Cc: Michał Winiarski <michal.winiarski@intel.com>
+Cc: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Assisted-by: GitHub_Copilot:claude-sonnet-5
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Acked-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+Link: https://patch.msgid.link/20260714062440.3421225-1-matthew.brost@intel.com
+(cherry picked from commit d45ad0aa7a1eb5d7288b5ed948b05695611dc39e)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 34 +++++++++++++++++++---------
+ drivers/gpu/drm/xe/xe_migrate.c | 5 +++-
+ drivers/gpu/drm/xe/xe_migrate.h | 1 +
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 20 ++++++++++++++--
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.h | 3 ++-
+ 5 files changed, 48 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 0dabe85351392e..1d46b61bf1285d 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -930,6 +930,21 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ xe_pm_runtime_get_noresume(xe);
+ }
+
++ /*
++ * Attach CCS BBs before submitting the copy job below so a VF
++ * migration racing the copy sees valid, up to date attach state.
++ */
++ if (IS_VF_CCS_READY(xe) &&
++ ((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
++ (old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
++ handle_system_ccs) {
++ ret = xe_sriov_vf_ccs_attach_bo(bo, new_mem);
++ if (ret) {
++ xe_pm_runtime_put(xe);
++ goto out;
++ }
++ }
++
+ if (move_lacks_source) {
+ u32 flags = 0;
+
+@@ -967,22 +982,19 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ ttm_bo_move_null(ttm_bo, new_mem);
+ }
+
+- dma_fence_put(fence);
+- xe_pm_runtime_put(xe);
+-
+ /*
+- * CCS meta data is migrated from TT -> SMEM. So, let us detach the
+- * BBs from BO as it is no longer needed.
++ * Detach must wait for the copy above to complete: a VF migration
++ * racing an in-flight copy must still see valid CCS BBs, so don't
++ * tear them down until the copy fence has signaled.
+ */
+ if (IS_VF_CCS_READY(xe) && old_mem_type == XE_PL_TT &&
+- new_mem->mem_type == XE_PL_SYSTEM)
++ new_mem->mem_type == XE_PL_SYSTEM) {
++ dma_fence_wait(fence, false);
+ xe_sriov_vf_ccs_detach_bo(bo);
++ }
+
+- if (IS_VF_CCS_READY(xe) &&
+- ((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
+- (old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
+- handle_system_ccs)
+- ret = xe_sriov_vf_ccs_attach_bo(bo);
++ dma_fence_put(fence);
++ xe_pm_runtime_put(xe);
+
+ out:
+ if ((!ttm_bo->resource || ttm_bo->resource->mem_type == XE_PL_SYSTEM) &&
+diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
+index 6a0c088d09fb33..e0a14360d312e0 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.c
++++ b/drivers/gpu/drm/xe/xe_migrate.c
+@@ -1001,6 +1001,8 @@ static int emit_flush_invalidate(struct xe_exec_queue *q, u32 *dw, int i,
+ * @tile: Tile whose migration context to be used.
+ * @q : Execution to be used along with migration context.
+ * @src_bo: The buffer object @src is currently bound to.
++ * @new_mem: The (not yet committed) destination resource @src_bo is being
++ * moved into; src_bo->ttm.resource is still the old resource.
+ * @read_write : Creates BB commands for CCS read/write.
+ *
+ * Creates batch buffer instructions to copy CCS metadata from CCS pool to
+@@ -1012,12 +1014,13 @@ static int emit_flush_invalidate(struct xe_exec_queue *q, u32 *dw, int i,
+ */
+ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ struct xe_bo *src_bo,
++ struct ttm_resource *new_mem,
+ enum xe_sriov_vf_ccs_rw_ctxs read_write)
+
+ {
+ bool src_is_pltt = read_write == XE_SRIOV_VF_CCS_READ_CTX;
+ bool dst_is_pltt = read_write == XE_SRIOV_VF_CCS_WRITE_CTX;
+- struct ttm_resource *src = src_bo->ttm.resource;
++ struct ttm_resource *src = new_mem;
+ struct xe_migrate *m = tile->migrate;
+ struct xe_gt *gt = tile->primary_gt;
+ u32 batch_size, batch_size_allocated;
+diff --git a/drivers/gpu/drm/xe/xe_migrate.h b/drivers/gpu/drm/xe/xe_migrate.h
+index 438c3bb66d9b24..8bac669685ee92 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.h
++++ b/drivers/gpu/drm/xe/xe_migrate.h
+@@ -129,6 +129,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
+
+ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ struct xe_bo *src_bo,
++ struct ttm_resource *new_mem,
+ enum xe_sriov_vf_ccs_rw_ctxs read_write);
+
+ void xe_migrate_ccs_rw_copy_clear(struct xe_bo *src_bo,
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+index d62156195f321b..e03714ef7ae996 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+@@ -330,6 +330,8 @@ void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx)
+ /**
+ * xe_sriov_vf_ccs_attach_bo - Insert CCS read write commands in the BO.
+ * @bo: the &buffer object to which batch buffer commands will be added.
++ * @new_mem: the (not yet committed) destination resource @bo is being moved
++ * into; bo->ttm.resource is still the old resource at this point.
+ *
+ * This function shall be called only by VF. It inserts the PTEs and copy
+ * command instructions in the BO by calling xe_migrate_ccs_rw_copy()
+@@ -337,7 +339,7 @@ void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx)
+ *
+ * Returns: 0 if successful, negative error code on failure.
+ */
+-int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo)
++int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo, struct ttm_resource *new_mem)
+ {
+ struct xe_device *xe = xe_bo_device(bo);
+ enum xe_sriov_vf_ccs_rw_ctxs ctx_id;
+@@ -356,7 +358,21 @@ int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo)
+ xe_assert(xe, !bb);
+
+ ctx = &xe->sriov.vf.ccs.contexts[ctx_id];
+- err = xe_migrate_ccs_rw_copy(tile, ctx->mig_q, bo, ctx_id);
++ err = xe_migrate_ccs_rw_copy(tile, ctx->mig_q, bo, new_mem, ctx_id);
++ if (err)
++ goto err_unwind;
++ }
++ return 0;
++
++err_unwind:
++ /*
++ * Clean up any contexts already attached. Can't reuse
++ * xe_sriov_vf_ccs_detach_bo() here as it requires both contexts
++ * attached before cleaning up either one.
++ */
++ for_each_ccs_rw_ctx(ctx_id) {
++ if (bo->bb_ccs[ctx_id])
++ xe_migrate_ccs_rw_copy_clear(bo, ctx_id);
+ }
+ return err;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+index a9c6512f87034f..00d2c9dbe00d9a 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+@@ -11,11 +11,12 @@
+ #include "xe_sriov_vf_ccs_types.h"
+
+ struct drm_printer;
++struct ttm_resource;
+ struct xe_device;
+ struct xe_bo;
+
+ int xe_sriov_vf_ccs_init(struct xe_device *xe);
+-int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo);
++int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo, struct ttm_resource *new_mem);
+ int xe_sriov_vf_ccs_detach_bo(struct xe_bo *bo);
+ int xe_sriov_vf_ccs_register_context(struct xe_device *xe);
+ void xe_sriov_vf_ccs_print(struct xe_device *xe, struct drm_printer *p);
+--
+2.53.0
+
--- /dev/null
+From b96a726fb586a35949b47299a8eda7661b50d883 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 12:07:45 +0000
+Subject: drm/xe/vf: Shadow buffer management for CCS read/write operations
+
+From: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+
+[ Upstream commit fa18290bf0723b02bfa8d30d2e14722f0d096c2c ]
+
+CCS copy command consist of 5-dword sequence. If vCPU halts during
+save/restore operations while these sequences are being programmed,
+incomplete writes can cause page faults during IGPU CCS metadata saving.
+
+Use shadow buffer management to prevent partial write issues during CCS
+operations.
+
+Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Suggested-by: Matthew Brost <matthew.brost@intel.com>
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20251118120745.3460172-3-satyanarayana.k.v.p@intel.com
+Stable-dep-of: 56441f9e08ad ("drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_migrate.c | 57 ++++++++++++++++++++++++++--
+ drivers/gpu/drm/xe/xe_migrate.h | 3 ++
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 19 ++++++++--
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.h | 1 +
+ 4 files changed, 73 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
+index b6905f35d6c81f..6a0c088d09fb33 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.c
++++ b/drivers/gpu/drm/xe/xe_migrate.c
+@@ -33,6 +33,7 @@
+ #include "xe_res_cursor.h"
+ #include "xe_sa.h"
+ #include "xe_sched_job.h"
++#include "xe_sriov_vf_ccs.h"
+ #include "xe_sync.h"
+ #include "xe_trace_bo.h"
+ #include "xe_validation.h"
+@@ -1022,12 +1023,16 @@ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ u32 batch_size, batch_size_allocated;
+ struct xe_device *xe = gt_to_xe(gt);
+ struct xe_res_cursor src_it, ccs_it;
++ struct xe_sriov_vf_ccs_ctx *ctx;
++ struct xe_sa_manager *bb_pool;
+ u64 size = xe_bo_size(src_bo);
+ struct xe_bb *bb = NULL;
+ u64 src_L0, src_L0_ofs;
+ u32 src_L0_pt;
+ int err;
+
++ ctx = &xe->sriov.vf.ccs.contexts[read_write];
++
+ xe_res_first_sg(xe_bo_sg(src_bo), 0, size, &src_it);
+
+ xe_res_first_sg(xe_bo_sg(src_bo), xe_bo_ccs_pages_start(src_bo),
+@@ -1060,11 +1065,15 @@ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ size -= src_L0;
+ }
+
++ bb_pool = ctx->mem.ccs_bb_pool;
++ guard(mutex) (xe_sa_bo_swap_guard(bb_pool));
++ xe_sa_bo_swap_shadow(bb_pool);
++
+ bb = xe_bb_ccs_new(gt, batch_size, read_write);
+ if (IS_ERR(bb)) {
+ drm_err(&xe->drm, "BB allocation failed.\n");
+ err = PTR_ERR(bb);
+- goto err_ret;
++ return err;
+ }
+
+ batch_size_allocated = batch_size;
+@@ -1113,10 +1122,52 @@ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ xe_assert(xe, (batch_size_allocated == bb->len));
+ src_bo->bb_ccs[read_write] = bb;
+
++ xe_sriov_vf_ccs_rw_update_bb_addr(ctx);
++ xe_sa_bo_sync_shadow(bb->bo);
+ return 0;
++}
+
+-err_ret:
+- return err;
++/**
++ * xe_migrate_ccs_rw_copy_clear() - Clear the CCS read/write batch buffer
++ * content.
++ * @src_bo: The buffer object @src is currently bound to.
++ * @read_write : Creates BB commands for CCS read/write.
++ *
++ * Directly clearing the BB lacks atomicity and can lead to undefined
++ * behavior if the vCPU is halted mid-operation during the clearing
++ * process. To avoid this issue, we use a shadow buffer object approach.
++ *
++ * First swap the SA BO address with the shadow BO, perform the clearing
++ * operation on the BB, update the shadow BO in the ring buffer, then
++ * sync the shadow and the actual buffer to maintain consistency.
++ *
++ * Returns: None.
++ */
++void xe_migrate_ccs_rw_copy_clear(struct xe_bo *src_bo,
++ enum xe_sriov_vf_ccs_rw_ctxs read_write)
++{
++ struct xe_bb *bb = src_bo->bb_ccs[read_write];
++ struct xe_device *xe = xe_bo_device(src_bo);
++ struct xe_sriov_vf_ccs_ctx *ctx;
++ struct xe_sa_manager *bb_pool;
++ u32 *cs;
++
++ xe_assert(xe, IS_SRIOV_VF(xe));
++
++ ctx = &xe->sriov.vf.ccs.contexts[read_write];
++ bb_pool = ctx->mem.ccs_bb_pool;
++
++ guard(mutex) (xe_sa_bo_swap_guard(bb_pool));
++ xe_sa_bo_swap_shadow(bb_pool);
++
++ cs = xe_sa_bo_cpu_addr(bb->bo);
++ memset(cs, MI_NOOP, bb->len * sizeof(u32));
++ xe_sriov_vf_ccs_rw_update_bb_addr(ctx);
++
++ xe_sa_bo_sync_shadow(bb->bo);
++
++ xe_bb_free(bb, NULL);
++ src_bo->bb_ccs[read_write] = NULL;
+ }
+
+ /**
+diff --git a/drivers/gpu/drm/xe/xe_migrate.h b/drivers/gpu/drm/xe/xe_migrate.h
+index bc55f650204b83..438c3bb66d9b24 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.h
++++ b/drivers/gpu/drm/xe/xe_migrate.h
+@@ -131,6 +131,9 @@ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ struct xe_bo *src_bo,
+ enum xe_sriov_vf_ccs_rw_ctxs read_write);
+
++void xe_migrate_ccs_rw_copy_clear(struct xe_bo *src_bo,
++ enum xe_sriov_vf_ccs_rw_ctxs read_write);
++
+ struct xe_lrc *xe_migrate_lrc(struct xe_migrate *migrate);
+ struct xe_exec_queue *xe_migrate_exec_queue(struct xe_migrate *migrate);
+ int xe_migrate_access_memory(struct xe_migrate *m, struct xe_bo *bo,
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+index 1a7d767632dadf..d62156195f321b 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+@@ -148,7 +148,8 @@ static int alloc_bb_pool(struct xe_tile *tile, struct xe_sriov_vf_ccs_ctx *ctx)
+ xe_sriov_info(xe, "Allocating %s CCS BB pool size = %lldMB\n",
+ ctx->ctx_id ? "Restore" : "Save", bb_pool_size / SZ_1M);
+
+- sa_manager = xe_sa_bo_manager_init(tile, bb_pool_size, SZ_16);
++ sa_manager = __xe_sa_bo_manager_init(tile, bb_pool_size, SZ_4K, SZ_16,
++ XE_SA_BO_MANAGER_FLAG_SHADOW);
+
+ if (IS_ERR(sa_manager)) {
+ xe_sriov_err(xe, "Suballocator init failed with error: %pe\n",
+@@ -314,6 +315,18 @@ int xe_sriov_vf_ccs_init(struct xe_device *xe)
+ return err;
+ }
+
++#define XE_SRIOV_VF_CCS_RW_BB_ADDR_OFFSET (2 * sizeof(u32))
++void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx)
++{
++ u64 addr = xe_sa_manager_gpu_addr(ctx->mem.ccs_bb_pool);
++ struct xe_lrc *lrc = xe_exec_queue_lrc(ctx->mig_q);
++ struct xe_device *xe = gt_to_xe(ctx->mig_q->gt);
++
++ xe_device_wmb(xe);
++ xe_map_wr(xe, &lrc->bo->vmap, XE_SRIOV_VF_CCS_RW_BB_ADDR_OFFSET, u32, addr);
++ xe_device_wmb(xe);
++}
++
+ /**
+ * xe_sriov_vf_ccs_attach_bo - Insert CCS read write commands in the BO.
+ * @bo: the &buffer object to which batch buffer commands will be added.
+@@ -374,9 +387,7 @@ int xe_sriov_vf_ccs_detach_bo(struct xe_bo *bo)
+ if (!bb)
+ continue;
+
+- memset(bb->cs, MI_NOOP, bb->len * sizeof(u32));
+- xe_bb_free(bb, NULL);
+- bo->bb_ccs[ctx_id] = NULL;
++ xe_migrate_ccs_rw_copy_clear(bo, ctx_id);
+ }
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+index 0745c0ff022828..a9c6512f87034f 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+@@ -19,6 +19,7 @@ int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo);
+ int xe_sriov_vf_ccs_detach_bo(struct xe_bo *bo);
+ int xe_sriov_vf_ccs_register_context(struct xe_device *xe);
+ void xe_sriov_vf_ccs_print(struct xe_device *xe, struct drm_printer *p);
++void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx);
+
+ static inline bool xe_sriov_vf_ccs_ready(struct xe_device *xe)
+ {
+--
+2.53.0
+
--- /dev/null
+From 32df72a99bfd5c3da5abda26c1f6ce96ec99147d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 15:17:59 -0700
+Subject: drm/xe/wopcm: fix WOPCM size for LNL+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit ad87e2476b3b246580f407afc8ffa91d621bc849 ]
+
+Starting on LNL the WOPCM size is 8MB instead of 4, so we need to avoid
+using the [0, 8MB) range of the GGTT as that can be unaccessible from
+the microcontrollers.
+
+Note that the proper long-term fix here is to read the WOPCM size from
+the HW, but that is a more serious rework that would be difficult to
+backport, so we can do that as a follow-up.
+
+Fixes: 9c57bc08652a ("drm/xe/lnl: Drop force_probe requirement")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Shuicheng Lin <shuicheng.lin@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260713221758.3285744-2-daniele.ceraolospurio@intel.com
+(cherry picked from commit 3033b0b24ed0e2f5e56bdd4d9c183417c365a45b)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wopcm.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c
+index ada0d0aa6b7494..2fd2a82be89f87 100644
+--- a/drivers/gpu/drm/xe/xe_wopcm.c
++++ b/drivers/gpu/drm/xe/xe_wopcm.c
+@@ -49,9 +49,9 @@
+ */
+
+ /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
+-/* FIXME: Larger size require for 2 tile PVC, do a proper probe sooner or later */
++/* FIXME: Larger size require for some platforms, do a proper probe sooner or later */
+ #define DGFX_WOPCM_SIZE SZ_4M
+-/* FIXME: Larger size require for MTL, do a proper probe sooner or later */
++#define LNL_WOPCM_SIZE SZ_8M
+ #define MTL_WOPCM_SIZE SZ_4M
+ #define WOPCM_SIZE SZ_2M
+
+@@ -181,9 +181,14 @@ static int __wopcm_init_regs(struct xe_device *xe, struct xe_gt *gt,
+
+ u32 xe_wopcm_size(struct xe_device *xe)
+ {
+- return IS_DGFX(xe) ? DGFX_WOPCM_SIZE :
+- xe->info.platform == XE_METEORLAKE ? MTL_WOPCM_SIZE :
+- WOPCM_SIZE;
++ if (xe->info.platform >= XE_LUNARLAKE)
++ return LNL_WOPCM_SIZE;
++ else if (IS_DGFX(xe))
++ return DGFX_WOPCM_SIZE;
++ else if (xe->info.platform == XE_METEORLAKE)
++ return MTL_WOPCM_SIZE;
++ else
++ return WOPCM_SIZE;
+ }
+
+ /**
+--
+2.53.0
+
--- /dev/null
+From fe1596ba834ff982f0ac18326b7fdd2997d6a2f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 10:38:39 +0000
+Subject: firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset
+ calculation
+
+From: Sebastian Ene <sebastianene@google.com>
+
+[ Upstream commit b4d961351aa84fdf0148783fb1f3a1391b8a0adb ]
+
+Use the descriptor's `ep_mem_offset` to calculate the start of the endpoint
+memory access array and to comply with the FF-A spec instead of defaulting
+to `sizeof(struct ffa_mem_region)`.
+This requires moving `ffa_mem_region_additional_setup()` earlier in the setup
+flow.
+Also, add sanity checks to ensure the calculated descriptor offsets do not
+exceed `max_fragsize`.
+
+Fixes: 113580530ee7 ("firmware: arm_ffa: Update memory descriptor to support v1.1 format")
+Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Sebastian Ene <sebastianene@google.com>
+Link: https://patch.msgid.link/20260702103848.1647249-3-sebastianene@google.com
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 20 +++++++++++++++-----
+ include/linux/arm_ffa.h | 2 +-
+ 2 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 6f576c39e4832a..1d0bd586da4d6f 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -707,19 +707,30 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ struct ffa_composite_mem_region *composite;
+ struct ffa_mem_region_addr_range *constituents;
+ struct ffa_mem_region_attributes *ep_mem_access;
+- u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg);
++ u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg), ep_offset;
++ u32 emad_end, emad_size = ffa_emad_size_get(drv_info->version);
+
+ mem_region->tag = args->tag;
+ mem_region->flags = args->flags;
+ mem_region->sender_id = drv_info->vm_id;
+ mem_region->attributes = ffa_memory_attributes_get(func_id);
++
++ ffa_mem_region_additional_setup(drv_info->version, mem_region);
+ composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
+ drv_info->version);
++ if (composite_offset + sizeof(*composite) > max_fragsize)
++ return -ENXIO;
+
+ for (idx = 0; idx < args->nattrs; idx++) {
+- ep_mem_access = buffer +
+- ffa_mem_desc_offset(buffer, idx, drv_info->version);
+- memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
++ ep_offset = ffa_mem_desc_offset(buffer, idx, drv_info->version);
++ if (check_add_overflow(ep_offset, emad_size, &emad_end))
++ return -ENXIO;
++
++ if (emad_end > max_fragsize)
++ return -ENXIO;
++
++ ep_mem_access = buffer + ep_offset;
++ memset(ep_mem_access, 0, emad_size);
+ ep_mem_access->receiver = args->attrs[idx].receiver;
+ ep_mem_access->attrs = args->attrs[idx].attrs;
+ ep_mem_access->composite_off = composite_offset;
+@@ -729,7 +740,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ }
+ mem_region->handle = 0;
+ mem_region->ep_count = args->nattrs;
+- ffa_mem_region_additional_setup(drv_info->version, mem_region);
+
+ composite = buffer + composite_offset;
+ composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
+diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
+index 81e603839c4a51..62d67dae8b7033 100644
+--- a/include/linux/arm_ffa.h
++++ b/include/linux/arm_ffa.h
+@@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
+ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
+ offset += offsetof(struct ffa_mem_region, ep_mem_offset);
+ else
+- offset += sizeof(struct ffa_mem_region);
++ offset += buf->ep_mem_offset;
+
+ return offset;
+ }
+--
+2.53.0
+
--- /dev/null
+From 83644e951404bdf4b05c075b5c39100cc48aed32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index c76eabb8436a85..feded15bb5e921 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1133,7 +1133,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From cbb38410e93528c776d9a2f9ae3bfc3c5ba84af8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 10:38:38 +0000
+Subject: firmware: arm_ffa: Fix out-of-bound writes in
+ ffa_setup_and_transmit()
+
+From: Mostafa Saleh <smostafa@google.com>
+
+[ Upstream commit 3383ffb7ef937317361713ffcc21921a7848511a ]
+
+Sashiko (locally) reports multiple out-of-bound issues in
+ffa_setup_and_transmit:
+1) Writing ep_mem_access->reserved can write out of bounds for FFA
+ versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case
+ while reserved has an offset of 24.
+ Instead of zeroing fields, memset the struct to zero first based on
+ the FFA version.
+
+2) Make sure there is enough size to write constituents.
+
+While at it, convert the only sizeof() in the driver that uses a
+type instead of variable.
+
+Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
+Fixes: 111a833dc5cb ("firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors")
+Signed-off-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Sebastian Ene <sebastianene@google.com>
+Link: https://patch.msgid.link/20260702103848.1647249-2-sebastianene@google.com
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index feded15bb5e921..6f576c39e4832a 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -719,11 +719,10 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ for (idx = 0; idx < args->nattrs; idx++) {
+ ep_mem_access = buffer +
+ ffa_mem_desc_offset(buffer, idx, drv_info->version);
++ memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
+ ep_mem_access->receiver = args->attrs[idx].receiver;
+ ep_mem_access->attrs = args->attrs[idx].attrs;
+ ep_mem_access->composite_off = composite_offset;
+- ep_mem_access->flag = 0;
+- ep_mem_access->reserved = 0;
+ ffa_emad_impdef_value_init(drv_info->version,
+ ep_mem_access->impdef_val,
+ args->attrs[idx].impdef_val);
+@@ -763,7 +762,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ constituents = buffer;
+ }
+
+- if ((void *)constituents - buffer > max_fragsize) {
++ if ((void *)constituents + sizeof(*constituents) - buffer > max_fragsize) {
+ pr_err("Memory Region Fragment > Tx Buffer size\n");
+ return -EFAULT;
+ }
+@@ -772,7 +771,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE;
+ constituents->reserved = 0;
+ constituents++;
+- frag_len += sizeof(struct ffa_mem_region_addr_range);
++ frag_len += sizeof(*constituents);
+ } while ((args->sg = sg_next(args->sg)));
+
+ return ffa_transmit_fragment(func_id, addr, buf_sz, frag_len,
+--
+2.53.0
+
--- /dev/null
+From 227331a2b0bd055779f0175d8d7e3a7a664a1996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 21:54:06 +0000
+Subject: firmware: arm_ffa: Respect firmware advertised RX/TX buffer size
+ limits
+
+From: Seth Forshee <sforshee@nvidia.com>
+
+[ Upstream commit 53716a4d745f1dac7aff33f3d1494b701eb2f888 ]
+
+FFA_FEATURES reports the minimum size and alignment boundary required
+for RXTX_MAP. In FF-A v1.2 and later it can also report a maximum buffer
+size, with zero meaning that no maximum is enforced.
+
+The driver only used the minimum value and then rounded it up to PAGE_SIZE
+before invoking RXTX_MAP after commit 83210251fd70 ("firmware: arm_ffa:
+Use the correct buffer size during RXTX_MAP"). On systems where PAGE_SIZE
+is larger than the advertised minimum, this can exceed a non-zero maximum
+reported by firmware. Older implementations do not advertise a maximum and
+may also reject the rounded-up size.
+
+Decode the maximum size and clamp the page-aligned minimum to it when it
+is present. If no maximum is advertised and RXTX_MAP rejects the rounded
+size with INVALID_PARAMETERS, retry with the advertised minimum size.
+Record drv_info->rxtx_bufsz only after RXTX_MAP succeeds so it reflects
+the size registered with firmware.
+
+While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
+consistency.
+
+Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
+Suggested-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Seth Forshee <sforshee@nvidia.com>
+Link: https://patch.msgid.link/20260602-b4-ffa-rxtx-map-fixes-v2-1-7cb06508da84@nvidia.com
+(sudeep.holla: Minor rewording subject and commit message)
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 3fbc75caf0c506..c76eabb8436a85 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -32,6 +32,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
++#include <linux/minmax.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/mutex.h>
+@@ -55,7 +56,9 @@
+ (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
+
+ #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
+-#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
++#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
++#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
++#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
+
+ #define FFA_MAX_NOTIFICATIONS 64
+
+@@ -2088,7 +2091,7 @@ static int __init ffa_init(void)
+ {
+ int ret;
+ u32 buf_sz;
+- size_t rxtx_bufsz = SZ_4K;
++ size_t rxtx_min_bufsz = SZ_4K, rxtx_max_bufsz = 0, rxtx_bufsz;
+
+ ret = ffa_transport_init(&invoke_ffa_fn);
+ if (ret)
+@@ -2111,15 +2114,18 @@ static int __init ffa_init(void)
+ ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
+ if (!ret) {
+ if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
+- rxtx_bufsz = SZ_64K;
++ rxtx_min_bufsz = SZ_64K;
+ else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
+- rxtx_bufsz = SZ_16K;
++ rxtx_min_bufsz = SZ_16K;
+ else
+- rxtx_bufsz = SZ_4K;
++ rxtx_min_bufsz = SZ_4K;
++
++ rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
++ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
++ rxtx_max_bufsz = rxtx_min_bufsz;
+ }
+
+- rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
+- drv_info->rxtx_bufsz = rxtx_bufsz;
++ rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
+ drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
+ if (!drv_info->rx_buffer) {
+ ret = -ENOMEM;
+@@ -2135,10 +2141,17 @@ static int __init ffa_init(void)
+ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+ virt_to_phys(drv_info->rx_buffer),
+ rxtx_bufsz / FFA_PAGE_SIZE);
++ if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
++ rxtx_bufsz = rxtx_min_bufsz;
++ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
++ virt_to_phys(drv_info->rx_buffer),
++ rxtx_bufsz / FFA_PAGE_SIZE);
++ }
+ if (ret) {
+ pr_err("failed to register FFA RxTx buffers\n");
+ goto free_pages;
+ }
++ drv_info->rxtx_bufsz = rxtx_bufsz;
+
+ mutex_init(&drv_info->rx_lock);
+ mutex_init(&drv_info->tx_lock);
+--
+2.53.0
+
--- /dev/null
+From fbfe39523ff2e4a23e0b98818301b3a0bc8bad8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 2047edbdc5f6b1..9bf7f43ab868c8 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -600,9 +600,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f15286f9c2d54e719ae8351dd6dc3cd00f78a5d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 8f26bfb695861f..5150cd53d4435a 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -2031,6 +2031,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ change_mad_state(mad_send_wr, IB_MAD_STATE_EARLY_RESP);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -2050,6 +2068,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From 89ec4c759a1ec41bc62cf4c40657173eb34e0219 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 1308213791f19d..2dc87e2156d373 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1385,7 +1385,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From 83fab616aa69e03fa73b34c2b31e7c8ab56a2e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 22:49:55 +0800
+Subject: ksmbd: pin conn during async oplock break notification
+
+From: Qihang <q.h.hack.winter@gmail.com>
+
+[ Upstream commit aa5d8f3f96aa11a4a54ce993c11ce8af11c546f9 ]
+
+smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn
+pointer in an async ksmbd_work and then queue that work on ksmbd-io. The
+work only increments conn->r_count, which prevents teardown from passing
+the pending-request wait after the increment, but it does not pin the
+struct ksmbd_conn object.
+
+If connection teardown races with an oplock break notification, the last
+conn reference can be dropped before the queued worker finishes. The
+worker then uses the freed conn in ksmbd_conn_write() and
+ksmbd_conn_r_count_dec().
+
+Take a real conn reference when publishing the conn pointer to the async
+work item, and drop it after the notification work has decremented
+r_count. Apply the same lifetime rule to lease break notification, which
+uses the same work->conn pattern.
+
+Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification")
+Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index a019c4496ae433..ff0dbf3f8cbf49 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -705,6 +705,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -740,7 +741,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
+ br_info->open_trunc = opinfo->open_trunc;
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+@@ -814,6 +815,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -853,7 +855,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
+ memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+--
+2.53.0
+
--- /dev/null
+From 8781db4f567c616ea34bb0721d63d7f46431d296 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
+index 67a2d7a793f6ed..b11d854d3fcfba 100644
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -400,6 +400,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From 4647fcd37d6cd8027f92793114ee5ad39dbcf447 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 1c70cb26e7ba17..f7f60025d042a4 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2123,6 +2123,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From e756d1b2e9182ec68dcb72dde608d71500e3403f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 20:10:42 +0800
+Subject: mtd: fix double free and WARN_ON in add_mtd_device() error paths
+
+From: Xue Lei <Xue.Lei@windriver.com>
+
+[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]
+
+When device_register() or mtd_nvmem_add() fails inside
+add_mtd_device() for a partition, the error handling triggers
+mtd_release() via put_device() or device_unregister(). mtd_release()
+calls release_mtd_partition() which frees the mtd_info structure.
+However, callers such as mtd_add_partition() and add_mtd_partitions()
+also call free_partition() in their error paths, resulting in a double
+free.
+
+Additionally, release_mtd_partition() hits WARN_ON(!list_empty(
+&mtd->part.node)) because the partition node is still linked in the
+parent's partitions list when the release callback fires from the
+add_mtd_device() error path.
+
+Fix this by overriding dev->type and dev->release before put_device()
+in the error paths, so that device_release() invokes a no-op function
+instead of mtd_release(). For the mtd_nvmem_add() failure case,
+device_unregister() is replaced with device_del() to separate the
+device removal from the final kobject reference drop, allowing the
+override to take effect before put_device() is called.
+
+The callers' error paths (list_del + free_partition) remain the sole
+owners of mtd_info lifetime on add_mtd_device() failure, which is the
+expected contract.
+
+The normal partition teardown path is not affected: del_mtd_device()
+goes through kref_put() -> mtd_device_release() -> device_unregister()
+with dev->type still set to &mtd_devtype, so mtd_release() ->
+release_mtd_partition() continues to work correctly for the regular
+removal case.
+
+Reported-by: syzbot+e9c76b56dc05023b8117@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e9c76b56dc05023b8117
+Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
+Signed-off-by: Xue Lei <Xue.Lei@windriver.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 64808493b4f5ea..42cabd3c1efad1 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -104,6 +104,15 @@ static void mtd_release(struct device *dev)
+ device_destroy(&mtd_class, index + 1);
+ }
+
++/*
++ * No-op device release used in add_mtd_device() error paths.
++ * Prevents mtd_release() from being called via device_release(),
++ * which would free the mtd_info that the caller still manages.
++ */
++static void mtd_dev_release_nop(struct device *dev)
++{
++}
++
+ static void mtd_device_release(struct kref *kref)
+ {
+ struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+@@ -798,10 +807,8 @@ int add_mtd_device(struct mtd_info *mtd)
+ mtd_check_of_node(mtd);
+ of_node_get(mtd_get_of_node(mtd));
+ error = device_register(&mtd->dev);
+- if (error) {
+- put_device(&mtd->dev);
++ if (error)
+ goto fail_added;
+- }
+
+ /* Add the nvmem provider */
+ error = mtd_nvmem_add(mtd);
+@@ -839,8 +846,16 @@ int add_mtd_device(struct mtd_info *mtd)
+ return 0;
+
+ fail_nvmem_add:
+- device_unregister(&mtd->dev);
++ device_del(&mtd->dev);
+ fail_added:
++ /*
++ * Clear type and set nop release to prevent mtd_release() ->
++ * release_mtd_partition() -> free_partition() from freeing mtd.
++ * The caller handles cleanup on failure.
++ */
++ mtd->dev.type = NULL;
++ mtd->dev.release = mtd_dev_release_nop;
++ put_device(&mtd->dev);
+ of_node_put(mtd_get_of_node(mtd));
+ fail_devname:
+ idr_remove(&mtd_idr, i);
+--
+2.53.0
+
--- /dev/null
+From dc5012153ee7f7c26f2965c9ade4c5143a233feb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index d8f2e5be2d315e..42ff7deace80c5 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From 83605e7c140865e08b3862241cde29e0f36b2269 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/ecc-mtk.c b/drivers/mtd/nand/ecc-mtk.c
+index c75bb8b80cc1e1..96703f0a418ea2 100644
+--- a/drivers/mtd/nand/ecc-mtk.c
++++ b/drivers/mtd/nand/ecc-mtk.c
+@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 3ae064709b65b1e8c74e4524ff8674fb54aff1e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2026 20:18:23 +0000
+Subject: net: dropreason: add SKB_DROP_REASON_RECURSION_LIMIT
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d15d3de94a4766fb43d7fe7a72ed0479fb268131 ]
+
+ip[6]tunnel_xmit() can drop packets if a too deep recursion level
+is detected.
+
+Add SKB_DROP_REASON_RECURSION_LIMIT drop reason.
+
+We will use this reason later in __dev_queue_xmit().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Joe Damato <joe@dama.to>
+Link: https://patch.msgid.link/20260312201824.203093-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/dropreason-core.h | 3 +++
+ include/net/ip6_tunnel.h | 2 +-
+ net/ipv4/ip_tunnel_core.c | 2 +-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
+index 58d91ccc56e0b5..de74e537b4ede4 100644
+--- a/include/net/dropreason-core.h
++++ b/include/net/dropreason-core.h
+@@ -129,6 +129,7 @@
+ FN(DUALPI2_STEP_DROP) \
+ FN(PSP_INPUT) \
+ FN(PSP_OUTPUT) \
++ FN(RECURSION_LIMIT) \
+ FNe(MAX)
+
+ /**
+@@ -616,6 +617,8 @@ enum skb_drop_reason {
+ SKB_DROP_REASON_PSP_INPUT,
+ /** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
+ SKB_DROP_REASON_PSP_OUTPUT,
++ /** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */
++ SKB_DROP_REASON_RECURSION_LIMIT,
+ /**
+ * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
+ * shouldn't be used as a real 'reason' - only for tracing code gen
+diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
+index 359b595f1df936..b99805ee2fd14b 100644
+--- a/include/net/ip6_tunnel.h
++++ b/include/net/ip6_tunnel.h
+@@ -162,7 +162,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
+ dev->name);
+ DEV_STATS_INC(dev, tx_errors);
+ }
+- kfree_skb(skb);
++ kfree_skb_reason(skb, SKB_DROP_REASON_RECURSION_LIMIT);
+ return;
+ }
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 4b5fd4b13722ca..fc993c78cbcc5e 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -65,7 +65,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
+ DEV_STATS_INC(dev, tx_errors);
+ }
+ ip_rt_put(rt);
+- kfree_skb(skb);
++ kfree_skb_reason(skb, SKB_DROP_REASON_RECURSION_LIMIT);
+ return;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From bd3b68e5cd54d8b476487ae0860661f1f834187b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index c66b90c912e78e..bd0405373c5e97 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2089,6 +2089,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2138,6 +2140,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 157e30928af00636bab2ea49e0ab9ad66d28d7cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2026 20:18:24 +0000
+Subject: net: plumb drop reasons to __dev_queue_xmit()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 045f977dd4ebdd3ad8e96cf684917adfc5805adb ]
+
+Add drop reasons to __dev_queue_xmit():
+
+- SKB_DROP_REASON_DEV_READY : device is not UP.
+
+- SKB_DROP_REASON_RECURSION_LIMIT : recursion limit on virtual device is hit.
+
+Also add an unlikely() for the SKB_DROP_REASON_DEV_READY case,
+and reduce indentation level.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Joe Damato <joe@dama.to>
+Link: https://patch.msgid.link/20260312201824.203093-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 83 ++++++++++++++++++++++++++------------------------
+ 1 file changed, 43 insertions(+), 40 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 8dee703a0916ed..246d654551ae56 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4702,9 +4702,10 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
+ {
+ struct net_device *dev = skb->dev;
+ struct netdev_queue *txq = NULL;
+- struct Qdisc *q;
+- int rc = -ENOMEM;
++ enum skb_drop_reason reason;
++ int cpu, rc = -ENOMEM;
+ bool again = false;
++ struct Qdisc *q;
+
+ skb_reset_mac_header(skb);
+ skb_assert_len(skb);
+@@ -4773,59 +4774,61 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
+ * Check this and shot the lock. It is not prone from deadlocks.
+ *Either shot noqueue qdisc, it is even simpler 8)
+ */
+- if (dev->flags & IFF_UP) {
+- int cpu = smp_processor_id(); /* ok because BHs are off */
++ if (unlikely(!(dev->flags & IFF_UP))) {
++ reason = SKB_DROP_REASON_DEV_READY;
++ goto drop;
++ }
+
+- if (!netif_tx_owned(txq, cpu)) {
+- bool is_list = false;
++ cpu = smp_processor_id(); /* ok because BHs are off */
+
+- if (dev_xmit_recursion())
+- goto recursion_alert;
++ if (likely(!netif_tx_owned(txq, cpu))) {
++ bool is_list = false;
+
+- skb = validate_xmit_skb(skb, dev, &again);
+- if (!skb)
+- goto out;
++ if (dev_xmit_recursion())
++ goto recursion_alert;
+
+- HARD_TX_LOCK(dev, txq, cpu);
++ skb = validate_xmit_skb(skb, dev, &again);
++ if (!skb)
++ goto out;
+
+- if (!netif_xmit_stopped(txq)) {
+- is_list = !!skb->next;
++ HARD_TX_LOCK(dev, txq, cpu);
+
+- dev_xmit_recursion_inc();
+- skb = dev_hard_start_xmit(skb, dev, txq, &rc);
+- dev_xmit_recursion_dec();
++ if (!netif_xmit_stopped(txq)) {
++ is_list = !!skb->next;
+
+- /* GSO segments a single SKB into
+- * a list of frames. TCP expects error
+- * to mean none of the data was sent.
+- */
+- if (is_list)
+- rc = NETDEV_TX_OK;
+- }
+- HARD_TX_UNLOCK(dev, txq);
+- if (!skb) /* xmit completed */
+- goto out;
++ dev_xmit_recursion_inc();
++ skb = dev_hard_start_xmit(skb, dev, txq, &rc);
++ dev_xmit_recursion_dec();
+
+- net_crit_ratelimited("Virtual device %s asks to queue packet!\n",
+- dev->name);
+- /* NETDEV_TX_BUSY or queue was stopped */
+- if (!is_list)
+- rc = -ENETDOWN;
+- } else {
+- /* Recursion is detected! It is possible,
+- * unfortunately
++ /* GSO segments a single SKB into a list of frames.
++ * TCP expects error to mean none of the data was sent.
+ */
+-recursion_alert:
+- net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n",
+- dev->name);
+- rc = -ENETDOWN;
++ if (is_list)
++ rc = NETDEV_TX_OK;
+ }
++ HARD_TX_UNLOCK(dev, txq);
++ if (!skb) /* xmit completed */
++ goto out;
++
++ net_crit_ratelimited("Virtual device %s asks to queue packet!\n",
++ dev->name);
++ /* NETDEV_TX_BUSY or queue was stopped */
++ if (!is_list)
++ rc = -ENETDOWN;
++ } else {
++ /* Recursion is detected! It is possible unfortunately. */
++recursion_alert:
++ net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n",
++ dev->name);
++ rc = -ENETDOWN;
+ }
+
++ reason = SKB_DROP_REASON_RECURSION_LIMIT;
++drop:
+ rcu_read_unlock_bh();
+
+ dev_core_stats_tx_dropped_inc(dev);
+- kfree_skb_list(skb);
++ kfree_skb_list_reason(skb, reason);
+ return rc;
+ out:
+ rcu_read_unlock_bh();
+--
+2.53.0
+
--- /dev/null
+From 015647c2c1d27ab2203cf99b27f3f3d619b18890 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 876b30c5709e1f..b14807761d829e 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -342,14 +342,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 8964512141b9e27fa0f37dd7922121c53b0f6440 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 21:33:09 -0700
+Subject: powerpc/85xx: Add fsl,ifc to common device ids
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 25957f7c3dac3265332d766b71233e3622f17e14 ]
+
+Add fsl,ifc to mpc85xx_common_ids so that of_platform_bus_probe
+creates a platform device for the IFC node even without 'simple-bus'
+in its compatible property. On P1010 and similar platforms the IFC
+node is a direct child of the root, so it must be explicitly matched
+to be populated.
+
+Fixes: 0bf51cc9e9e5 ("powerpc: dts: mpc85xx: remove "simple-bus" compatible from ifc node")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260604043309.91280-1-rosenp@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/85xx/common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
+index 757811155587db..c11deb2f50ed45 100644
+--- a/arch/powerpc/platforms/85xx/common.c
++++ b/arch/powerpc/platforms/85xx/common.c
+@@ -42,6 +42,8 @@ static const struct of_device_id mpc85xx_common_ids[] __initconst = {
+ { .compatible = "fsl,qoriq-pcie-v2.3", },
+ { .compatible = "fsl,qoriq-pcie-v2.2", },
+ { .compatible = "fsl,fman", },
++ /* IFC NAND and NOR controllers */
++ { .compatible = "fsl,ifc", },
+ {},
+ };
+
+--
+2.53.0
+
--- /dev/null
+From da45c1a00df585ac0b65434b96e0187dd34ce691 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2026 15:16:37 +0200
+Subject: powerpc/time: Prepare to stop elapsing in dynticks-idle
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit c8ba971cf8567d49eb5f43ee90c4e50424331c18 ]
+
+Currently the tick subsystem stores the idle cputime accounting in
+private fields, allowing cohabitation with architecture idle vtime
+accounting. The former is fetched on online CPUs, the latter on offline
+CPUs.
+
+For consolidation purpose, architecture vtime accounting will continue
+to account the cputime but will make a break when the idle tick is
+stopped. The dyntick cputime accounting will then be relayed by the tick
+subsystem so that the idle cputime is still seen advancing coherently
+even when the tick isn't there to flush the idle vtime.
+
+Prepare for that and introduce three new APIs which will be used in
+subsequent patches:
+
+ - vtime_dynticks_start() is deemed to be called when idle enters in
+ dyntick mode. The idle cputime that elapsed so far is accumulated.
+
+ - vtime_dynticks_stop() is deemed to be called when idle exits from
+ dyntick mode. The vtime entry clocks are fast-forward to current time
+ so that idle accounting restarts elapsing from now.
+
+ - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
+ fast-forward the clock to current time so that the IRQ time is still
+ accounted by vtime while nohz cputime is paused.
+
+Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
+accounting twice the idle cputime, along with nohz accounting.
+
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Link: https://patch.msgid.link/20260508131647.43868-6-frederic@kernel.org
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
+ include/linux/vtime.h | 6 ++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index b4472288e0d434..3460d1a5a97c2a 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
+ acct->starttime = acct0->starttime;
+ }
+ }
++
++#ifdef CONFIG_NO_HZ_COMMON
++/**
++ * vtime_reset - Fast forward vtime entry clocks
++ *
++ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
++ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
++ */
++void vtime_reset(void)
++{
++ struct cpu_accounting_data *acct = get_accounting(current);
++
++ acct->starttime = mftb();
++#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
++ acct->startspurr = read_spurr(acct->starttime);
++#endif
++}
++
++/**
++ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
++ *
++ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
++ * is accumulated and the tick subsystem takes over the idle cputime accounting.
++ */
++void vtime_dyntick_start(void)
++{
++ vtime_account_idle(current);
++}
++
++/**
++ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
++ *
++ * Called when idle exits from dyntick mode. The vtime entry clocks are
++ * fast-forward to current time so that idle accounting restarts elapsing from
++ * now.
++ */
++void vtime_dyntick_stop(void)
++{
++ vtime_reset();
++}
++#endif /* CONFIG_NO_HZ_COMMON */
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/include/linux/vtime.h b/include/linux/vtime.h
+index 29dd5b91dd7d66..3fc04b849e4e30 100644
+--- a/include/linux/vtime.h
++++ b/include/linux/vtime.h
+@@ -32,11 +32,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
+ extern void vtime_account_softirq(struct task_struct *tsk);
+ extern void vtime_account_hardirq(struct task_struct *tsk);
+ extern void vtime_flush(struct task_struct *tsk);
++extern void vtime_reset(void);
++extern void vtime_dyntick_start(void);
++extern void vtime_dyntick_stop(void);
+ #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+ static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
+ static inline void vtime_account_softirq(struct task_struct *tsk) { }
+ static inline void vtime_account_hardirq(struct task_struct *tsk) { }
+ static inline void vtime_flush(struct task_struct *tsk) { }
++static inline void vtime_reset(void) { }
++static inline void vtime_dyntick_start(void) { }
++static inline void vtime_dyntick_stop(void) { }
+ #endif
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 9629649b7a75a16030b988e53789384f8c1e0f3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:13:29 +0530
+Subject: powerpc/vtime: Initialize starttime at boot for native accounting
+
+From: Shrikanth Hegde <sshegde@linux.ibm.com>
+
+[ Upstream commit c1c1ffa490fc33591e90852ed0d38804dd20bc36 ]
+
+It was observed that /proc/stat had very large value for one ore more
+CPUs. It was more visible after recent code simplifications around
+cpustats.
+
+System has 240 CPUs.
+
+cat /proc/uptime;
+194.18 46500.55
+cat /proc/stat
+cpu 5966 39 837032887 4650070 164 185 100 0 0 0
+cpu0 108 0 837030890 19109 24 4 23 0 0 0
+
+Since uptime is 194s, system time of each CPU can't be more than 19400.
+Sum of system time of all CPUs can't be more than 19400*240 4656000.
+In fact huge value is close to mftb(). Note mftb doesn't reset on powerVM
+when the LPAR restart. It only resets when whole system resets. The same
+issue exists for kexec too.
+
+This happens since starttime is not setup at init time. Once it is set
+then subsequent vtime_delta will return the right delta.
+
+Fix it by initializing the starttime during CPU initialization. This
+fixes the large times seen.
+
+cat /proc/uptime; cat /proc/stat
+15.78 3694.63
+cpu 6035 35 1347 369479 23 144 49 0 0 0
+cpu0 19 0 38 1508 0 1 14 0 0 0
+
+Now, system time is reported as expected.
+
+Fixes: cf9efce0ce31 ("powerpc: Account time using timebase rather than PURR")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Suggested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260605124329.377533-1-sshegde@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 3460d1a5a97c2a..11145c40183dd1 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -377,7 +377,6 @@ void vtime_task_switch(struct task_struct *prev)
+ }
+ }
+
+-#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_reset - Fast forward vtime entry clocks
+ *
+@@ -394,6 +393,7 @@ void vtime_reset(void)
+ #endif
+ }
+
++#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
+ *
+@@ -933,6 +933,7 @@ static void __init set_decrementer_max(void)
+ static void __init init_decrementer_clockevent(void)
+ {
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ void secondary_cpu_time_init(void)
+@@ -948,6 +949,7 @@ void secondary_cpu_time_init(void)
+ /* FIME: Should make unrelated change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 31ae6a218cd9de5471ed2f822577e6a7523964ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 507d216256c0dd..72e98286fba2fe 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -185,6 +185,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ spinlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3570,6 +3571,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Free up the resources used by a ppp channel.
+ */
+@@ -3585,9 +3598,7 @@ static void ppp_destroy_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3600,6 +3611,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(&ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_unregister(&ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 7ca90ab11374b0f1b7095a046d46f2ee6848367e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:21:05 +0300
+Subject: RDMA/cma: Fix hardware address comparison length in netevent callback
+
+From: Or Gerlitz <ogerlitz@ddn.com>
+
+[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
+
+The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
+
+This breaks IPoIB, which uses 20-byte addresses. By truncating the
+memcmp, the CMA may incorrectly assume the target address is
+unchanged and fails to abort the stalled connection.
+
+Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len
+to correctly evaluate the full address regardless of the link layer.
+
+Fixes: 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
+Signed-off-by: Or Gerlitz <ogerlitz@ddn.com>
+Link: https://patch.msgid.link/20260617-fix-cma-ipoib-v1-1-03f869344304@ddn.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index ce511800b056cf..648acc2222cf54 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5237,7 +5237,7 @@ static int cma_netevent_callback(struct notifier_block *self,
+
+ list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
+ if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
+- neigh->ha, ETH_ALEN))
++ neigh->ha, neigh->dev->addr_len))
+ continue;
+ cma_id_get(current_id);
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
+--
+2.53.0
+
--- /dev/null
+From 832adc208d9390b06d28aee20fd51c0e1f904282 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:51 +0800
+Subject: RDMA/erdma: initialize ret for empty receive WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
+
+erdma_post_recv() returns ret after walking the receive work request list.
+If the caller passes an empty list, the loop is skipped and ret is not
+assigned.
+
+Initialize ret to 0 so an empty receive work request list returns success
+instead of stack data.
+
+Fixes: 155055771704 ("RDMA/erdma: Add verbs implementation")
+Link: https://patch.msgid.link/r/20260618041752.481193-1-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_qp.c b/drivers/infiniband/hw/erdma/erdma_qp.c
+index 25f6c49aec7798..e002343832f74d 100644
+--- a/drivers/infiniband/hw/erdma/erdma_qp.c
++++ b/drivers/infiniband/hw/erdma/erdma_qp.c
+@@ -734,7 +734,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
+ const struct ib_recv_wr *wr = recv_wr;
+ struct erdma_qp *qp = to_eqp(ibqp);
+ unsigned long flags;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&qp->lock, flags);
+
+--
+2.53.0
+
--- /dev/null
+From 03c42c521f48d6ac4e3cf4a6f60f144762fe28d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 1680d0ac071ed1..ae7a3939124f23 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -842,7 +842,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From 6702cf7eb4be1928e28d5c255cd5aa4c7959491b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 5f5b79109d5471..4084168d0194fb 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2800,7 +2800,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2833,7 +2833,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From 62e789ae0408beaa2c9e76773f9d773eeda692ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:19:36 +0000
+Subject: RDMA/irdma: Prevent rereg_mr for non-mem regions
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]
+
+When a QP/CQ/SRQ is created, a two step process is used
+where the buffer is allocated in userspace and explicitly
+registered with the normal reg_mr mechanism prior to creating
+the actual QP/CQ/SRQ object.
+
+These special registrations are indicated via an ABI field
+so the driver knows that they do not have a valid mkey and
+to skip the actual CQP command submission.
+
+Since these are real MR objects from the core's perspective,
+it is possible for a user application to invoke rereg_mr on them
+and cause a real CQP op to be emitted with the zero-initialized
+mkey value of 0.
+
+Fix this by preventing rereg_mr on these special regions.
+
+Fixes: 5ac388db27c4 ("RDMA/irdma: Add support to re-register a memory region")
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 2b85e32134a5b8..c210f9a37fb97b 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -3756,6 +3756,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
+ return ERR_PTR(-EOPNOTSUPP);
+
++ if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
++ return ERR_PTR(-EINVAL);
++
+ ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
+ if (ret)
+ return ERR_PTR(ret);
+--
+2.53.0
+
--- /dev/null
+From 7573fd775228248bc7ba9361686ad978917f3bb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:40:13 +0000
+Subject: RDMA/irdma: Prevent user-triggered null deref on QP create
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit b9b0889071569d43623c260074e159cd8f26adb1 ]
+
+Previously, the user QP creation path would only attempt to
+populate iwqp->iwpbl if the user-provided req.user_wqe_bufs
+field was non-zero. The problem is that iwqp->iwpbl is
+unconditionally dereferenced later on in irdma_setup_virt_qp.
+
+While there was a check for iwqp->iwpbl != NULL, this check
+would only occur if req.user_wqe_bufs was non-zero. The end
+result is that a user could send a zero user_wqe_bufs value
+and trigger a null ptr deref.
+
+Fix this by unconditionally calling irdma_get_pbl and bailing
+if it fails, similar to the CQ and SRQ paths.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Link: https://patch.msgid.link/r/20260617164013.280790-1-jmoroni@google.com
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index dfd5f0caabb878..5f5b79109d5471 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -631,17 +631,16 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
+
+ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
+ iwqp->user_mode = 1;
+- if (req.user_wqe_bufs) {
+- spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+- iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+- &ucontext->qp_reg_mem_list);
+- spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
+
+- if (!iwqp->iwpbl) {
+- ret = -ENODATA;
+- ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
+- return ret;
+- }
++ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
++ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
++ &ucontext->qp_reg_mem_list);
++ spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
++
++ if (!iwqp->iwpbl) {
++ ret = -ENODATA;
++ ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
++ return ret;
+ }
+
+ if (!ucontext->use_raw_attrs) {
+--
+2.53.0
+
--- /dev/null
+From 984124f998cd1af91ed2dd8efc2f3d7a67e4baaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 21:44:22 +0000
+Subject: RDMA/irdma: Remove redundant legacy_mode checks
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit ed8621be482bf18dcd217aa024e95758bf9d28f2 ]
+
+The driver has the following invariants:
+
+1. legacy_mode is only allowed on GEN_1 hardware (enforced
+ in irdma_alloc_ucontext).
+
+2. GEN_1 hardware does not set IRDMA_FEATURE_CQ_RESIZE or
+ IRDMA_FEATURE_RTS_AE. These feature flags are only set
+ for GEN_2 and GEN_3 hardware.
+
+Therefore, legacy_mode is always false if IRDMA_FEATURE_CQ_RESIZE
+or IRDMA_FEATURE_RTS_AE is set, so remove the redundant checks.
+
+Link: https://patch.msgid.link/r/20260602214423.1315105-1-jmoroni@google.com
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: b9b088907156 ("RDMA/irdma: Prevent user-triggered null deref on QP create")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/uk.c | 9 +++------
+ drivers/infiniband/hw/irdma/user.h | 1 -
+ drivers/infiniband/hw/irdma/verbs.c | 7 +------
+ 3 files changed, 4 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index 4cc81d61be7fad..7aab0076196677 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -1540,15 +1540,12 @@ static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {
+ * irdma_setup_connection_wqes - setup WQEs necessary to complete
+ * connection.
+ * @qp: hw qp (user and kernel)
+- * @info: qp initialization info
+ */
+-static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
+- struct irdma_qp_uk_init_info *info)
++static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp)
+ {
+ u16 move_cnt = 1;
+
+- if (!info->legacy_mode &&
+- (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE))
++ if (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE)
+ move_cnt = 3;
+
+ qp->conn_wqes = move_cnt;
+@@ -1699,7 +1696,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
+ sq_ring_size = qp->sq_size << info->sq_shift;
+ IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
+ if (info->first_sq_wq) {
+- irdma_setup_connection_wqes(qp, info);
++ irdma_setup_connection_wqes(qp);
+ qp->swqe_polarity = 1;
+ qp->first_sq_wq = true;
+ } else {
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index aeebf768174abd..a0b409a895f0eb 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -560,7 +560,6 @@ struct irdma_qp_uk_init_info {
+ u8 sq_shift;
+ u8 rq_shift;
+ int abi_ver;
+- bool legacy_mode;
+ struct irdma_srq_uk *srq_uk;
+ };
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index c210f9a37fb97b..dfd5f0caabb878 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -632,7 +632,6 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
+ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
+ iwqp->user_mode = 1;
+ if (req.user_wqe_bufs) {
+- info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode;
+ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+ &ucontext->qp_reg_mem_list);
+@@ -2068,10 +2067,6 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
+ rdma_udata_to_drv_context(udata, struct irdma_ucontext,
+ ibucontext);
+
+- /* CQ resize not supported with legacy GEN_1 libi40iw */
+- if (ucontext->legacy_mode)
+- return -EOPNOTSUPP;
+-
+ if (ib_copy_from_udata(&req, udata,
+ min(sizeof(req), udata->inlen)))
+ return -EINVAL;
+@@ -2550,7 +2545,7 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ cqmr = &iwpbl->cq_mr;
+
+ if (rf->sc_dev.hw_attrs.uk_attrs.feature_flags &
+- IRDMA_FEATURE_CQ_RESIZE && !ucontext->legacy_mode) {
++ IRDMA_FEATURE_CQ_RESIZE) {
+ spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
+ iwpbl_shadow = irdma_get_pbl(
+ (unsigned long)req.user_shadow_area,
+--
+2.53.0
+
--- /dev/null
+From 81ff97d6f64d9410b6d08d8158c715c9e905a4c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:52 +0800
+Subject: RDMA/mana_ib: initialize err for empty send WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 155fd5ce2382b0ffbec0d7ee7b3a6818a27a5aed ]
+
+mana_ib_post_send() returns err after walking the send work request list.
+If the caller passes an empty list, the loop is skipped and err is not
+assigned.
+
+Initialize err to 0 so an empty send work request list returns success
+instead of stack data.
+
+Fixes: c8017f5b4856 ("RDMA/mana_ib: UD/GSI work requests")
+Link: https://patch.msgid.link/r/20260618041752.481193-2-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mana/wr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mana/wr.c b/drivers/infiniband/hw/mana/wr.c
+index 1813567d3b16c9..36a1d506f08f65 100644
+--- a/drivers/infiniband/hw/mana/wr.c
++++ b/drivers/infiniband/hw/mana/wr.c
+@@ -144,7 +144,7 @@ static int mana_ib_post_send_ud(struct mana_ib_qp *qp, const struct ib_ud_wr *wr
+ int mana_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+ {
+- int err;
++ int err = 0;
+ struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
+
+ for (; wr; wr = wr->next) {
+--
+2.53.0
+
--- /dev/null
+From 662549041c19585df456db3eea891d474b00ea16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index efa2f097b58289..9fbade0b85715a 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -316,6 +316,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -369,11 +370,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -391,14 +387,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -424,7 +420,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -439,11 +435,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -452,7 +445,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -464,9 +457,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -476,22 +483,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From fc29c7928cd7a5243546de723ce876bf999326db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:24 +0000
+Subject: RDMA/umem: Add pinned revocable dmabuf import interface
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c ]
+
+Added an interface for importing a pinned but revocable dmabuf.
+This interface can be used by drivers that are capable of revocation
+so that they can import dmabufs from exporters that may require it,
+such as VFIO.
+
+This interface implements a two step process, where drivers will first
+call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and
+map the dmabuf (and provide a functional move_notify/invalidate_mappings
+callback), but will return with the lock still held so that the
+driver can then populate the callback via
+ib_umem_dmabuf_set_revoke_locked() without races from concurrent
+revocations. This scheme also allows for easier integration with drivers
+that may not have actually allocated their internal MR objects at the time
+of the get_pinned_revocable* call.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-4-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 61 +++++++++++++++++++++++++++
+ include/rdma/ib_umem.h | 19 +++++++++
+ 2 files changed, 80 insertions(+)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index b239ac09ec2921..4fc73f53342b7e 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -206,6 +206,10 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+
+ if (umem_dmabuf->revoked)
+ return;
++
++ if (umem_dmabuf->pinned_revoke)
++ umem_dmabuf->pinned_revoke(umem_dmabuf->private);
++
+ ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+ if (umem_dmabuf->pinned) {
+ dma_buf_unpin(umem_dmabuf->attach);
+@@ -214,6 +218,11 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+ umem_dmabuf->revoked = 1;
+ }
+
++static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = {
++ .allow_peer2peer = true,
++ .move_notify = ib_umem_dmabuf_revoke_locked,
++};
++
+ static struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
+ struct device *dma_device,
+@@ -266,6 +275,58 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
+
++/**
++ * ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf
++ * @device: IB device.
++ * @offset: Start offset.
++ * @size: Length.
++ * @fd: dmabuf fd.
++ * @access: Access flags.
++ *
++ * Obtains a umem from a dmabuf for drivers/devices that can support revocation.
++ *
++ * Returns with dma_resv_lock held upon success. The driver must set the revoke
++ * callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked().
++ *
++ * When a revocation occurs, the revoke callback will be called. The driver must
++ * ensure that the region is no longer accessed when the callback returns. Any
++ * subsequent access attempts should also probably cause an AE for MRs.
++ *
++ * If the umem is used for an MR, the driver must ensure that the key remains in
++ * use such that it cannot be obtained by a new region until this region is
++ * fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with
++ * revoke calls, it can use dma_resv_lock.
++ *
++ * If successful, then the revoke callback may be called at any time and will
++ * also be called automatically upon ib_umem_release (serialized). The revoke
++ * callback will be called one time at most.
++ *
++ * Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure.
++ */
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ const struct dma_buf_attach_ops *ops =
++ &ib_umem_dmabuf_attach_pinned_revocable_ops;
++
++ return ib_umem_dmabuf_get_pinned_and_lock(device, device->dma_device,
++ offset, size, fd, access,
++ ops);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_revocable_and_lock);
++
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv)
++{
++ dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
++
++ umem_dmabuf->pinned_revoke = revoke;
++ umem_dmabuf->private = priv;
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_set_revoke_locked);
++
+ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ unsigned long offset,
+ size_t size, int fd,
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 5122f78467675e..90b1ea19a90a0a 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -36,6 +36,7 @@ struct ib_umem_dmabuf {
+ struct scatterlist *last_sg;
+ unsigned long first_sg_offset;
+ unsigned long last_sg_trim;
++ void (*pinned_revoke)(void *priv);
+ void *private;
+ u8 pinned : 1;
+ u8 revoked : 1;
+@@ -141,6 +142,12 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ size_t size, int fd,
+ int access);
+ struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access);
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv);
++struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+ unsigned long offset, size_t size,
+@@ -201,6 +208,18 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
++static inline struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ return ERR_PTR(-EOPNOTSUPP);
++}
++
++static inline void
++ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv) {}
++
+ static inline struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+--
+2.53.0
+
--- /dev/null
+From a5ad00dd5f1908fd1a1724c2d45c87edd5326b91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jan 2026 21:09:55 -0700
+Subject: riscv: enable kernel access to shadow stack memory via the FWFT SBI
+ call
+
+From: Deepak Gupta <debug@rivosinc.com>
+
+[ Upstream commit 41213bf2ae6c936f51a79986b37f95da9ecbb970 ]
+
+The kernel has to perform shadow stack operations on the user shadow stack.
+During signal delivery and sigreturn, the shadow stack token must be
+created and validated respectively. Thus shadow stack access for the kernel
+must be enabled.
+
+In the future, when kernel shadow stacks are enabled, they must be
+enabled as early as possible for better coverage and to prevent any
+imbalance between the regular stack and the shadow stack. After
+'relocate_enable_mmu' has completed, this is the earliest that it can
+be enabled.
+
+Reviewed-by: Zong Li <zong.li@sifive.com>
+Signed-off-by: Deepak Gupta <debug@rivosinc.com>
+Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> # QEMU, custom CVA6
+Tested-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
+Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-22-b55691eacf4f@rivosinc.com
+[pjw@kernel.org: updated to apply; cleaned up commit message]
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Stable-dep-of: 3a2694bf6ac8 ("riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/asm-offsets.c | 6 ++++++
+ arch/riscv/kernel/head.S | 27 +++++++++++++++++++++++++++
+ 2 files changed, 33 insertions(+)
+
+diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
+index 0a5e3e892c0ea0..739f6c6ed15885 100644
+--- a/arch/riscv/kernel/asm-offsets.c
++++ b/arch/riscv/kernel/asm-offsets.c
+@@ -529,4 +529,10 @@ void asm_offsets(void)
+ DEFINE(FREGS_A6, offsetof(struct __arch_ftrace_regs, a6));
+ DEFINE(FREGS_A7, offsetof(struct __arch_ftrace_regs, a7));
+ #endif
++#ifdef CONFIG_RISCV_SBI
++ DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
++ DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
++ DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
++ DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
++#endif
+ }
+diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
+index bdf3352acf4cb4..9c99c5ad6fe8a3 100644
+--- a/arch/riscv/kernel/head.S
++++ b/arch/riscv/kernel/head.S
+@@ -15,6 +15,7 @@
+ #include <asm/image.h>
+ #include <asm/scs.h>
+ #include <asm/xip_fixup.h>
++#include <asm/usercfi.h>
+ #include "efi-header.S"
+
+ __HEAD
+@@ -170,6 +171,19 @@ secondary_start_sbi:
+ call relocate_enable_mmu
+ #endif
+ call .Lsetup_trap_vector
++#if defined(CONFIG_RISCV_SBI) && defined(CONFIG_RISCV_USER_CFI)
++ li a7, SBI_EXT_FWFT
++ li a6, SBI_EXT_FWFT_SET
++ li a0, SBI_FWFT_SHADOW_STACK
++ li a1, 1 /* enable supervisor to access shadow stack access */
++ li a2, SBI_FWFT_SET_FLAG_LOCK
++ ecall
++ beqz a0, 1f
++ la a1, riscv_nousercfi
++ li a0, CMDLINE_DISABLE_RISCV_USERCFI_BCFI
++ REG_S a0, (a1)
++1:
++#endif
+ scs_load_current
+ call smp_callin
+ #endif /* CONFIG_SMP */
+@@ -330,6 +344,19 @@ SYM_CODE_START(_start_kernel)
+ la tp, init_task
+ la sp, init_thread_union + THREAD_SIZE
+ addi sp, sp, -PT_SIZE_ON_STACK
++#if defined(CONFIG_RISCV_SBI) && defined(CONFIG_RISCV_USER_CFI)
++ li a7, SBI_EXT_FWFT
++ li a6, SBI_EXT_FWFT_SET
++ li a0, SBI_FWFT_SHADOW_STACK
++ li a1, 1 /* enable supervisor to access shadow stack access */
++ li a2, SBI_FWFT_SET_FLAG_LOCK
++ ecall
++ beqz a0, 1f
++ la a1, riscv_nousercfi
++ li a0, CMDLINE_DISABLE_RISCV_USERCFI_BCFI
++ REG_S a0, (a1)
++1:
++#endif
+ scs_load_current
+
+ #ifdef CONFIG_KASAN
+--
+2.53.0
+
--- /dev/null
+From 7d1a79d11020d1ec3923d441664f06cf003490a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 18:42:40 -0600
+Subject: riscv: export kaslr offset and satp in VMCOREINFO ELF notes
+
+From: Austin Kim <austin.kim@lge.com>
+
+[ Upstream commit d8e99133eb4a8d09dcbf71f7277dc948d3413227 ]
+
+The following options are required by the kdump crash utility for RISC-V
+based vmcore file:
+
+- kaslr: If the vmcore is generated from a KASLR-enabled Linux kernel,
+ the KASLR offset is required for the crash utility to load
+ the vmcore. Without the proper kaslr option, the crash utility
+ fails to load the vmcore file.
+- satp: The exact root page table address helps determine the correct base
+ PGD address.
+
+With this patch, RISC-V VMCOREINFO ELF notes now include both kaslr
+and satp information.
+
+Signed-off-by: Austin Kim <austin.kim@lge.com>
+Link: https://patch.msgid.link/aYwKUE3ZzN7/ZY/A@adminpc-PowerEdge-R7525
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Stable-dep-of: 3a2694bf6ac8 ("riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/vmcore_info.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/riscv/kernel/vmcore_info.c b/arch/riscv/kernel/vmcore_info.c
+index d5e448aa90e746..682ba423cf203d 100644
+--- a/arch/riscv/kernel/vmcore_info.c
++++ b/arch/riscv/kernel/vmcore_info.c
+@@ -3,6 +3,11 @@
+ #include <linux/vmcore_info.h>
+ #include <linux/pagemap.h>
+
++static inline u64 get_satp_value(void)
++{
++ return csr_read(CSR_SATP);
++}
++
+ void arch_crash_save_vmcoreinfo(void)
+ {
+ VMCOREINFO_NUMBER(phys_ram_base);
+@@ -27,5 +32,7 @@ void arch_crash_save_vmcoreinfo(void)
+ #else
+ vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n",
+ kernel_map.va_kernel_pa_offset);
++ vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
++ vmcoreinfo_append_str("NUMBER(satp)=0x%llx\n", get_satp_value());
+ #endif
+ }
+--
+2.53.0
+
--- /dev/null
+From 07e53fd655124537b9b12e767a85526c72df4c14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:04:14 +0800
+Subject: riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE
+
+From: Rui Qi <qirui.001@bytedance.com>
+
+[ Upstream commit 3a2694bf6ac8e47b3814293e80343f58fc72937f ]
+
+The FUNCTION_ALIGNMENT_4B select forces the whole kernel to be built
+with -fmin-function-alignment=4. This alignment is only needed so the
+patchable-function-entry NOPs, which arch/riscv/Makefile emits under
+CONFIG_DYNAMIC_FTRACE, can be patched reliably on RISCV_ISA_C=y builds
+where compressed instructions otherwise allow 2-byte function
+alignment.
+
+The select is currently gated on HAVE_DYNAMIC_FTRACE, a capability bit
+that is selected whenever the toolchain supports dynamic ftrace, rather
+than on whether tracing is actually enabled. As a result every
+RISCV_ISA_C=y build gets 4-byte function alignment across the entire
+kernel even when function tracing is disabled, needlessly growing the
+kernel image and wasting instruction cache for a feature that is not
+in use.
+
+Gate the select on DYNAMIC_FTRACE instead, matching the condition under
+which arch/riscv/Makefile emits -fpatchable-function-entry, so the
+alignment is only applied when it is actually needed.
+
+Fixes: c41bf4326c7b ("riscv: ftrace: align patchable functions to 4 Byte boundary")
+Signed-off-by: Rui Qi <qirui.001@bytedance.com>
+Link: https://patch.msgid.link/20260706130415.463682-1-qirui.001@bytedance.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index c09dbb89461ddb..17b968321b6679 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -153,7 +153,7 @@ config RISCV
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_CONTIGUOUS if MMU
+ select HAVE_DYNAMIC_FTRACE if MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
+- select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
++ select FUNCTION_ALIGNMENT_4B if DYNAMIC_FTRACE && RISCV_ISA_C
+ select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
+ select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI)
+ select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
+--
+2.53.0
+
--- /dev/null
+From e0c01437675c2af560dbf23f79be34cd5085ecd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 17:30:56 -0700
+Subject: riscv: hwprobe: Avoid uninitialized read in hwprobe_get_cpus()
+
+From: Mark Harris <mark.hsj@gmail.com>
+
+[ Upstream commit 5caae1deee89a6582c761d5dcd4b924b744426cc ]
+
+When cpusetsize < cpumask_size(), hwprobe_get_cpus() did not fully
+initialize its copy of the cpu mask, which could cause non-deterministic
+results from the riscv_hwprobe syscall on a system with more than 8 CPUs
+when the supplied cpu mask is empty. Address this by fully initializing
+the cpu mask.
+
+Fixes: e178bf146e4b ("RISC-V: hwprobe: Introduce which-cpus flag")
+Signed-off-by: Mark Harris <mark.hsj@gmail.com>
+Reviewed-by: Nam Cao <namcao@linutronix.de>
+Reviewed-by: Michael Ellerman <mpe@kernel.org>
+Link: https://patch.msgid.link/20260714003056.73707-1-mark.hsj@gmail.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/sys_hwprobe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
+index 199d13f86f3135..460fb297672e68 100644
+--- a/arch/riscv/kernel/sys_hwprobe.c
++++ b/arch/riscv/kernel/sys_hwprobe.c
+@@ -409,6 +409,7 @@ static int hwprobe_get_cpus(struct riscv_hwprobe __user *pairs,
+ if (cpusetsize > cpumask_size())
+ cpusetsize = cpumask_size();
+
++ cpumask_clear(&cpus);
+ ret = copy_from_user(&cpus, cpus_user, cpusetsize);
+ if (ret)
+ return -EFAULT;
+--
+2.53.0
+
--- /dev/null
+From 6d2bb998bb0764d49ef86c981e4d356670186611 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Apr 2026 19:28:48 -0600
+Subject: riscv: Remove support for XIP kernel
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit 9b3a2be84803cf18c4b4d1efc695991f0daa153c ]
+
+XIP has a history of being broken for long periods of time. In 2023, it was
+broken for 18 months before getting fixed [1]. In 2024 it was 4 months [2].
+
+And now it is broken again since commit a44fb5722199 ("riscv: Add runtime
+constant support"), 10 months ago.
+
+These are clear signs that XIP feature is not being used.
+
+I occasionally looked after XIP, but mostly because I was bored and had
+nothing better to do.
+
+Remove XIP support. Revert is possible if someone shows up complaining.
+
+Link: https://lore.kernel.org/linux-riscv/20231212-customary-hardcover-e19462bf8e75@wendy/ [1]
+Link: https://lore.kernel.org/linux-riscv/20240526110104.470429-1-namcao@linutronix.de/ [2]
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Cc: Frederik Haxel <haxel@fzi.de>
+Cc: Vitaly Wool <vitaly.wool@konsulko.com>
+Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://patch.msgid.link/20260202115403.2119218-1-namcao@linutronix.de
+[pjw@kernel.org: updated to apply]
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Stable-dep-of: 3a2694bf6ac8 ("riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 86 ++++++---------------
+ arch/riscv/Kconfig.socs | 8 +-
+ arch/riscv/Makefile | 3 -
+ arch/riscv/boot/Makefile | 11 ---
+ arch/riscv/include/asm/page.h | 29 --------
+ arch/riscv/include/asm/pgtable.h | 20 -----
+ arch/riscv/include/asm/scs.h | 1 -
+ arch/riscv/include/asm/set_memory.h | 2 +-
+ arch/riscv/include/asm/xip_fixup.h | 49 ------------
+ arch/riscv/kernel/head.S | 41 ----------
+ arch/riscv/kernel/head.h | 3 -
+ arch/riscv/kernel/setup.c | 6 +-
+ arch/riscv/kernel/suspend_entry.S | 2 -
+ arch/riscv/kernel/traps.c | 4 -
+ arch/riscv/kernel/vmcore_info.c | 7 --
+ arch/riscv/kernel/vmlinux.lds.S | 5 --
+ arch/riscv/mm/init.c | 111 ++--------------------------
+ 17 files changed, 37 insertions(+), 351 deletions(-)
+ delete mode 100644 arch/riscv/include/asm/xip_fixup.h
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index fadec20b87a8e3..c09dbb89461ddb 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -48,8 +48,8 @@ config RISCV
+ select ARCH_HAS_PTE_SPECIAL
+ select ARCH_HAS_SET_DIRECT_MAP if MMU
+ select ARCH_HAS_SET_MEMORY if MMU
+- select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
+- select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
++ select ARCH_HAS_STRICT_KERNEL_RWX if MMU
++ select ARCH_HAS_STRICT_MODULE_RWX if MMU
+ select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+ select ARCH_HAS_SYSCALL_WRAPPER
+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+@@ -85,7 +85,7 @@ config RISCV
+ select ARCH_WANT_FRAME_POINTERS
+ select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT
+ select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
+- select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL
++ select ARCH_WANT_LD_ORPHAN_WARN
+ select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
+ select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
+ select ARCH_WANTS_NO_INSTR
+@@ -130,13 +130,13 @@ config RISCV
+ select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
+ select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
+- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
+- select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL
++ select HAVE_ARCH_JUMP_LABEL
++ select HAVE_ARCH_JUMP_LABEL_RELATIVE
+ select HAVE_ARCH_KASAN if MMU && 64BIT
+ select HAVE_ARCH_KASAN_VMALLOC if MMU && 64BIT
+ select HAVE_ARCH_KFENCE if MMU && 64BIT
+ select HAVE_ARCH_KSTACK_ERASE
+- select HAVE_ARCH_KGDB if !XIP_KERNEL
++ select HAVE_ARCH_KGDB
+ select HAVE_ARCH_KGDB_QXFER_PKT
+ select HAVE_ARCH_MMAP_RND_BITS if MMU
+ select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
+@@ -152,7 +152,7 @@ config RISCV
+ select HAVE_CONTEXT_TRACKING_USER
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_CONTIGUOUS if MMU
+- select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
++ select HAVE_DYNAMIC_FTRACE if MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
+ select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
+ select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
+ select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI)
+@@ -160,7 +160,7 @@ config RISCV
+ select HAVE_FTRACE_GRAPH_FUNC
+ select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS
+ select HAVE_FUNCTION_GRAPH_FREGS
+- select HAVE_FUNCTION_TRACER if !XIP_KERNEL && HAVE_DYNAMIC_FTRACE
++ select HAVE_FUNCTION_TRACER if HAVE_DYNAMIC_FTRACE
+ select HAVE_EBPF_JIT if MMU
+ select HAVE_GENERIC_TIF_BITS
+ select HAVE_GUP_FAST if MMU
+@@ -169,16 +169,16 @@ config RISCV
+ select HAVE_GCC_PLUGINS
+ select HAVE_GENERIC_VDSO if MMU
+ select HAVE_IRQ_TIME_ACCOUNTING
+- select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_GZIP if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_LZ4 if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_LZMA if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_LZO if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_UNCOMPRESSED if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_ZSTD if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KERNEL_XZ if !XIP_KERNEL && !EFI_ZBOOT
+- select HAVE_KPROBES if !XIP_KERNEL
+- select HAVE_KRETPROBES if !XIP_KERNEL
++ select HAVE_KERNEL_BZIP2 if !EFI_ZBOOT
++ select HAVE_KERNEL_GZIP if !EFI_ZBOOT
++ select HAVE_KERNEL_LZ4 if !EFI_ZBOOT
++ select HAVE_KERNEL_LZMA if !EFI_ZBOOT
++ select HAVE_KERNEL_LZO if !EFI_ZBOOT
++ select HAVE_KERNEL_UNCOMPRESSED if !EFI_ZBOOT
++ select HAVE_KERNEL_ZSTD if !EFI_ZBOOT
++ select HAVE_KERNEL_XZ if !EFI_ZBOOT
++ select HAVE_KPROBES
++ select HAVE_KRETPROBES
+ # https://github.com/ClangBuiltLinux/linux/issues/1881
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD
+ select HAVE_MOVE_PMD
+@@ -189,9 +189,9 @@ config RISCV
+ select HAVE_PERF_REGS
+ select HAVE_PERF_USER_STACK_DUMP
+ select HAVE_POSIX_CPU_TIMERS_TASK_WORK
+- select HAVE_PREEMPT_DYNAMIC_KEY if !XIP_KERNEL
++ select HAVE_PREEMPT_DYNAMIC_KEY
+ select HAVE_REGS_AND_STACK_ACCESS_API
+- select HAVE_RETHOOK if !XIP_KERNEL
++ select HAVE_RETHOOK
+ select HAVE_RSEQ
+ select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG
+ select HAVE_SAMPLE_FTRACE_DIRECT
+@@ -212,7 +212,7 @@ config RISCV
+ select PCI_ECAM if (ACPI && PCI)
+ select PCI_MSI if PCI
+ select RELOCATABLE if !MMU && !PHYS_RAM_BASE_FIXED
+- select RISCV_ALTERNATIVE if !XIP_KERNEL
++ select RISCV_ALTERNATIVE
+ select RISCV_APLIC
+ select RISCV_IMSIC
+ select RISCV_INTC
+@@ -539,7 +539,6 @@ endchoice
+
+ config RISCV_ALTERNATIVE
+ bool
+- depends on !XIP_KERNEL
+ help
+ This Kconfig allows the kernel to automatically patch the
+ erratum or cpufeature required by the execution platform at run
+@@ -1113,7 +1112,6 @@ config PARAVIRT_TIME_ACCOUNTING
+
+ config RELOCATABLE
+ bool "Build a relocatable kernel"
+- depends on !XIP_KERNEL
+ select MODULE_SECTIONS if MODULES
+ select ARCH_VMLINUX_NEEDS_RELOCS
+ help
+@@ -1130,7 +1128,7 @@ config RELOCATABLE
+ config RANDOMIZE_BASE
+ bool "Randomize the address of the kernel image"
+ select RELOCATABLE
+- depends on MMU && 64BIT && !XIP_KERNEL
++ depends on MMU && 64BIT
+ help
+ Randomizes the virtual address at which the kernel image is
+ loaded, as a security feature that deters exploit attempts
+@@ -1198,7 +1196,7 @@ config EFI_STUB
+
+ config EFI
+ bool "UEFI runtime support"
+- depends on OF && !XIP_KERNEL
++ depends on OF
+ depends on MMU
+ default y
+ select ARCH_SUPPORTS_ACPI if 64BIT
+@@ -1249,44 +1247,6 @@ config PHYS_RAM_BASE
+ explicitly specified to run early relocations of read-write data
+ from flash to RAM.
+
+-config XIP_KERNEL
+- bool "Kernel Execute-In-Place from ROM"
+- depends on MMU && SPARSEMEM && NONPORTABLE
+- # This prevents XIP from being enabled by all{yes,mod}config, which
+- # fail to build since XIP doesn't support large kernels.
+- depends on !COMPILE_TEST
+- select PHYS_RAM_BASE_FIXED
+- help
+- Execute-In-Place allows the kernel to run from non-volatile storage
+- directly addressable by the CPU, such as NOR flash. This saves RAM
+- space since the text section of the kernel is not loaded from flash
+- to RAM. Read-write sections, such as the data section and stack,
+- are still copied to RAM. The XIP kernel is not compressed since
+- it has to run directly from flash, so it will take more space to
+- store it. The flash address used to link the kernel object files,
+- and for storing it, is configuration dependent. Therefore, if you
+- say Y here, you must know the proper physical address where to
+- store the kernel image depending on your own flash memory usage.
+-
+- Also note that the make target becomes "make xipImage" rather than
+- "make zImage" or "make Image". The final kernel binary to put in
+- ROM memory will be arch/riscv/boot/xipImage.
+-
+- SPARSEMEM is required because the kernel text and rodata that are
+- flash resident are not backed by memmap, then any attempt to get
+- a struct page on those regions will trigger a fault.
+-
+- If unsure, say N.
+-
+-config XIP_PHYS_ADDR
+- hex "XIP Kernel Physical Location"
+- depends on XIP_KERNEL
+- default "0x21000000"
+- help
+- This is the physical address in your flash memory the kernel will
+- be linked for and stored to. This address is dependent on your
+- own flash usage.
+-
+ config RISCV_ISA_FALLBACK
+ bool "Permit falling back to parsing riscv,isa for extension support by default"
+ default y
+diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
+index 848e7149e4435a..baed90e6ae4878 100644
+--- a/arch/riscv/Kconfig.socs
++++ b/arch/riscv/Kconfig.socs
+@@ -2,7 +2,7 @@ menu "SoC selection"
+
+ config ARCH_ANDES
+ bool "Andes SoCs"
+- depends on MMU && !XIP_KERNEL
++ depends on MMU
+ select ERRATA_ANDES
+ help
+ This enables support for Andes SoC platform hardware.
+@@ -28,7 +28,7 @@ config ARCH_RENESAS
+
+ config ARCH_SIFIVE
+ bool "SiFive SoCs"
+- select ERRATA_SIFIVE if !XIP_KERNEL
++ select ERRATA_SIFIVE
+ help
+ This enables support for SiFive SoC platform hardware.
+
+@@ -56,7 +56,7 @@ config SOC_STARFIVE
+
+ config ARCH_SUNXI
+ bool "Allwinner sun20i SoCs"
+- depends on MMU && !XIP_KERNEL
++ depends on MMU
+ select ERRATA_THEAD
+ select SUN4I_TIMER
+ help
+@@ -65,7 +65,7 @@ config ARCH_SUNXI
+
+ config ARCH_THEAD
+ bool "T-HEAD RISC-V SoCs"
+- depends on MMU && !XIP_KERNEL
++ depends on MMU
+ select ERRATA_THEAD
+ select PM_GENERIC_DOMAINS if PM
+ help
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index 4c6de57f65ef0e..c7aaa2965a689b 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -147,7 +147,6 @@ ifdef CONFIG_RISCV_M_MODE
+ boot-image-$(CONFIG_SOC_CANAAN_K210) := loader.bin
+ endif
+ boot-image-$(CONFIG_EFI_ZBOOT) := vmlinuz.efi
+-boot-image-$(CONFIG_XIP_KERNEL) := xipImage
+ KBUILD_IMAGE := $(boot)/$(boot-image-y)
+
+ libs-y += arch/riscv/lib/
+@@ -212,8 +211,6 @@ define archhelp
+ echo ' Image.xz - Compressed kernel image (arch/riscv/boot/Image.xz)'
+ echo ' vmlinuz.efi - Compressed EFI kernel image (arch/riscv/boot/vmlinuz.efi)'
+ echo ' Default when CONFIG_EFI_ZBOOT=y'
+- echo ' xipImage - Execute-in-place kernel image (arch/riscv/boot/xipImage)'
+- echo ' Default when CONFIG_XIP_KERNEL=y'
+ echo ' install - Install kernel using (your) ~/bin/$(INSTALLKERNEL) or'
+ echo ' (distribution) /sbin/$(INSTALLKERNEL) or install to '
+ echo ' $$(INSTALL_PATH)'
+diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
+index 5301adf5f3f5d2..fcfbe3f814d664 100644
+--- a/arch/riscv/boot/Makefile
++++ b/arch/riscv/boot/Makefile
+@@ -20,17 +20,6 @@ OBJCOPYFLAGS_xipImage :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
+
+ targets := Image Image.* loader loader.o loader.lds loader.bin xipImage
+
+-ifeq ($(CONFIG_XIP_KERNEL),y)
+-
+-quiet_cmd_mkxip = $(quiet_cmd_objcopy)
+-cmd_mkxip = $(cmd_objcopy)
+-
+-$(obj)/xipImage: vmlinux FORCE
+- $(call if_changed,mkxip)
+- @$(kecho) ' Physical Address of xipImage: $(CONFIG_XIP_PHYS_ADDR)'
+-
+-endif
+-
+ $(obj)/Image: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
+index ffe213ad65a4ee..d0e29b52738567 100644
+--- a/arch/riscv/include/asm/page.h
++++ b/arch/riscv/include/asm/page.h
+@@ -29,11 +29,7 @@
+ #define PAGE_OFFSET_L5 _AC(0xff60000000000000, UL)
+ #define PAGE_OFFSET_L4 _AC(0xffffaf8000000000, UL)
+ #define PAGE_OFFSET_L3 _AC(0xffffffd600000000, UL)
+-#ifdef CONFIG_XIP_KERNEL
+-#define PAGE_OFFSET PAGE_OFFSET_L3
+-#else
+ #define PAGE_OFFSET kernel_map.page_offset
+-#endif /* CONFIG_XIP_KERNEL */
+ #else
+ #define PAGE_OFFSET _AC(0xc0000000, UL)
+ #endif /* CONFIG_64BIT */
+@@ -106,15 +102,8 @@ struct kernel_mapping {
+ /* Offset between linear mapping virtual address and kernel load address */
+ unsigned long va_pa_offset;
+ /* Offset between kernel mapping virtual address and kernel load address */
+-#ifdef CONFIG_XIP_KERNEL
+- unsigned long va_kernel_xip_text_pa_offset;
+- unsigned long va_kernel_xip_data_pa_offset;
+- uintptr_t xiprom;
+- uintptr_t xiprom_sz;
+-#else
+ unsigned long page_offset;
+ unsigned long va_kernel_pa_offset;
+-#endif
+ };
+
+ extern struct kernel_mapping kernel_map;
+@@ -133,16 +122,7 @@ extern unsigned long vmemmap_start_pfn;
+ void *linear_mapping_pa_to_va(unsigned long x);
+ #endif
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define kernel_mapping_pa_to_va(y) ({ \
+- unsigned long _y = (unsigned long)(y); \
+- (_y < phys_ram_base) ? \
+- (void *)(_y + kernel_map.va_kernel_xip_text_pa_offset) : \
+- (void *)(_y + kernel_map.va_kernel_xip_data_pa_offset); \
+- })
+-#else
+ #define kernel_mapping_pa_to_va(y) ((void *)((unsigned long)(y) + kernel_map.va_kernel_pa_offset))
+-#endif
+
+ #define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x)
+
+@@ -152,16 +132,7 @@ void *linear_mapping_pa_to_va(unsigned long x);
+ phys_addr_t linear_mapping_va_to_pa(unsigned long x);
+ #endif
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define kernel_mapping_va_to_pa(y) ({ \
+- unsigned long _y = (unsigned long)(y); \
+- (_y < kernel_map.virt_addr + kernel_map.xiprom_sz) ? \
+- (_y - kernel_map.va_kernel_xip_text_pa_offset) : \
+- (_y - kernel_map.va_kernel_xip_data_pa_offset); \
+- })
+-#else
+ #define kernel_mapping_va_to_pa(y) ((unsigned long)(y) - kernel_map.va_kernel_pa_offset)
+-#endif
+
+ #define __va_to_pa_nodebug(x) ({ \
+ unsigned long _x = x; \
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 9b2e967c9fe080..78bde59498836b 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -144,21 +144,6 @@
+
+ #include <linux/page_table_check.h>
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define XIP_FIXUP(addr) ({ \
+- extern char _sdata[], _start[], _end[]; \
+- uintptr_t __rom_start_data = CONFIG_XIP_PHYS_ADDR \
+- + (uintptr_t)&_sdata - (uintptr_t)&_start; \
+- uintptr_t __rom_end_data = CONFIG_XIP_PHYS_ADDR \
+- + (uintptr_t)&_end - (uintptr_t)&_start; \
+- uintptr_t __a = (uintptr_t)(addr); \
+- (__a >= __rom_start_data && __a < __rom_end_data) ? \
+- __a - __rom_start_data + CONFIG_PHYS_RAM_BASE : __a; \
+- })
+-#else
+-#define XIP_FIXUP(addr) (addr)
+-#endif /* CONFIG_XIP_KERNEL */
+-
+ struct pt_alloc_ops {
+ pte_t *(*get_pte_virt)(phys_addr_t pa);
+ phys_addr_t (*alloc_pte)(uintptr_t va);
+@@ -1106,13 +1091,8 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
+ extern char _start[];
+ extern void *_dtb_early_va;
+ extern uintptr_t _dtb_early_pa;
+-#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_MMU)
+-#define dtb_early_va (*(void **)XIP_FIXUP(&_dtb_early_va))
+-#define dtb_early_pa (*(uintptr_t *)XIP_FIXUP(&_dtb_early_pa))
+-#else
+ #define dtb_early_va _dtb_early_va
+ #define dtb_early_pa _dtb_early_pa
+-#endif /* CONFIG_XIP_KERNEL */
+ extern u64 satp_mode;
+
+ void paging_init(void);
+diff --git a/arch/riscv/include/asm/scs.h b/arch/riscv/include/asm/scs.h
+index ab7714aa93bdc4..023a412fe38d37 100644
+--- a/arch/riscv/include/asm/scs.h
++++ b/arch/riscv/include/asm/scs.h
+@@ -10,7 +10,6 @@
+ /* Load init_shadow_call_stack to gp. */
+ .macro scs_load_init_stack
+ la gp, init_shadow_call_stack
+- XIP_FIXUP_OFFSET gp
+ .endm
+
+ /* Load the per-CPU IRQ shadow call stack to gp. */
+diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
+index 87389e93325a3b..ef59e1716a2cfd 100644
+--- a/arch/riscv/include/asm/set_memory.h
++++ b/arch/riscv/include/asm/set_memory.h
+@@ -47,7 +47,7 @@ bool kernel_page_present(struct page *page);
+
+ #endif /* __ASSEMBLER__ */
+
+-#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_XIP_KERNEL)
++#if defined(CONFIG_STRICT_KERNEL_RWX)
+ #ifdef CONFIG_64BIT
+ #define SECTION_ALIGN (1 << 21)
+ #else
+diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h
+deleted file mode 100644
+index f3d56299bc22c5..00000000000000
+--- a/arch/riscv/include/asm/xip_fixup.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * XIP fixup macros, only useful in assembly.
+- */
+-#ifndef _ASM_RISCV_XIP_FIXUP_H
+-#define _ASM_RISCV_XIP_FIXUP_H
+-
+-#include <linux/pgtable.h>
+-
+-#ifdef CONFIG_XIP_KERNEL
+-.macro XIP_FIXUP_OFFSET reg
+- /* Fix-up address in Flash into address in RAM early during boot before
+- * MMU is up. Because generated code "thinks" data is in Flash, but it
+- * is actually in RAM (actually data is also in Flash, but Flash is
+- * read-only, thus we need to use the data residing in RAM).
+- *
+- * The start of data in Flash is _sdata and the start of data in RAM is
+- * CONFIG_PHYS_RAM_BASE. So this fix-up essentially does this:
+- * reg += CONFIG_PHYS_RAM_BASE - _start
+- */
+- li t0, CONFIG_PHYS_RAM_BASE
+- add \reg, \reg, t0
+- la t0, _sdata
+- sub \reg, \reg, t0
+-.endm
+-.macro XIP_FIXUP_FLASH_OFFSET reg
+- /* In linker script, at the transition from read-only section to
+- * writable section, the VMA is increased while LMA remains the same.
+- * (See in linker script how _sdata, __data_loc and LOAD_OFFSET is
+- * changed)
+- *
+- * Consequently, early during boot before MMU is up, the generated code
+- * reads the "writable" section at wrong addresses, because VMA is used
+- * by compiler to generate code, but the data is located in Flash using
+- * LMA.
+- */
+- la t0, _sdata
+- sub \reg, \reg, t0
+- la t0, __data_loc
+- add \reg, \reg, t0
+-.endm
+-#else
+-.macro XIP_FIXUP_OFFSET reg
+-.endm
+-.macro XIP_FIXUP_FLASH_OFFSET reg
+-.endm
+-#endif /* CONFIG_XIP_KERNEL */
+-
+-#endif
+diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
+index 9c99c5ad6fe8a3..65039904436892 100644
+--- a/arch/riscv/kernel/head.S
++++ b/arch/riscv/kernel/head.S
+@@ -14,7 +14,6 @@
+ #include <asm/hwcap.h>
+ #include <asm/image.h>
+ #include <asm/scs.h>
+-#include <asm/xip_fixup.h>
+ #include <asm/usercfi.h>
+ #include "efi-header.S"
+
+@@ -75,7 +74,6 @@ pe_head_start:
+ relocate_enable_mmu:
+ /* Relocate return address */
+ la a1, kernel_map
+- XIP_FIXUP_OFFSET a1
+ REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
+ la a2, _start
+ sub a1, a1, a2
+@@ -89,7 +87,6 @@ relocate_enable_mmu:
+ /* Compute satp for kernel page tables, but don't load it yet */
+ srl a2, a0, PAGE_SHIFT
+ la a1, satp_mode
+- XIP_FIXUP_OFFSET a1
+ REG_L a1, 0(a1)
+ or a2, a2, a1
+
+@@ -100,7 +97,6 @@ relocate_enable_mmu:
+ * to ensure the new translations are in use.
+ */
+ la a0, trampoline_pg_dir
+- XIP_FIXUP_OFFSET a0
+ srl a0, a0, PAGE_SHIFT
+ or a0, a0, a1
+ sfence.vma
+@@ -154,11 +150,9 @@ secondary_start_sbi:
+
+ /* a0 contains the hartid & a1 contains boot data */
+ li a2, SBI_HART_BOOT_TASK_PTR_OFFSET
+- XIP_FIXUP_OFFSET a2
+ add a2, a2, a1
+ REG_L tp, (a2)
+ li a3, SBI_HART_BOOT_STACK_PTR_OFFSET
+- XIP_FIXUP_OFFSET a3
+ add a3, a3, a1
+ REG_L sp, (a3)
+
+@@ -167,7 +161,6 @@ secondary_start_sbi:
+ #ifdef CONFIG_MMU
+ /* Enable virtual memory and relocate to virtual address */
+ la a0, swapper_pg_dir
+- XIP_FIXUP_OFFSET a0
+ call relocate_enable_mmu
+ #endif
+ call .Lsetup_trap_vector
+@@ -269,40 +262,13 @@ SYM_CODE_START(_start_kernel)
+ .Lgood_cores:
+
+ /* The lottery system is only required for spinwait booting method */
+-#ifndef CONFIG_XIP_KERNEL
+ /* Pick one hart to run the main boot sequence */
+ la a3, hart_lottery
+ li a2, 1
+ amoadd.w a3, a2, (a3)
+ bnez a3, .Lsecondary_start
+-
+-#else
+- /* hart_lottery in flash contains a magic number */
+- la a3, hart_lottery
+- mv a2, a3
+- XIP_FIXUP_OFFSET a2
+- XIP_FIXUP_FLASH_OFFSET a3
+- lw t1, (a3)
+- amoswap.w t0, t1, (a2)
+- /* first time here if hart_lottery in RAM is not set */
+- beq t0, t1, .Lsecondary_start
+-
+-#endif /* CONFIG_XIP */
+ #endif /* CONFIG_RISCV_BOOT_SPINWAIT */
+
+-#ifdef CONFIG_XIP_KERNEL
+- la sp, _end + THREAD_SIZE
+- XIP_FIXUP_OFFSET sp
+- mv s0, a0
+- mv s1, a1
+- call __copy_data
+-
+- /* Restore a0 & a1 copy */
+- mv a0, s0
+- mv a1, s1
+-#endif
+-
+-#ifndef CONFIG_XIP_KERNEL
+ /* Clear BSS for flat non-ELF images */
+ la a3, __bss_start
+ la a4, __bss_stop
+@@ -312,20 +278,16 @@ SYM_CODE_START(_start_kernel)
+ add a3, a3, RISCV_SZPTR
+ blt a3, a4, .Lclear_bss
+ .Lclear_bss_done:
+-#endif
+ la a2, boot_cpu_hartid
+- XIP_FIXUP_OFFSET a2
+ REG_S a0, (a2)
+
+ /* Initialize page tables and relocate to virtual addresses */
+ la tp, init_task
+ la sp, init_thread_union + THREAD_SIZE
+- XIP_FIXUP_OFFSET sp
+ addi sp, sp, -PT_SIZE_ON_STACK
+ scs_load_init_stack
+ #ifdef CONFIG_BUILTIN_DTB
+ la a0, __dtb_start
+- XIP_FIXUP_OFFSET a0
+ #else
+ mv a0, a1
+ #endif /* CONFIG_BUILTIN_DTB */
+@@ -335,7 +297,6 @@ SYM_CODE_START(_start_kernel)
+ call setup_vm
+ #ifdef CONFIG_MMU
+ la a0, early_pg_dir
+- XIP_FIXUP_OFFSET a0
+ call relocate_enable_mmu
+ #endif /* CONFIG_MMU */
+
+@@ -374,9 +335,7 @@ SYM_CODE_START(_start_kernel)
+
+ slli a3, a0, LGREG
+ la a1, __cpu_spinwait_stack_pointer
+- XIP_FIXUP_OFFSET a1
+ la a2, __cpu_spinwait_task_pointer
+- XIP_FIXUP_OFFSET a2
+ add a1, a3, a1
+ add a2, a3, a2
+
+diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
+index a556fdaafed943..05a04bef442b1b 100644
+--- a/arch/riscv/kernel/head.h
++++ b/arch/riscv/kernel/head.h
+@@ -11,9 +11,6 @@
+ extern atomic_t hart_lottery;
+
+ asmlinkage void __init setup_vm(uintptr_t dtb_pa);
+-#ifdef CONFIG_XIP_KERNEL
+-asmlinkage void __init __copy_data(void);
+-#endif
+
+ #ifdef CONFIG_RISCV_BOOT_SPINWAIT
+ extern void *__cpu_spinwait_stack_pointer[];
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index b5bc5fc65cea65..c89cc272440b9f 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -46,11 +46,7 @@
+ * This is used before the kernel initializes the BSS so it can't be in the
+ * BSS.
+ */
+-atomic_t hart_lottery __section(".sdata")
+-#ifdef CONFIG_XIP_KERNEL
+-= ATOMIC_INIT(0xC001BEEF)
+-#endif
+-;
++atomic_t hart_lottery __section(".sdata");
+ unsigned long boot_cpu_hartid;
+ EXPORT_SYMBOL_GPL(boot_cpu_hartid);
+
+diff --git a/arch/riscv/kernel/suspend_entry.S b/arch/riscv/kernel/suspend_entry.S
+index 2d54f309c14059..d71b55fd6259f3 100644
+--- a/arch/riscv/kernel/suspend_entry.S
++++ b/arch/riscv/kernel/suspend_entry.S
+@@ -10,7 +10,6 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/assembler.h>
+ #include <asm/csr.h>
+-#include <asm/xip_fixup.h>
+
+ .text
+ .altmacro
+@@ -70,7 +69,6 @@ SYM_TYPED_FUNC_START(__cpu_resume_enter)
+
+ /* Enable MMU */
+ la a0, swapper_pg_dir
+- XIP_FIXUP_OFFSET a0
+ call relocate_enable_mmu
+
+ /* Restore A0 and A1 */
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 47afea4ff1a8d2..3d24a4697bd915 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -142,11 +142,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
+ }
+ }
+
+-#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE)
+-#define __trap_section __noinstr_section(".xip.traps")
+-#else
+ #define __trap_section noinstr
+-#endif
+ #define DO_ERROR_INFO(name, signo, code, str) \
+ asmlinkage __visible __trap_section void name(struct pt_regs *regs) \
+ { \
+diff --git a/arch/riscv/kernel/vmcore_info.c b/arch/riscv/kernel/vmcore_info.c
+index 682ba423cf203d..c27efceec3cc3a 100644
+--- a/arch/riscv/kernel/vmcore_info.c
++++ b/arch/riscv/kernel/vmcore_info.c
+@@ -24,15 +24,8 @@ void arch_crash_save_vmcoreinfo(void)
+ #endif
+ #endif
+ vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR);
+-#ifdef CONFIG_XIP_KERNEL
+- /* TODO: Communicate with crash-utility developers on the information to
+- * export. The XIP case is more complicated, because the virtual-physical
+- * address offset depends on whether the address is in ROM or in RAM.
+- */
+-#else
+ vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n",
+ kernel_map.va_kernel_pa_offset);
+ vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+ vmcoreinfo_append_str("NUMBER(satp)=0x%llx\n", get_satp_value());
+-#endif
+ }
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index 997f9eb3b22b13..1f4f8496941aef 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -7,10 +7,6 @@
+ #define RO_EXCEPTION_TABLE_ALIGN 4
+ #define RUNTIME_DISCARD_EXIT
+
+-#ifdef CONFIG_XIP_KERNEL
+-#include "vmlinux-xip.lds.S"
+-#else
+-
+ #include <asm/pgtable.h>
+ #define LOAD_OFFSET KERNEL_LINK_ADDR
+
+@@ -176,4 +172,3 @@ SECTIONS
+
+ DISCARDS
+ }
+-#endif /* CONFIG_XIP_KERNEL */
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index ee40ca01ac6636..4994df8dc92618 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -41,20 +41,17 @@ u64 new_vmalloc[NR_CPUS / sizeof(u64) + 1];
+
+ struct kernel_mapping kernel_map __ro_after_init;
+ EXPORT_SYMBOL(kernel_map);
+-#ifdef CONFIG_XIP_KERNEL
+-#define kernel_map (*(struct kernel_mapping *)XIP_FIXUP(&kernel_map))
+-#endif
+
+ #ifdef CONFIG_64BIT
+-u64 satp_mode __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL) ? SATP_MODE_57 : SATP_MODE_39;
++u64 satp_mode __ro_after_init = SATP_MODE_57;
+ #else
+ u64 satp_mode __ro_after_init = SATP_MODE_32;
+ #endif
+ EXPORT_SYMBOL(satp_mode);
+
+ #ifdef CONFIG_64BIT
+-bool pgtable_l4_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
+-bool pgtable_l5_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
++bool pgtable_l4_enabled __ro_after_init = true;
++bool pgtable_l5_enabled __ro_after_init = true;
+ EXPORT_SYMBOL(pgtable_l4_enabled);
+ EXPORT_SYMBOL(pgtable_l5_enabled);
+ #endif
+@@ -197,9 +194,6 @@ void __init arch_mm_preinit(void)
+
+ /* Limit the memory size via mem. */
+ static phys_addr_t memory_limit;
+-#ifdef CONFIG_XIP_KERNEL
+-#define memory_limit (*(phys_addr_t *)XIP_FIXUP(&memory_limit))
+-#endif /* CONFIG_XIP_KERNEL */
+
+ static int __init early_mem(char *p)
+ {
+@@ -223,10 +217,7 @@ static void __init setup_bootmem(void)
+ phys_addr_t max_mapped_addr;
+ phys_addr_t phys_ram_end, vmlinux_start;
+
+- if (IS_ENABLED(CONFIG_XIP_KERNEL))
+- vmlinux_start = __pa_symbol(&_sdata);
+- else
+- vmlinux_start = __pa_symbol(&_start);
++ vmlinux_start = __pa_symbol(&_start);
+
+ memblock_enforce_memory_limit(memory_limit);
+
+@@ -246,12 +237,10 @@ static void __init setup_bootmem(void)
+ * Make sure we align the start of the memory on a PMD boundary so that
+ * at worst, we map the linear mapping with PMD mappings.
+ */
+- if (!IS_ENABLED(CONFIG_XIP_KERNEL)) {
+- phys_ram_base = memblock_start_of_DRAM() & PMD_MASK;
++ phys_ram_base = memblock_start_of_DRAM() & PMD_MASK;
+ #ifdef CONFIG_SPARSEMEM_VMEMMAP
+- vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
++ vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
+ #endif
+- }
+
+ /*
+ * In 64-bit, any use of __va/__pa before this point is wrong as we
+@@ -366,13 +355,6 @@ static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
+
+ pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
+-#define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
+-#define fixmap_pte ((pte_t *)XIP_FIXUP(fixmap_pte))
+-#define early_pg_dir ((pgd_t *)XIP_FIXUP(early_pg_dir))
+-#endif /* CONFIG_XIP_KERNEL */
+-
+ static const pgprot_t protection_map[16] = {
+ [VM_NONE] = PAGE_NONE,
+ [VM_READ] = PAGE_READ,
+@@ -469,32 +451,14 @@ static pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss;
+ static pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss;
+ static pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define trampoline_pmd ((pmd_t *)XIP_FIXUP(trampoline_pmd))
+-#define fixmap_pmd ((pmd_t *)XIP_FIXUP(fixmap_pmd))
+-#define early_pmd ((pmd_t *)XIP_FIXUP(early_pmd))
+-#endif /* CONFIG_XIP_KERNEL */
+-
+ static p4d_t trampoline_p4d[PTRS_PER_P4D] __page_aligned_bss;
+ static p4d_t fixmap_p4d[PTRS_PER_P4D] __page_aligned_bss;
+ static p4d_t early_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define trampoline_p4d ((p4d_t *)XIP_FIXUP(trampoline_p4d))
+-#define fixmap_p4d ((p4d_t *)XIP_FIXUP(fixmap_p4d))
+-#define early_p4d ((p4d_t *)XIP_FIXUP(early_p4d))
+-#endif /* CONFIG_XIP_KERNEL */
+-
+ static pud_t trampoline_pud[PTRS_PER_PUD] __page_aligned_bss;
+ static pud_t fixmap_pud[PTRS_PER_PUD] __page_aligned_bss;
+ static pud_t early_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define trampoline_pud ((pud_t *)XIP_FIXUP(trampoline_pud))
+-#define fixmap_pud ((pud_t *)XIP_FIXUP(fixmap_pud))
+-#define early_pud ((pud_t *)XIP_FIXUP(early_pud))
+-#endif /* CONFIG_XIP_KERNEL */
+-
+ static pmd_t *__init get_pmd_virt_early(phys_addr_t pa)
+ {
+ /* Before MMU is enabled */
+@@ -765,21 +729,6 @@ static uintptr_t __meminit best_map_size(phys_addr_t pa, uintptr_t va, phys_addr
+ return PAGE_SIZE;
+ }
+
+-#ifdef CONFIG_XIP_KERNEL
+-#define phys_ram_base (*(phys_addr_t *)XIP_FIXUP(&phys_ram_base))
+-extern char _xiprom[], _exiprom[], __data_loc;
+-
+-/* called from head.S with MMU off */
+-asmlinkage void __init __copy_data(void)
+-{
+- void *from = (void *)(&__data_loc);
+- void *to = (void *)CONFIG_PHYS_RAM_BASE;
+- size_t sz = (size_t)((uintptr_t)(&_end) - (uintptr_t)(&_sdata));
+-
+- memcpy(to, from, sz);
+-}
+-#endif
+-
+ #ifdef CONFIG_STRICT_KERNEL_RWX
+ static __meminit pgprot_t pgprot_from_va(uintptr_t va)
+ {
+@@ -815,7 +764,7 @@ static __meminit pgprot_t pgprot_from_va(uintptr_t va)
+ }
+ #endif /* CONFIG_STRICT_KERNEL_RWX */
+
+-#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
++#if defined(CONFIG_64BIT)
+ u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa);
+ u64 __pi_set_satp_mode_from_fdt(uintptr_t dtb_pa);
+
+@@ -965,28 +914,6 @@ static __init void set_satp_mode(uintptr_t dtb_pa)
+ #error "setup_vm() is called from head.S before relocate so it should not use absolute addressing."
+ #endif
+
+-#ifdef CONFIG_XIP_KERNEL
+-static void __init create_kernel_page_table(pgd_t *pgdir,
+- __always_unused bool early)
+-{
+- uintptr_t va, start_va, end_va;
+-
+- /* Map the flash resident part */
+- end_va = kernel_map.virt_addr + kernel_map.xiprom_sz;
+- for (va = kernel_map.virt_addr; va < end_va; va += PMD_SIZE)
+- create_pgd_mapping(pgdir, va,
+- kernel_map.xiprom + (va - kernel_map.virt_addr),
+- PMD_SIZE, PAGE_KERNEL_EXEC);
+-
+- /* Map the data in RAM */
+- start_va = kernel_map.virt_addr + (uintptr_t)&_sdata - (uintptr_t)&_start;
+- end_va = kernel_map.virt_addr + kernel_map.size;
+- for (va = start_va; va < end_va; va += PMD_SIZE)
+- create_pgd_mapping(pgdir, va,
+- kernel_map.phys_addr + (va - start_va),
+- PMD_SIZE, PAGE_KERNEL);
+-}
+-#else
+ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
+ {
+ uintptr_t va, end_va;
+@@ -999,7 +926,6 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
+ early ?
+ PAGE_KERNEL_EXEC : pgprot_from_va(va));
+ }
+-#endif
+
+ /*
+ * Setup a 4MB mapping that encompasses the device tree: for 64-bit kernel,
+@@ -1141,27 +1067,11 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
+
+ kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset;
+
+-#ifdef CONFIG_XIP_KERNEL
+- kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
+- kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
+-
+- phys_ram_base = CONFIG_PHYS_RAM_BASE;
+-#ifdef CONFIG_SPARSEMEM_VMEMMAP
+- vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
+-#endif
+- kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
+- kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start);
+-
+- kernel_map.va_kernel_xip_text_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
+- kernel_map.va_kernel_xip_data_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr
+- + (uintptr_t)&_sdata - (uintptr_t)&_start;
+-#else
+ kernel_map.phys_addr = (uintptr_t)(&_start);
+ kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr;
+ kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
+-#endif
+
+-#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
++#if defined(CONFIG_64BIT)
+ set_satp_mode(dtb_pa);
+ set_mmap_rnd_bits_max();
+ #endif
+@@ -1234,13 +1144,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
+ if (pgtable_l4_enabled)
+ create_pud_mapping(trampoline_pud, kernel_map.virt_addr,
+ (uintptr_t)trampoline_pmd, PUD_SIZE, PAGE_TABLE);
+-#ifdef CONFIG_XIP_KERNEL
+- create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
+- kernel_map.xiprom, PMD_SIZE, PAGE_KERNEL_EXEC);
+-#else
+ create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
+ kernel_map.phys_addr, PMD_SIZE, PAGE_KERNEL_EXEC);
+-#endif
+ #else
+ /* Setup trampoline PGD */
+ create_pgd_mapping(trampoline_pg_dir, kernel_map.virt_addr,
+--
+2.53.0
+
--- /dev/null
+From 998350d98a4bb5c984015934dcae3f387033d6c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:02:14 +0200
+Subject: s390/checksum: Fix csum_partial() without vector facility
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+[ Upstream commit 4bb06b60d982355e22647b3d12d6619419f8c1fa ]
+
+Currently csum_partial() calls csum_copy() with copy=false and dst=NULL.
+On machines without the vector facility, csum_copy() falls back to
+cksm(dst, ...), causing the checksum to be calculated from address zero
+instead of the source buffer.
+
+The VX implementation already checksums data loaded from src. Make the
+fallback do the same by passing src to cksm().
+
+Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/lib/csum-partial.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/lib/csum-partial.c b/arch/s390/lib/csum-partial.c
+index 458abd9bac7025..9d74ceff136c54 100644
+--- a/arch/s390/lib/csum-partial.c
++++ b/arch/s390/lib/csum-partial.c
+@@ -23,7 +23,7 @@ static __always_inline __wsum csum_copy(void *dst, const void *src, int len, __w
+ if (!cpu_has_vx()) {
+ if (copy)
+ memcpy(dst, src, len);
+- return cksm(dst, len, sum);
++ return cksm(src, len, sum);
+ }
+ kernel_fpu_begin(&vxstate, KERNEL_VXR_V16V23);
+ fpu_vlvgf(16, (__force u32)sum, 1);
+--
+2.53.0
+
--- /dev/null
+From 58de3631610a2f09047fd9789edfd3369c5125a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Dec 2025 02:22:03 +0000
+Subject: sched/ext: Avoid null ptr traversal when ->put_prev_task() is called
+ with NULL next
+
+From: John Stultz <jstultz@google.com>
+
+[ Upstream commit 12b5cd99a05f7cbc2ceb88b3b9601d404ef2236a ]
+
+Early when trying to get sched_ext and proxy-exe working together,
+I kept tripping over NULL ptr in put_prev_task_scx() on the line:
+ if (sched_class_above(&ext_sched_class, next->sched_class)) {
+
+Which was due to put_prev_task() passes a NULL next, calling:
+ prev->sched_class->put_prev_task(rq, prev, NULL);
+
+put_prev_task_scx() already guards for a NULL next in the
+switch_class case, but doesn't seem to have a guard for
+sched_class_above() check.
+
+I can't say I understand why this doesn't trip usually without
+proxy-exec. And in newer kernels there are way fewer
+put_prev_task(), and I can't easily reproduce the issue now
+even with proxy-exec.
+
+But we still have one put_prev_task() call left in core.c that
+seems like it could trip this, so I wanted to send this out for
+consideration.
+
+tj: put_prev_task() can be called with NULL @next; however, when @p is
+queued, that doesn't happen, so this condition shouldn't currently be
+triggerable. The connection isn't straightforward or necessarily reliable,
+so add the NULL check even if it can't currently be triggered.
+
+Link: http://lkml.kernel.org/r/20251206022218.1541878-1-jstultz@google.com
+Signed-off-by: John Stultz <jstultz@google.com>
+Reviewed-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Stable-dep-of: b7d9c359e5cf ("sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index d8280f87443310..d399494364c0a3 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -2396,7 +2396,7 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
+ * ops.enqueue() that @p is the only one available for this cpu,
+ * which should trigger an explicit follow-up scheduling event.
+ */
+- if (sched_class_above(&ext_sched_class, next->sched_class)) {
++ if (next && sched_class_above(&ext_sched_class, next->sched_class)) {
+ WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_LAST));
+ do_enqueue_task(rq, p, SCX_ENQ_LAST, -1);
+ } else {
+--
+2.53.0
+
--- /dev/null
+From cc160a64fc58eca600ed8c19c2e6c514acdff58e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jun 2026 12:55:48 -1000
+Subject: sched_ext: Don't warn on core-sched forced idle in
+ put_prev_task_scx()
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit b7d9c359e5cf867f7eb23df3bb1c6b9e58af24da ]
+
+put_prev_task_scx() warns when a runnable task drops to a lower sched_class
+without SCX_OPS_ENQ_LAST, on the assumption that balance_one() would have
+kept it running. Core scheduling breaks that: a forced-idle SMT sibling
+reschedules through the core_pick fast path in pick_next_task(), which skips
+pick_task_scx() and thus balance_one(), so a runnable task can drop to idle
+with ENQ_LAST unset.
+
+Gate the warning on sched_cpu_cookie_match(): a cookie mismatch means core
+scheduling forced the idle, while a match (or core scheduling off) still
+catches a genuine missing-ENQ_LAST drop.
+
+Fixes: 7c65ae81ea86 ("sched_ext: Don't call put_prev_task_scx() before picking the next task")
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index d399494364c0a3..83baf270888882 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -2395,9 +2395,14 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
+ * sched_class, %SCX_OPS_ENQ_LAST must be set. Tell
+ * ops.enqueue() that @p is the only one available for this cpu,
+ * which should trigger an explicit follow-up scheduling event.
++ *
++ * Core scheduling can force this CPU idle while @p stays
++ * runnable. @p's cookie then won't match the core's, so skip
++ * the warning in that case.
+ */
+ if (next && sched_class_above(&ext_sched_class, next->sched_class)) {
+- WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_LAST));
++ WARN_ON_ONCE(sched_cpu_cookie_match(rq, p) &&
++ !(sch->ops.flags & SCX_OPS_ENQ_LAST));
+ do_enqueue_task(rq, p, SCX_ENQ_LAST, -1);
+ } else {
+ do_enqueue_task(rq, p, 0, -1);
+--
+2.53.0
+
--- /dev/null
+From 1ff88d3291818e5cf10ecea0d61d338f4ed2695e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 13:46:30 -0400
+Subject: scsi: core: wake eh reliably when using scsi_schedule_eh
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit dccf3b1798b70f94e958b3d00b83010399e6fb05 ]
+
+Drivers which use the scsi_schedule_eh function to run the error handler
+currently risk the error handler thread never waking once all commands are
+timed out or inactive. There is no enforced memory order between setting
+the host into error recovery state and counting busy commands. This can
+result in a race with scsi_dec_host_busy where neither CPU sees both
+conditions of all commands inactive and the host error state to request
+waking the error handler.
+
+To fix this, run the scsi_schedule_eh's scsi_eh_wakeup from a new work item
+which will use rcu to ensure scsi_schedule_eh's call to scsi_host_busy will
+occur after the error state is globally visible and will be seen by any
+current scsi_dec_host_busy callers.
+
+Fixes: 6eb045e092ef ("scsi: core: avoid host-wide host_busy counter for scsi_mq")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Link: https://patch.msgid.link/20260615174630.11492-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hosts.c | 2 ++
+ drivers/scsi/scsi_error.c | 22 +++++++++++++++++++++-
+ drivers/scsi/scsi_priv.h | 1 +
+ include/scsi/scsi_host.h | 3 +++
+ 4 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index 17173239301e61..a1055fe4922f64 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -343,6 +343,7 @@ static void scsi_host_dev_release(struct device *dev)
+ /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
+ rcu_barrier();
+
++ cancel_work_sync(&shost->eh_work);
+ if (shost->tmf_work_q)
+ destroy_workqueue(shost->tmf_work_q);
+ if (shost->ehandler)
+@@ -408,6 +409,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
+ INIT_LIST_HEAD(&shost->starved_list);
+ init_waitqueue_head(&shost->host_wait);
+ mutex_init(&shost->scan_mutex);
++ INIT_WORK(&shost->eh_work, scsi_rcu_eh_wakeup);
+
+ index = ida_alloc(&host_index_ida, GFP_KERNEL);
+ if (index < 0) {
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 2fd4ca96b3089d..13d46b6e0359e2 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -73,6 +73,26 @@ void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy)
+ }
+ }
+
++void scsi_rcu_eh_wakeup(struct work_struct *work)
++{
++ struct Scsi_Host *shost = container_of(work, struct Scsi_Host, eh_work);
++ unsigned long flags;
++ unsigned int busy;
++
++ /*
++ * Ensure any running scsi_dec_host_busy has completed its rcu section
++ * so changes to host state and host_eh_scheduled are visible to all
++ * future calls of scsi_dec_host_busy
++ */
++ synchronize_rcu();
++
++ busy = scsi_host_busy(shost);
++
++ spin_lock_irqsave(shost->host_lock, flags);
++ scsi_eh_wakeup(shost, busy);
++ spin_unlock_irqrestore(shost->host_lock, flags);
++}
++
+ /**
+ * scsi_schedule_eh - schedule EH for SCSI host
+ * @shost: SCSI host to invoke error handling on.
+@@ -88,7 +108,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
+ if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 ||
+ scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) {
+ shost->host_eh_scheduled++;
+- scsi_eh_wakeup(shost, scsi_host_busy(shost));
++ queue_work(shost->tmf_work_q, &shost->eh_work);
+ }
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
+index 5b2b19f5e8ec8a..68866b18a60058 100644
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -91,6 +91,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req);
+ extern int scsi_error_handler(void *host);
+ extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd);
+ extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy);
++extern void scsi_rcu_eh_wakeup(struct work_struct *work);
+ extern void scsi_eh_scmd_add(struct scsi_cmnd *);
+ void scsi_eh_ready_devs(struct Scsi_Host *shost,
+ struct list_head *work_q,
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index f5a24326123605..936403c15e53d3 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -714,6 +714,9 @@ struct Scsi_Host {
+ */
+ struct device *dma_dev;
+
++ /* Used for an rcu-synchronizing eh wakeup */
++ struct work_struct eh_work;
++
+ /* Delay for runtime autosuspend */
+ int rpm_autosuspend_delay;
+
+--
+2.53.0
+
--- /dev/null
+From d691c900016dba20728097018f0e72793251a8eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 2ae390219efdd3..4bbba29f7341ee 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -316,7 +316,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
--- /dev/null
+From dca872c32386ede5a6542d06907aedb185da24c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:27:36 +0530
+Subject: selftests/alsa: Fix memory leak in find_controls error path
+
+From: Malaya Kumar Rout <malayarout91@gmail.com>
+
+[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
+
+In find_controls(), card_data is allocated with malloc() but when
+snd_ctl_open_lconf() fails, the code jumps to next_card without
+freeing the allocated memory. This results in a memory leak for
+each card where snd_ctl_open_lconf() fails.
+
+Add free(card_data) before goto next_card to ensure proper cleanup
+of the allocated memory in the error path.
+
+Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
+Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
+Link: https://patch.msgid.link/20260704105736.94874-1-malayarout91@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/alsa/mixer-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
+index e113dafa5c2464..cfb7968fbac075 100644
+--- a/tools/testing/selftests/alsa/mixer-test.c
++++ b/tools/testing/selftests/alsa/mixer-test.c
+@@ -84,6 +84,7 @@ static void find_controls(void)
+ if (err < 0) {
+ ksft_print_msg("Failed to get hctl for card %d: %s\n",
+ card, snd_strerror(err));
++ free(card_data);
+ goto next_card;
+ }
+
+--
+2.53.0
+
input-ims-pcu-fix-heap-buffer-overflow-in-ims_pcu_pr.patch
input-ims-pcu-fix-logic-error-in-packet-reset.patch
fuse-fix-writeback-array-overflow-when-max_pages-is-.patch
+arm64-tegra-remove-fallback-compatible-for-gpcdma.patch
+arm64-tegra-fix-cpu-compatible-string-to-cortex-a78a.patch
+net-dropreason-add-skb_drop_reason_recursion_limit.patch
+net-plumb-drop-reasons-to-__dev_queue_xmit.patch
+xfrm-propagate-einprogress-from-validate_xmit_xfrm.patch
+xfrm-fix-stale-skb-prev-after-async-crypto-steals-a-.patch
+firmware-arm_ffa-respect-firmware-advertised-rx-tx-b.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+btrfs-use-bool-type-for-btrfs_path-members-used-as-b.patch
+btrfs-fallback-to-transaction-csum-tree-on-a-commit-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+sched-ext-avoid-null-ptr-traversal-when-put_prev_tas.patch
+sched_ext-don-t-warn-on-core-sched-forced-idle-in-pu.patch
+xfrm-reject-optional-iptfs-templates-in-outbound-pol.patch
+rdma-cma-fix-hardware-address-comparison-length-in-n.patch
+rdma-umem-add-pinned-revocable-dmabuf-import-interfa.patch
+rdma-irdma-prevent-rereg_mr-for-non-mem-regions.patch
+rdma-irdma-remove-redundant-legacy_mode-checks.patch
+rdma-irdma-prevent-user-triggered-null-deref-on-qp-c.patch
+rdma-erdma-initialize-ret-for-empty-receive-wr-lists.patch
+rdma-mana_ib-initialize-err-for-empty-send-wr-lists.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-publish-qp-after-initialization.patch
+mtd-fix-double-free-and-warn_on-in-add_mtd_device-er.patch
+selftests-alsa-fix-memory-leak-in-find_controls-erro.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm-clear-mode-callbacks-after-failed-mode-setup.patch
+xfrm-iptfs-propagate-skbfl_shared_frag-in-iptfs_skb_.patch
+xfrm6-clear-dst.dev-on-error-to-avoid-double-netdev_.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-cfg80211-fix-an-error-handling-path-in-cfg80211.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-mac80211-fix-unsol_bcast_probe_resp-double-free.patch
+wifi-mac80211-fix-fils_discovery-double-free-on-allo.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-mac80211-defer-link-rx-stats-percpu-free-to-rcu.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-cfg80211-convert-pmsr_free_wk-to-wiphy_work-to-.patch
+wifi-nl80211-free-rnr-data-on-mbssid-mismatch.patch
+wifi-cfg80211-derive-s1g-beacon-tsf-from-s1g-fields.patch
+wifi-nl80211-validate-nested-mbssid-ie-blobs.patch
+wifi-nl80211-constrain-mbssid-tx-link-id-range.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-avoid-non-s1g-aid-fallback-for-s1g-ass.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+firmware-arm_ffa-fix-out-of-bound-writes-in-ffa_setu.patch
+firmware-arm_ffa-fix-endpoint-memory-access-descript.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-amd-ps-disable-msi-on-resume-in-acp-pci-driver.patch
+asoc-amd-ps-fix-wrong-acp-version-string-in-pci_requ.patch
+asoc-amd-ps-replace-bitwise-or-with-logical-or-in-ir.patch
+asoc-cs42l43-correct-report-for-forced-microphone-ja.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+cpufreq-make-cpufreq_update_pressure-fall-back-to-cp.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+udmabuf-ensure-to-perform-cache-synchronisation-in-b.patch
+scsi-core-wake-eh-reliably-when-using-scsi_schedule_.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-use-platform_get_irq.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+accel-ivpu-fix-wrong-register-read-in-lnl-failure-di.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+bluetooth-mgmt-revalidate-load_conn_param-queued-upd.patch
+bluetooth-hci_sync-extend-conn_hash-lookup-critical-.patch
+bluetooth-mgmt-fix-locking-in-unpair_device-disconne.patch
+bluetooth-mgmt-hold-reference-for-hci_conn-in-mgmt_p.patch
+bluetooth-hci_qca-clear-memdump-state-on-invalid-dum.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+riscv-enable-kernel-access-to-shadow-stack-memory-vi.patch
+riscv-export-kaslr-offset-and-satp-in-vmcoreinfo-elf.patch
+riscv-remove-support-for-xip-kernel.patch
+riscv-gate-function_alignment_4b-on-dynamic_ftrace.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+can-raw-add-locking-for-raw-flags-bitfield.patch
+powerpc-85xx-add-fsl-ifc-to-common-device-ids.patch
+powerpc-time-prepare-to-stop-elapsing-in-dynticks-id.patch
+powerpc-vtime-initialize-starttime-at-boot-for-nativ.patch
+bpf-sockmap-reject-unhashed-udp-sockets-on-sockmap-u.patch
+drm-panthor-check-debugfs-gem-lock-initialization.patch
+s390-checksum-fix-csum_partial-without-vector-facili.patch
+riscv-hwprobe-avoid-uninitialized-read-in-hwprobe_ge.patch
+can-j1939-fix-lockless-local-destination-check.patch
+drm-xe-allow-the-caller-to-pass-guc_buf_cache-size.patch
+drm-xe-sa-shadow-buffer-support-in-the-sub-allocator.patch
+drm-xe-vf-shadow-buffer-management-for-ccs-read-writ.patch
+drm-xe-vf-fix-vf-ccs-attach-detach-race-with-in-flig.patch
+drm-xe-wopcm-fix-wopcm-size-for-lnl.patch
+ksmbd-pin-conn-during-async-oplock-break-notificatio.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-wm-clear-the-plane-ddb_y-entries-on-plane-d.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+accel-amdxdna-fix-use-after-free-of-mm_struct-in-job.patch
+tcp-fix-time_wait-socket-reference-leak-on-psp-polic.patch
+dpll-fix-null-pointer-dereference-in-dpll_msg_add_pi.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From 858f8c41f18865f7a79fdf9353d296b976abe900 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 786a7e963f1ff4..5bbe98dc0529b9 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3546,6 +3546,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3582,13 +3583,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3605,11 +3614,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 47031beac7caa02b94056aea285f72ad21da5d5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 18:13:17 +0000
+Subject: tcp: fix TIME_WAIT socket reference leak on PSP policy failure
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2c1931a81122c3cdc4c89448fe0442c69e21c0d5 ]
+
+Release the TIME_WAIT socket reference and jump to discard_it
+upon PSP policy failure in both IPv4 and IPv6 receive paths.
+This prevents a memory leak of tcp_tw_bucket structures.
+
+Fixes: 659a2899a57d ("tcp: add datapath logic for PSP with inline key exchange")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
+Link: https://patch.msgid.link/20260710181317.4060230-1-edumazet@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_ipv4.c | 6 ++++--
+ net/ipv6/tcp_ipv6.c | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index f0106c2be1cf23..a1ed4fa264836d 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -2452,8 +2452,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
+ }
+
+ drop_reason = psp_twsk_rx_policy_check(inet_twsk(sk), skb);
+- if (drop_reason)
+- break;
++ if (drop_reason) {
++ inet_twsk_put(inet_twsk(sk));
++ goto discard_it;
++ }
+ }
+ /* to ACK */
+ fallthrough;
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 59b5900dd42bd6..ad9f69d49f2e3d 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1984,8 +1984,10 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+ }
+
+ drop_reason = psp_twsk_rx_policy_check(inet_twsk(sk), skb);
+- if (drop_reason)
+- break;
++ if (drop_reason) {
++ inet_twsk_put(inet_twsk(sk));
++ goto discard_it;
++ }
+ }
+ /* to ACK */
+ fallthrough;
+--
+2.53.0
+
--- /dev/null
+From eddc2266bc4c0b8221f4d2b3d504b9903fa1c8d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 12:57:25 +0200
+Subject: udmabuf: Ensure to perform cache synchronisation in
+ begin_cpu_udmabuf()
+
+From: Robert Mader <robert.mader@collabora.com>
+
+[ Upstream commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 ]
+
+The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to
+fix cacheline EEXIST warning") says:
+
+> The CPU sync at map/unmap time is also redundant for udmabuf:
+> begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit
+> cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU
+> access is requested through the dma-buf interface.
+
+This, however, does not apply to the first time begin_cpu_udmabuf() is
+called on an udmabuf, in which case the implementation previously relied on
+get_sg_table() to perform the cache synchronisation.
+
+Ensure to call dma_sync_sgtable_for_cpu() in that case as well.
+
+Fixes: 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning")
+Signed-off-by: Robert Mader <robert.mader@collabora.com>
+Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
+Link: https://patch.msgid.link/20260627105725.9083-1-robert.mader@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma-buf/udmabuf.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index be47d1ff6c508b..30b0f0c72e928c 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -249,21 +249,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
+ {
+ struct udmabuf *ubuf = buf->priv;
+ struct device *dev = ubuf->device->this_device;
+- int ret = 0;
+
+ if (!ubuf->sg) {
+ ubuf->sg = get_sg_table(dev, buf, direction);
+ if (IS_ERR(ubuf->sg)) {
++ int ret;
++
+ ret = PTR_ERR(ubuf->sg);
+ ubuf->sg = NULL;
++ return ret;
+ } else {
+ ubuf->sg_dir = direction;
+ }
+- } else {
+- dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
+ }
+
+- return ret;
++ dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
++ return 0;
+ }
+
+ static int end_cpu_udmabuf(struct dma_buf *buf,
+--
+2.53.0
+
--- /dev/null
+From 87467d11d656e2b12af6f971b6b9a243bcf713fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index a0e88dbaaebe67..9ab62a2667c7b6 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4465,6 +4465,7 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4479,7 +4480,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From c5d19719dae4fff34ae3dcf48f518c5063431a4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index af1e2ce1628dae..11f7a27bb7046c 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -205,7 +205,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 217b282593ec1d1e345374e3c6cc4a8f563c6cb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 6b204ca91a140b..34b76479f888bf 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1195,6 +1195,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From cb25d64896bb51dbad8a252ecaadd06b8cf401bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:55:23 +0530
+Subject: wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock
+
+From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+
+[ Upstream commit 2b0eab425e1f658d8fe1df7590e3b9af5959505e ]
+
+When a netlink socket that owns a PMSR session is closed,
+cfg80211_release_pmsr() clears the request's nl_portid and queues
+pmsr_free_wk to call cfg80211_pmsr_process_abort() asynchronously.
+
+If the interface tears down concurrently, cfg80211_pmsr_wdev_down()
+is called under wiphy_lock and calls cancel_work_sync(&pmsr_free_wk)
+to wait for any running work. The work function acquires wiphy_lock
+via guard(wiphy) before calling process_abort.
+
+This is a deadlock: wdev_down holds wiphy_lock and blocks inside
+cancel_work_sync(); pmsr_free_wk blocks trying to acquire that same
+wiphy_lock. Neither thread can proceed.
+
+The same deadlock is reachable from cfg80211_leave_locked(), which
+calls cfg80211_pmsr_wdev_down() for all interface types under
+wiphy_lock.
+
+Fix this by converting pmsr_free_wk from a plain work_struct to a
+wiphy_work. The wiphy_work dispatcher holds wiphy_lock when running
+work items, so the explicit guard(wiphy) in the work function is no
+longer needed. wiphy_work_cancel() can be called safely while holding
+wiphy_lock - since wiphy_lock prevents the work from running
+concurrently, wiphy_work_cancel() never blocks, eliminating the
+deadlock.
+
+Remove the cancel_work_sync() for pmsr_free_wk from the
+NETDEV_GOING_DOWN handler. cfg80211_leave(), called unconditionally
+just before it, already cancels any pending work under wiphy_lock
+via wiphy_work_cancel() inside cfg80211_pmsr_wdev_down().
+
+Fixes: 6dccbc9f3e1d ("wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down")
+Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260703082523.2629324-1-peddolla.reddy@oss.qualcomm.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 2 +-
+ net/wireless/core.c | 3 +--
+ net/wireless/core.h | 2 +-
+ net/wireless/pmsr.c | 8 +++-----
+ 4 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 820e299f06b5ee..1509be85139ecf 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6740,7 +6740,7 @@ struct wireless_dev {
+
+ struct list_head pmsr_list;
+ spinlock_t pmsr_lock;
+- struct work_struct pmsr_free_wk;
++ struct wiphy_work pmsr_free_wk;
+
+ unsigned long unprot_beacon_reported;
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 34b76479f888bf..efbf7b3046342e 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1444,7 +1444,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
+ INIT_LIST_HEAD(&wdev->mgmt_registrations);
+ INIT_LIST_HEAD(&wdev->pmsr_list);
+ spin_lock_init(&wdev->pmsr_lock);
+- INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
++ wiphy_work_init(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
+
+ #ifdef CONFIG_CFG80211_WEXT
+ wdev->wext.default_key = -1;
+@@ -1579,7 +1579,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ }
+ /* since we just did cfg80211_leave() nothing to do there */
+ cancel_work_sync(&wdev->disconnect_wk);
+- cancel_work_sync(&wdev->pmsr_free_wk);
+ break;
+ case NETDEV_DOWN:
+ wiphy_lock(&rdev->wiphy);
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index d5d78752227af9..9bfd39af1742e1 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -566,7 +566,7 @@ cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len);
+
+ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
+ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
+-void cfg80211_pmsr_free_wk(struct work_struct *work);
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work);
+
+ void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
+ void cfg80211_remove_links(struct wireless_dev *wdev);
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 13801cf35e9fca..d2546c27879fa4 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -625,13 +625,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
+ }
+ }
+
+-void cfg80211_pmsr_free_wk(struct work_struct *work)
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work)
+ {
+ struct wireless_dev *wdev = container_of(work, struct wireless_dev,
+ pmsr_free_wk);
+
+- guard(wiphy)(wdev->wiphy);
+-
+ cfg80211_pmsr_process_abort(wdev);
+ }
+
+@@ -647,7 +645,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+
+- cancel_work_sync(&wdev->pmsr_free_wk);
++ wiphy_work_cancel(wdev->wiphy, &wdev->pmsr_free_wk);
+ if (found)
+ cfg80211_pmsr_process_abort(wdev);
+
+@@ -662,7 +660,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
+ list_for_each_entry(req, &wdev->pmsr_list, list) {
+ if (req->nl_portid == portid) {
+ req->nl_portid = 0;
+- schedule_work(&wdev->pmsr_free_wk);
++ wiphy_work_queue(wdev->wiphy, &wdev->pmsr_free_wk);
+ }
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+--
+2.53.0
+
--- /dev/null
+From e58aa203d89963bb3a37816299f3ab4b8abe0eca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 00:19:46 +0800
+Subject: wifi: cfg80211: derive S1G beacon TSF from S1G fields
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 4e5a4641e7b4763656336b7891d01359aaf363cd ]
+
+cfg80211_inform_bss_frame_data() parses S1G beacons with the extension
+frame layout, but still reads the TSF from the regular probe response
+layout after the S1G branch. For S1G beacons that reads bytes at the
+regular management-frame timestamp offset instead of the S1G timestamp.
+
+Use the 32-bit S1G beacon timestamp and the S1G Beacon Compatibility
+element's TSF completion field when informing an S1G BSS. Keep the
+regular management-frame timestamp read in the non-S1G branch.
+
+Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Tested-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Reviewed-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Link: https://patch.msgid.link/20260611161943.91069-6-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 27d5f99dbb2289..af1e2ce1628dae 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3326,14 +3326,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ bssid = ext->u.s1g_beacon.sa;
+ capability = le16_to_cpu(compat->compat_info);
+ beacon_interval = le16_to_cpu(compat->beacon_int);
++ tsf = le32_to_cpu(ext->u.s1g_beacon.timestamp);
++ tsf |= (u64)le32_to_cpu(compat->tsf_completion) << 32;
+ } else {
+ bssid = mgmt->bssid;
+ beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
+ capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
++ tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+ }
+
+- tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+-
+ if (ieee80211_is_probe_resp(mgmt->frame_control))
+ ftype = CFG80211_BSS_FTYPE_PRESP;
+ else if (ext)
+--
+2.53.0
+
--- /dev/null
+From 06ccde9e54ccfe49ed663639f90063c207d034c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:48:56 +0200
+Subject: wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit c6659f66d4ee4841aafae5659d2ef5e4c5c63cb6 ]
+
+If the test against IEEE80211_MAX_SSID_LEN fails, then 'creq' leaks.
+Use the existing error handling path to fix it.
+
+Fixes: 2a5193119269 ("cfg80211/nl80211: scanning (and mac80211 update to use it)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://patch.msgid.link/a1be7eea4da0da18f90589af252bb76a18a61978.1781984889.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 2f2104bb0d52ff..27d5f99dbb2289 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3627,8 +3627,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+ /* translate "Scan for SSID" request */
+ if (wreq) {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+- if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
+- return -EINVAL;
++ if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
++ err = -EINVAL;
++ goto out;
++ }
+ memcpy(creq->req.ssids[0].ssid, wreq->essid,
+ wreq->essid_len);
+ creq->req.ssids[0].ssid_len = wreq->essid_len;
+--
+2.53.0
+
--- /dev/null
+From 829c68ca26346639aa1a707b25f54604d4886c93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index fd14a3c2eab45b..06563f60848705 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From 5f0d9677a99c4fc6f298ec9e3e3a7e669d3a7eda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 237e5d7eeb47c3..776dcf8835d715 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -347,7 +347,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From b2abf7c1394e2fd8fa1c1b3060310142d393d5b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index d2546c27879fa4..fd14a3c2eab45b 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -196,6 +196,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -248,6 +249,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -257,10 +266,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From fb8b855b52b8b224a2bed6bf8fb93996a5cb0eb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 215814861cbda5..0808e69c3c1786 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6162,6 +6162,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6174,16 +6176,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From 09b2b0cf2bfe5f18db155c09a1696dd3bac39364 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From be5d1a130db68d8c0d2aeef1c4ec6631df006095 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 23:24:41 +0800
+Subject: wifi: mac80211: avoid non-S1G AID fallback for S1G assoc
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 035ed430ce6a2c35b01e211844a9f0a7643e57a4 ]
+
+When assoc_data->s1g is set and no AID Response element is present,
+falling back to mgmt->u.assoc_resp.aid reads the non-S1G
+association-response layout.
+
+Keep the fallback for non-S1G only. If a successful S1G association
+response omits the AID Response element, abandon the association
+instead of proceeding with AID 0. Initialize aid to 0 for other S1G
+responses so the later mask and logging flow keeps a defined value
+without reading the non-S1G layout.
+
+Fixes: 2a8a6b7c4cb0 ("wifi: mac80211: handle station association response with S1G")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612152440.25955-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/mlme.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 8854e47b056721..9ec4125c06d193 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -6476,7 +6476,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ {
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
+- u16 capab_info, status_code, aid;
++ u16 capab_info, status_code, aid = 0;
+ struct ieee80211_elems_parse_params parse_params = {
+ .bss = NULL,
+ .link_id = -1,
+@@ -6553,8 +6553,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+
+ if (elems->aid_resp)
+ aid = le16_to_cpu(elems->aid_resp->aid);
+- else
++ else if (!assoc_data->s1g)
+ aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
++ else if (status_code == WLAN_STATUS_SUCCESS)
++ goto abandon_assoc;
+
+ /*
+ * The 5 MSB of the AID field are reserved for a non-S1G STA. For
+--
+2.53.0
+
--- /dev/null
+From 317659041812361a2ed34cfde85999d92ffbdb90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 16:30:28 +0800
+Subject: wifi: mac80211: defer link RX stats percpu free to RCU
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+[ Upstream commit aa2eb62525188269cdd402a583b9a8ed94657ff0 ]
+
+sta_remove_link() frees a removed MLO link's RX stats percpu buffer right
+away, but defers only the link container to RCU:
+
+ sta_info_free_link(&alloc->info);
+ kfree_rcu(alloc, rcu_head);
+
+The RX fast path reads link_sta under rcu_read_lock and writes the percpu
+stats. A reader that resolved link_sta before the removal keeps the
+pointer. The container stays alive from the kfree_rcu, so the read still
+works. But the percpu block it points to is already freed. This needs
+uses_rss. That is when pcpu_rx_stats exists.
+
+The full STA teardown frees the deflink stats only after
+synchronize_net(). The link removal path had no such barrier. The race is
+hard to win in practice, but the free should still wait for RCU.
+
+Free the link together with its data from a single RCU callback, so the
+percpu block is reclaimed only after readers drain.
+
+Fixes: c71420db653a ("wifi: mac80211: RCU-ify link STA pointers")
+Link: https://lore.kernel.org/r/20260626080158.3589711-1-maoyixie.tju@gmail.com
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
+Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Link: https://patch.msgid.link/20260627083028.3826810-1-maoyixie.tju@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/sta_info.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index b0d9bb830f2931..54a6b20a4c5cd5 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -355,6 +355,15 @@ static void sta_info_free_link(struct link_sta_info *link_sta)
+ free_percpu(link_sta->pcpu_rx_stats);
+ }
+
++static void sta_link_free_rcu(struct rcu_head *head)
++{
++ struct sta_link_alloc *alloc =
++ container_of(head, struct sta_link_alloc, rcu_head);
++
++ sta_info_free_link(&alloc->info);
++ kfree(alloc);
++}
++
+ static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id)
+ {
+ struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy,
+@@ -427,10 +436,8 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
+
+ RCU_INIT_POINTER(sta->link[link_id], NULL);
+ RCU_INIT_POINTER(sta->sta.link[link_id], NULL);
+- if (alloc) {
+- sta_info_free_link(&alloc->info);
+- kfree_rcu(alloc, rcu_head);
+- }
++ if (alloc)
++ call_rcu(&alloc->rcu_head, sta_link_free_rcu);
+
+ ieee80211_sta_recalc_aggregates(&sta->sta);
+ }
+--
+2.53.0
+
--- /dev/null
+From fcc90eefedcfe83fa5f7b5bd862a2616f91a1992 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:32 -0700
+Subject: wifi: mac80211: fix fils_discovery double free on alloc failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 286e52a799fa158bdbd77da1426c4d93f9a6e7ad ]
+
+ieee80211_set_fils_discovery() calls kfree_rcu() on the old template
+before allocating the replacement. If the kzalloc() then fails, it
+returns -ENOMEM while link->u.ap.fils_discovery still points at the
+object already queued for freeing. A later update or AP teardown
+(ieee80211_stop_ap()) re-queues that same rcu_head; the second free is
+caught by KASAN when the RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800c065280 by task swapper/0/0
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-96 of size 96
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-2-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 001e4bb55b6199..f6232948bc0f4a 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1124,9 +1124,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ fd->max_interval = params->max_interval;
+
+ old = sdata_dereference(link->u.ap.fils_discovery, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+-
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+ if (!new)
+@@ -1138,6 +1135,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_FILS_DISCOVERY;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From f16702730b4c70a69ab47966e27885c5d91379b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:31 -0700
+Subject: wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc
+ failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 1d067abcd37062426c59ec73dbc4e87a63f33fea ]
+
+ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old
+template before allocating the replacement. If the kzalloc() then fails,
+it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points
+at the object already queued for freeing. A later update or AP teardown
+re-queues that same rcu_head; the second free is caught by KASAN when the
+RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800d06f300 by task exploit/145
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-128 of size 128
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index d32eacbb7517d7..001e4bb55b6199 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1157,8 +1157,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ link_conf->unsol_bcast_probe_resp_interval = params->interval;
+
+ old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+@@ -1171,6 +1169,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 0961e2844b4de1174fe918becdbe1c0dda0721c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 72c129478da088..499126317a914c 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -581,6 +581,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -588,10 +589,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From adb861c677b9ed82b74afead6239a4aac0d6fe13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index 20815fdc9d3764..a0724e1c530709 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -6898,6 +6898,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From da859bdc32bb3e2c76d0d2c6330c47e9e91c4e7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:56 +0800
+Subject: wifi: nl80211: constrain MBSSID TX link ID range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 172f06023669f0a96d32511669ff45c600731380 ]
+
+MBSSID transmitted-profile link IDs are valid only in the range
+0..IEEE80211_MLD_MAX_NUM_LINKS - 1. Constrain the nl80211 policy to
+reject out-of-range values during attribute validation.
+
+Fixes: 37523c3c47b3 ("wifi: nl80211: add link id of transmitted profile for MLO MBSSID")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-4-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 5583edf4852775..237e5d7eeb47c3 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -501,7 +501,7 @@ nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
+ [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
+ [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
+ [NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID] =
+- NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS),
++ NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1),
+ };
+
+ static const struct nla_policy
+--
+2.53.0
+
--- /dev/null
+From 303f1846a7ff8f35a0ec458add0544b8b0c6d8da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 19:22:09 +0800
+Subject: wifi: nl80211: free RNR data on MBSSID mismatch
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
+
+nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR
+entries than MBSSID entries.
+
+The rejected RNR allocation has not been attached to the beacon data yet,
+so free it before returning the error.
+
+Fixes: dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260610112208.1308-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 6e41a4269e1c57..e765c992eb20e4 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6232,8 +6232,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (IS_ERR(rnr))
+ return PTR_ERR(rnr);
+
+- if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
++ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
++ kfree(rnr);
+ return -EINVAL;
++ }
+
+ bcn->rnr_ies = rnr;
+ }
+--
+2.53.0
+
--- /dev/null
+From 4299bd357c046b0e694f77f11986ba38128209ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:55 +0800
+Subject: wifi: nl80211: validate nested MBSSID IE blobs
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
+
+Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed
+information-element stream before storing it for beacon construction.
+
+RNR parsing already validates each nested blob with validate_ie_attr()
+before storing it. Apply the same syntactic IE validation to MBSSID
+entries before counting and copying their data and length pointers.
+
+Fixes: dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-3-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index e765c992eb20e4..5583edf4852775 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6034,7 +6034,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
+ }
+
+ static struct cfg80211_mbssid_elems *
+-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
++nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
++ struct netlink_ext_ack *extack)
+ {
+ struct nlattr *nl_elems;
+ struct cfg80211_mbssid_elems *elems;
+@@ -6045,6 +6046,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+ return ERR_PTR(-EINVAL);
+
+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
++ int ret;
++
++ ret = validate_ie_attr(nl_elems, extack);
++ if (ret)
++ return ERR_PTR(ret);
++
+ if (num_elems >= 255)
+ return ERR_PTR(-EINVAL);
+ num_elems++;
+@@ -6216,7 +6223,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
+ struct cfg80211_mbssid_elems *mbssid =
+ nl80211_parse_mbssid_elems(&rdev->wiphy,
+- attrs[NL80211_ATTR_MBSSID_ELEMS]);
++ attrs[NL80211_ATTR_MBSSID_ELEMS],
++ extack);
+
+ if (IS_ERR(mbssid))
+ return PTR_ERR(mbssid);
+--
+2.53.0
+
--- /dev/null
+From 15c6bc3621a82ef7774c11e775080282a8a4ed4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 1294a1d6528e2c..9f491334c8d043 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 1cbf50199d1e9e0975575046587ee703c963bac7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 11:01:17 +0800
+Subject: xfrm: clear mode callbacks after failed mode setup
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 2538bd3cd1ff5af655908469544ac7b7ae259386 ]
+
+xfrm_state_gc_task can run long after a failed IPTFS state setup. In the
+reproduced case, __xfrm_init_state() cached x->mode_cbs, IPTFS setup
+returned -ENOMEM before publishing mode_data, and the temporary module
+reference from xfrm_get_mode_cbs() was dropped immediately. The dead state
+then kept x->mode_cbs until deferred GC ran after xfrm_iptfs had been
+unloaded.
+
+Clear x->mode_cbs when mode init or clone fails before publishing
+mode_data. Those states never installed mode-specific state or the
+long-term IPTFS module pin, so deferred GC has nothing mode-specific to
+destroy and must not retain a callback table pointer past the temporary
+lookup reference.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+failed setup path:
+1. cache x->mode_cbs
+2. mode setup fails before mode_data
+3. drop the temporary module ref
+4. dead state keeps x->mode_cbs cached
+
+GC/unload path:
+1. xfrm_state_put() queues GC work
+2. xfrm_iptfs unloads later
+3. xfrm_state_gc_task runs
+4. GC dereferences stale x->mode_cbs
+
+This also covers the failed clone path where clone_state() returns before
+publishing mode_data.
+
+Validation reproduced this kernel report:
+Kernel panic - not syncing: Fatal exception
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+failslab_stacktrace_filter matched xfrm_iptfs frames
+ack_error=-12
+FAULT_INJECTION: forcing a failure
+BUG: unable to handle page fault
+Workqueue: events xfrm_state_gc_task
+RIP: xfrm_state_gc_task+0x142/0x650
+Modules linked in: esp4_offload xfrm_user [last unloaded: xfrm_iptfs]
+Kernel panic - not syncing: Fatal exception
+
+Fixes: 4b3faf610cc6 ("xfrm: iptfs: add new iptfs xfrm mode impl")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 89daad5db10c9d..b9049c2297bd5a 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2070,8 +2070,11 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
+
+ x->mode_cbs = orig->mode_cbs;
+ if (x->mode_cbs && x->mode_cbs->clone_state) {
+- if (x->mode_cbs->clone_state(x, orig))
++ if (x->mode_cbs->clone_state(x, orig)) {
++ if (!x->mode_data)
++ x->mode_cbs = NULL;
+ goto error;
++ }
+ }
+
+
+@@ -3253,6 +3256,8 @@ int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
+ if (x->mode_cbs->init_state)
+ err = x->mode_cbs->init_state(x);
+ module_put(x->mode_cbs->owner);
++ if (err && !x->mode_data)
++ x->mode_cbs = NULL;
+ }
+ error:
+ return err;
+--
+2.53.0
+
--- /dev/null
+From 29d89ce66ca226883dede338eafe4fe9709dbd25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 12:03:27 +0200
+Subject: xfrm: fix stale skb->prev after async crypto steals a GSO segment
+
+From: Petr Wozniak <petr.wozniak@gmail.com>
+
+[ Upstream commit 3f4c3919baf0944ad96580467c302bc6c7758b00 ]
+
+skb_gso_segment() leaves the segment list head with ->prev pointing at
+the last segment, an invariant validate_xmit_skb_list() relies on when
+it sets its tail pointer (tail = skb->prev).
+
+When validate_xmit_xfrm() walks a GSO list and some segments are stolen
+by async crypto (->xmit() returns -EINPROGRESS), those segments are
+unlinked from the list but the head ->prev is never updated. If the
+last segment is the one stolen, the returned head still has ->prev
+pointing at it, even though it is now owned by the crypto engine and may
+be freed. validate_xmit_skb_list() later does tail->next = skb, writing
+through that stale pointer -- a use-after-free.
+
+Repoint skb->prev at the last retained segment before returning.
+
+Fixes: f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_device.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 8b526e3676389a..4719aba331cd66 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -224,6 +224,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ pskb = skb2;
+ }
+
++ /* skb_gso_segment() set skb->prev to the last segment, but async
++ * crypto may have stolen it above without updating ->prev. Repoint
++ * it at the last retained segment so validate_xmit_skb_list() does
++ * not chain onto a segment now owned by the crypto engine.
++ */
++ if (skb)
++ skb->prev = pskb;
++
+ return skb ? skb : ERR_PTR(-EINPROGRESS);
+ }
+ EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
+--
+2.53.0
+
--- /dev/null
+From b944177ffcca7a2571dc0b92bf7d1d4bf84d185d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 11:31:52 +0800
+Subject: xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
+
+From: Chen YanJun <moomichen@tencent.com>
+
+[ Upstream commit 430ea57d6daf765e88f90046afbfd1e071cb7200 ]
+
+When iptfs_skb_add_frags() copies frag references from the source
+frag walk into a new SKB, it increments the page reference count via
+__skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the
+destination SKB's skb_shinfo->flags.
+
+If the source SKB carries shared frags (e.g. from a page-pool backed
+receive path), the new inner SKB will appear to ESP as having privately
+owned frags. A subsequent esp_input() call for a nested transport-mode
+SA then takes the no-COW fast path and decrypts in place, writing over
+pages that are still referenced by the outer IPTFS SKB. This causes
+kernel-visible memory corruption and can trigger a panic.
+
+All other frag-transfer helpers in the kernel (skb_try_coalesce,
+skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly
+propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this
+convention by setting the flag inside the loop immediately after
+__skb_frag_ref() and nr_frags++, so every exit path that attaches a frag
+unconditionally propagates SKBFL_SHARED_FRAG.
+
+Fixes: 5f2b6a909574 ("xfrm: iptfs: add skb-fragment sharing code")
+Signed-off-by: Chen YanJun <moomichen@tencent.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_iptfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c
+index fe8e4f21b32819..d39253b06c4efd 100644
+--- a/net/xfrm/xfrm_iptfs.c
++++ b/net/xfrm/xfrm_iptfs.c
+@@ -480,6 +480,7 @@ static int iptfs_skb_add_frags(struct sk_buff *skb,
+ }
+ __skb_frag_ref(tofrag);
+ shinfo->nr_frags++;
++ shinfo->flags |= SKBFL_SHARED_FRAG;
+
+ /* see if we are done */
+ fraglen = tofrag->len;
+--
+2.53.0
+
--- /dev/null
+From 00e79f8efe45f129ecc6bcab9e29dfea73ef0b17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 4dad1f8172286a..25f9cbd3ce6a4f 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1329,8 +1329,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 369d2e389cd5a90eae6df7f2ab42f639aa0b8f56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 12:03:26 +0200
+Subject: xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()
+
+From: Petr Wozniak <petr.wozniak@gmail.com>
+
+[ Upstream commit 6860b467f569f732b11cbc588ae7e195e90e7e23 ]
+
+validate_xmit_xfrm() returns NULL both when a packet is dropped and
+when it is stolen by async crypto (-EINPROGRESS from ->xmit()).
+Callers cannot distinguish the two cases.
+
+f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+changed the semantics of a NULL return from "dropped" to "stolen or
+dropped", but __dev_queue_xmit() was not updated. On virtual/bridge
+interfaces (noqueue qdisc) __dev_queue_xmit() initialises rc=-ENOMEM
+and jumps to out: when skb is NULL, returning -ENOMEM to the caller
+even though the packet will be delivered correctly via xfrm_dev_resume().
+
+Return ERR_PTR(-EINPROGRESS) from validate_xmit_xfrm() for the async
+case so callers can tell it apart from a real drop. Update
+__dev_queue_xmit() to handle ERR_PTR(-EINPROGRESS) from
+validate_xmit_skb() correctly. Update validate_xmit_skb_list() to
+use IS_ERR_OR_NULL() so that ERR_PTR(-EINPROGRESS) is not mistakenly
+added to the transmitted list.
+
+Fixes: f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 10 ++++++++--
+ net/xfrm/xfrm_device.c | 4 ++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 246d654551ae56..a83083e8761b1b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4005,6 +4005,9 @@ static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb,
+ return NULL;
+ }
+
++/* Returns the skb on success, NULL if dropped, or ERR_PTR(-EINPROGRESS)
++ * if stolen by async xfrm crypto (delivered via xfrm_dev_resume()).
++ */
+ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev, bool *again)
+ {
+ netdev_features_t features;
+@@ -4076,7 +4079,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d
+ skb->prev = skb;
+
+ skb = validate_xmit_skb(skb, dev, again);
+- if (!skb)
++ if (IS_ERR_OR_NULL(skb))
+ continue;
+
+ if (!head)
+@@ -4788,8 +4791,11 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
+ goto recursion_alert;
+
+ skb = validate_xmit_skb(skb, dev, &again);
+- if (!skb)
++ if (IS_ERR_OR_NULL(skb)) {
++ if (PTR_ERR(skb) == -EINPROGRESS)
++ rc = NET_XMIT_SUCCESS;
+ goto out;
++ }
+
+ HARD_TX_LOCK(dev, txq, cpu);
+
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 550457e4c4f01d..8b526e3676389a 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -182,7 +182,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ err = x->type_offload->xmit(x, skb, esp_features);
+ if (err) {
+ if (err == -EINPROGRESS)
+- return NULL;
++ return ERR_PTR(-EINPROGRESS);
+
+ XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
+ kfree_skb(skb);
+@@ -224,7 +224,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ pskb = skb2;
+ }
+
+- return skb;
++ return skb ? skb : ERR_PTR(-EINPROGRESS);
+ }
+ EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
+
+--
+2.53.0
+
--- /dev/null
+From be31820820c21ea4fb8c646223eb4bf6268babd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 10:23:43 +0200
+Subject: xfrm: reject optional IPTFS templates in outbound policies
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit ea528f18231ec0f33317be57f8866913b19aba6e ]
+
+syzbot reported a stack-out-of-bounds read in xfrm_state_find()
+which flows from xfrm_tmpl_resolve_one().
+
+Commit 3d776e31c841 ("xfrm: Reject optional tunnel/BEET mode
+templates in outbound policies") disallowed optional tunnel and
+BEET in outbound policies to prevent this. Later when IPTFS
+added, it was not covered by that fix and can still trigger
+the out-of-bounds read;
+
+Extend the check to disallow optional IPTFS in outbound policies
+as well. IPTFS should be identical to tunnel mode.
+IN and FWD policies are not affected: xfrm_tmpl_resolve_one()
+is only reachable via the outbound path.
+
+Reproducer, before:
+
+ip link add dummy0 type dummy
+ip link set dummy0 up
+ip addr add 10.1.1.1/24 dev dummy0
+ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl
+ src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs
+ level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid
+ 2 mode transport
+ping -W 1 -c 1 10.1.1.2
+PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
+
+[ 64.168420] ==================================================================
+[ 64.169977] BUG: KASAN: stack-out-of-bounds in __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] Read of size 4 at addr ffff88800e1ffd20 by task ping/2844
+
+[ 64.169977] CPU: 2 UID: 0 PID: 2844 Comm: ping Not tainted 7.1.0-rc7-00180-geb23b588430a #98 PREEMPT(full)
+[ 64.169977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 64.169977] Call Trace:
+[ 64.169977] <TASK>
+[ 64.169977] dump_stack_lvl+0x47/0x70
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] print_report+0x152/0x4b0
+[ 64.169977] ? ksys_mmap_pgoff+0x6d/0xa0
+[ 64.169977] ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
+[ 64.169977] ? __virt_addr_valid+0x21b/0x230
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] kasan_report+0xa8/0xd0
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] __xfrm_dst_hash+0x24/0xc0
+[ 64.169977] xfrm_state_find+0xa2d/0x2f90
+[ 64.169977] ? __pfx_xfrm_state_find+0x10/0x10
+[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
+[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
+[ 64.169977] xfrm_tmpl_resolve_one+0x210/0x570
+[ 64.169977] ? __pfx_xfrm_tmpl_resolve_one+0x10/0x10
+[ 64.169977] ? __pfx_stack_trace_consume_entry+0x10/0x10
+[ 64.169977] ? kernel_text_address+0x5b/0x80
+[ 64.169977] ? __kernel_text_address+0xe/0x30
+[ 64.169977] ? unwind_get_return_address+0x5e/0x90
+[ 64.169977] ? arch_stack_walk+0x8c/0xe0
+[ 64.169977] xfrm_tmpl_resolve+0x130/0x200
+[ 64.169977] ? __pfx_xfrm_tmpl_resolve+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_inexact_lookup_rcu+0x10/0x10
+[ 64.169977] ? __refcount_add_not_zero.constprop.0+0xb2/0x110
+[ 64.169977] ? __pfx___refcount_add_not_zero.constprop.0+0x10/0x10
+[ 64.169977] xfrm_resolve_and_create_bundle+0xd5/0x310
+[ 64.169977] ? __pfx_xfrm_resolve_and_create_bundle+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
+[ 64.169977] xfrm_lookup_with_ifid+0x3d8/0xb80
+[ 64.169977] ? __pfx_xfrm_lookup_with_ifid+0x10/0x10
+[ 64.169977] ? ip_route_output_key_hash+0xc6/0x110
+[ 64.169977] ? kasan_save_track+0x10/0x30
+[ 64.169977] xfrm_lookup_route+0x18/0xe0
+[ 64.169977] ip4_datagram_release_cb+0x4c9/0x530
+[ 64.169977] ? __pfx_ip4_datagram_release_cb+0x10/0x10
+[ 64.169977] ? do_raw_spin_lock+0x71/0xc0
+[ 64.169977] ? __pfx_do_raw_spin_lock+0x10/0x10
+[ 64.169977] release_sock+0xb0/0x170
+[ 64.169977] udp_connect+0x43/0x50
+[ 64.169977] __sys_connect+0xa6/0x100
+[ 64.169977] ? alloc_fd+0x2e9/0x300
+[ 64.169977] ? __pfx___sys_connect+0x10/0x10
+[ 64.169977] ? preempt_latency_start+0x1f/0x70
+[ 64.169977] ? fd_install+0x7e/0x150
+[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
+[ 64.169977] ? __sys_socket+0xdf/0x130
+[ 64.169977] ? __pfx___sys_socket+0x10/0x10
+[ 64.169977] ? vma_refcount_put+0x43/0xa0
+[ 64.169977] __x64_sys_connect+0x7e/0x90
+[ 64.169977] do_syscall_64+0x11b/0x2b0
+[ 64.169977] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[ 64.169977] RIP: 0033:0x7f4851ecb570
+[ 64.169977] Code: 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 80 3d f9 ca 0d 00 00 74 17 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 54
+[ 64.169977] RSP: 002b:00007ffc830e3498 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
+[ 64.169977] RAX: ffffffffffffffda RBX: 00007ffc830e34d0 RCX: 00007f4851ecb570
+[ 64.169977] RDX: 0000000000000010 RSI: 00007ffc830e34d0 RDI: 0000000000000005
+[ 64.169977] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
+[ 64.169977] R10: 0000000000000006 R11: 0000000000000202 R12: 0000000000000005
+[ 64.169977] R13: 0000000000000000 R14: 00005619a863f340 R15: 0000000000000000
+[ 64.169977] </TASK>
+
+[ 64.169977] The buggy address belongs to stack of task ping/2844
+[ 64.169977] and is located at offset 88 in frame:
+[ 64.169977] ip4_datagram_release_cb+0x0/0x530
+
+[ 64.169977] This frame has 1 object:
+[ 64.169977] [32, 88) 'fl4'
+
+[ 64.169977] The buggy address belongs to the physical page:
+[ 64.169977] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xe1ff
+[ 64.169977] flags: 0x4000000000000000(zone=1)
+[ 64.169977] raw: 4000000000000000 0000000000000000 ffffea0000387fc8 0000000000000000
+[ 64.169977] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+[ 64.169977] page dumped because: kasan: bad access detected
+
+[ 64.169977] Memory state around the buggy address:
+[ 64.169977] ffff88800e1ffc00: f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00
+[ 64.169977] ffff88800e1ffc80: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00
+[ 64.169977] >ffff88800e1ffd00: 00 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00
+[ 64.169977] ^
+[ 64.169977] ffff88800e1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
+[ 64.169977] ffff88800e1ffe00: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 64.169977] ==================================================================
+[ 64.245153] Disabling lock debugging due to kernel taint
+
+After the fix:
+
+ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl \
+ src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs \
+ level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 \
+ mode transport
+
+Error: Mode in optional template not allowed in outbound policy.
+
+Fixes: d1716d5a44c3 ("xfrm: add generic iptfs defines and functionality")
+Reported-by: syzbot+0ac4d84afe1066a1f3e9@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/6a3ceb94.43b4ff68.30a095.0004.GAE@google.com/T/
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 9ad6619888c738..3641ccccbc4153 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -2068,13 +2068,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
+ switch (ut[i].mode) {
+ case XFRM_MODE_TUNNEL:
+ case XFRM_MODE_BEET:
++ case XFRM_MODE_IPTFS:
+ if (ut[i].optional && dir == XFRM_POLICY_OUT) {
+ NL_SET_ERR_MSG(extack, "Mode in optional template not allowed in outbound policy");
+ return -EINVAL;
+ }
+ break;
+- case XFRM_MODE_IPTFS:
+- break;
+ default:
+ if (ut[i].family != prev_family) {
+ NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
+--
+2.53.0
+
--- /dev/null
+From d12616259b7271d16f66ca6cfba379f0fe59ccb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 01:05:16 +0000
+Subject: xfrm6: clear dst.dev on error to avoid double netdev_put in
+ xfrm6_fill_dst()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
+
+On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst()
+releases the device reference with netdev_put() but leaves
+xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev)
+again, so the same net_device reference is released twice, underflowing
+its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for
+<dev> to become free").
+
+Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM
+device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in
+net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
+
+ ref_tracker: reference already released.
+ ref_tracker: allocated in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
+ ...
+ udpv6_sendmsg (net/ipv6/udp.c:1696)
+ ...
+ ref_tracker: freed in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
+ ...
+ WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
+ dst_destroy (net/core/dst.c:115)
+ rcu_core
+ handle_softirqs
+ ...
+
+Fixes: 84c4a9dfbf43 ("xfrm6: release dev before returning error")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 125ea9a5b8a082..3b749475f6ed65 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+ if (!xdst->u.rt6.rt6i_idev) {
+ netdev_put(dev, &xdst->u.dst.dev_tracker);
++ xdst->u.dst.dev = NULL;
+ return -ENODEV;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f49bf28572a05a3275e16f233dd9461017b26886 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index ed625d5bbe9ab0..8d77662d344f79 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2269,6 +2269,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
+--
+2.53.0
+
--- /dev/null
+From c3ce16e7b3cb2190b0c3dabcd6f9fffaf63a66ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 16:15:34 +0530
+Subject: arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
+
+The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the
+compatible string for all CPU nodes to match the actual hardware.
+
+Tegra234 hardware reports:
+ # head /proc/cpuinfo | egrep 'implementer|part'
+ CPU implementer : 0x41
+ CPU part : 0xd42
+
+Which maps to (from arch/arm64/include/asm/cputype.h):
+ #define ARM_CPU_IMP_ARM 0x41
+ #define ARM_CPU_PART_CORTEX_A78AE 0xD42
+
+Fixes: a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index d1d7f6a50e11f2..6decf99af5f089 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -3109,7 +3109,7 @@ cpus {
+ #size-cells = <0>;
+
+ cpu0_0: cpu@0 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00000>;
+
+@@ -3128,7 +3128,7 @@ cpu0_0: cpu@0 {
+ };
+
+ cpu0_1: cpu@100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00100>;
+
+@@ -3147,7 +3147,7 @@ cpu0_1: cpu@100 {
+ };
+
+ cpu0_2: cpu@200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00200>;
+
+@@ -3166,7 +3166,7 @@ cpu0_2: cpu@200 {
+ };
+
+ cpu0_3: cpu@300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00300>;
+
+@@ -3185,7 +3185,7 @@ cpu0_3: cpu@300 {
+ };
+
+ cpu1_0: cpu@10000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10000>;
+
+@@ -3204,7 +3204,7 @@ cpu1_0: cpu@10000 {
+ };
+
+ cpu1_1: cpu@10100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10100>;
+
+@@ -3223,7 +3223,7 @@ cpu1_1: cpu@10100 {
+ };
+
+ cpu1_2: cpu@10200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10200>;
+
+@@ -3242,7 +3242,7 @@ cpu1_2: cpu@10200 {
+ };
+
+ cpu1_3: cpu@10300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10300>;
+
+@@ -3261,7 +3261,7 @@ cpu1_3: cpu@10300 {
+ };
+
+ cpu2_0: cpu@20000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20000>;
+
+@@ -3280,7 +3280,7 @@ cpu2_0: cpu@20000 {
+ };
+
+ cpu2_1: cpu@20100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20100>;
+
+@@ -3299,7 +3299,7 @@ cpu2_1: cpu@20100 {
+ };
+
+ cpu2_2: cpu@20200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20200>;
+
+@@ -3318,7 +3318,7 @@ cpu2_2: cpu@20200 {
+ };
+
+ cpu2_3: cpu@20300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20300>;
+
+--
+2.53.0
+
--- /dev/null
+From 77e4a3a713a6eb34288f83be2ef3d3acd4164f52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:37 +0530
+Subject: ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
+
+The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was
+claimed with the stale name "AMD ACP6.2 audio" left over from the
+original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
+
+Fixes: 95e43a170bb1 ("ASoC: amd: add Pink Sardine ACP PCI driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 4af3c3665387db..8fe602c0b690cc 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -599,7 +599,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ return -ENODEV;
+ }
+
+- ret = pci_request_regions(pci, "AMD ACP6.2 audio");
++ ret = pci_request_regions(pci, "AMD ACP6.3 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+--
+2.53.0
+
--- /dev/null
+From 0a684363e549e554efa8e873d0b0f7b12cf0bec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 11:34:30 +0100
+Subject: ASoC: cs42l43: Correct report for forced microphone jack
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]
+
+Currently if the jack is forced to the microphone mode, it will report
+as line in. Correct the report to microphone.
+
+Fixes: fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20260708103430.1395207-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l43-jack.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
+index ba60acc4b2f094..d0f424d2e32650 100644
+--- a/sound/soc/codecs/cs42l43-jack.c
++++ b/sound/soc/codecs/cs42l43-jack.c
+@@ -283,6 +283,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
+ #define CS42L43_JACK_ABSENT 0x0
+
+ #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
++#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
+ #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
+ #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
+ #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
+@@ -867,7 +868,7 @@ static const struct cs42l43_jack_override_mode {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+ .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
+ CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
+- .report = CS42L43_JACK_LINEIN,
++ .report = CS42L43_JACK_MICROPHONE,
+ },
+ [CS42L43_JACK_RAW_OPTICAL] = {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+--
+2.53.0
+
--- /dev/null
+From 4672804fd825170db46d3225e5eb0e30d9cbb751 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index fa91f3c53fa462..fe75deafdb69fd 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From 55d735ce73149d2e700f6a7723f17ab3081a79b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index 962c2cdfa01744..a109315a8c0533 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -684,11 +684,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From bc4ba3c230ac97bac03c92eb84782d402bd5b1be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 52f5168e4db542..16c1deef389d10 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From e5ca5ec0990e73d23296779a8595150ea10decf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 97b934fa116e26..74514608a7fada 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From 16c28ef0055eb0651dfd619ace0db575df7957a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 74514608a7fada..66db8dd8ec2670 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+ if (unlikely(!qc)) {
+ dev_err(ap->dev, "failed to get qc");
+--
+2.53.0
+
--- /dev/null
+From d6b13a1e3db9e498cf8eb90e88b4ccc8d0add612 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:25 -0700
+Subject: ata: sata_dwc_460ex: use platform_get_irq()
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]
+
+Replace irq_of_parse_and_map() with platform_get_irq() in both
+sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred
+way to obtain IRQs for platform devices and provides better error
+reporting. Remove the now-unnecessary #include <linux/of_irq.h>.
+
+irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.
+
+Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 16c1deef389d10..97b934fa116e26 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -19,7 +19,6 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/of.h>
+-#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/libata.h>
+@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ struct sata_dwc_device *hsdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *np = dev->of_node;
+
+ hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL);
+ if (!hsdev->dma)
+@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ hsdev->dma->id = pdev->id;
+
+ /* Get SATA DMA interrupt number */
+- hsdev->dma->irq = irq_of_parse_and_map(np, 1);
+- if (!hsdev->dma->irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ hsdev->dma->irq = platform_get_irq(pdev, 1);
++ if (hsdev->dma->irq < 0)
++ return hsdev->dma->irq;
+
+ /* Get physical SATA DMA register base address */
+ hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1);
+@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {
+ static int sata_dwc_probe(struct platform_device *ofdev)
+ {
+ struct device *dev = &ofdev->dev;
+- struct device_node *np = dev->of_node;
+ struct sata_dwc_device *hsdev;
+ u32 idr, versionr;
+ char *ver = (char *)&versionr;
+@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ hsdev->dev = dev;
+
+ /* Get SATA interrupt number */
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ irq = platform_get_irq(ofdev, 0);
++ if (irq < 0)
++ return irq;
+
+ #ifdef CONFIG_SATA_DWC_OLD_DMA
+- if (!of_property_present(np, "dmas")) {
++ if (!of_property_present(dev->of_node, "dmas")) {
+ err = sata_dwc_dma_init_old(ofdev, hsdev);
+ if (err)
+ return err;
+--
+2.53.0
+
--- /dev/null
+From a1e3cf309950a1a015a5290dbcb650a3ea6e6350 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 14:22:50 +0800
+Subject: Bluetooth: hci_qca: Clear memdump state on invalid dump size
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bf587a10c33e5571a299742e45bc18960b9912e7 ]
+
+qca_controller_memdump() allocates qca->qca_memdump before processing
+the first dump packet. For a sequence-zero packet it then disables IBS,
+marks memdump collection active, and reads the advertised dump size.
+
+If the controller reports a zero dump size, the error path frees the
+local qca_memdump object and returns without clearing qca->qca_memdump
+or undoing the collection state. A later memdump work item initializes
+its local pointer from qca->qca_memdump and skips allocation when that
+pointer is non-NULL, so it can operate on freed memory. The stale
+collection and IBS-disabled flags can also leave waiters or later
+transmit handling blocked behind an aborted dump.
+
+Clear the saved pointer and memdump state before returning from the
+invalid-size path, matching the cleanup used when hci_devcd_init() fails.
+
+A static analysis checker reported the stale memdump state, and manual
+source review confirmed the invalid-size failure path.
+
+Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 2986b18655a150..47c50a43db0232 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1069,6 +1069,10 @@ static void qca_controller_memdump(struct work_struct *work)
+ if (!(qca_memdump->ram_dump_size)) {
+ bt_dev_err(hu->hdev, "Rx invalid memdump size");
+ kfree(qca_memdump);
++ qca->qca_memdump = NULL;
++ qca->memdump_state = QCA_MEMDUMP_COLLECTED;
++ clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
++ clear_bit(QCA_IBS_DISABLED, &qca->flags);
+ kfree_skb(skb);
+ mutex_unlock(&qca->hci_memdump_lock);
+ return;
+--
+2.53.0
+
--- /dev/null
+From bf17a794933e787e75eaca81489671269e25c214 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:41 +0300
+Subject: Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 16cd66443957e4ad42155c6fec401012f600c6f8 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF.
+
+Take hdev->lock for hci_conn lookup and hci_abort_conn(). Don't use RCU
+to ensure the conn is fully initialized at this point.
+
+Fixes: 227a0cdf4a028 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 20fe7f011b75c2..2d9781668cb74a 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3005,6 +3005,8 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_unpair_device *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3012,6 +3014,11 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return 0;
+
+@@ -3019,6 +3026,7 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+@@ -3166,6 +3174,8 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_disconnect *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3173,6 +3183,11 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return -ENOTCONN;
+
+@@ -3180,6 +3195,7 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From bc548702fd1de53bd541fecba1505aaaf8bb77b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:42 +0300
+Subject: Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit da55f570191d5d72f10c607a7043b947eb05ea46 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF. Use of hci_conn in hci_sync callbacks also
+needs to hold refcount to avoid UAF.
+
+Take appropriate locks for hci_conn lookups, and take refcount for
+hci_conn pointers stored in mgmt_pending_cmd so that the pointer stays
+valid.
+
+When accessing conn->state, ensure hdev->lock is held to avoid data
+race.
+
+Fixes: 7b445e220db9 ("Bluetooth: MGMT: Fix holding hci_conn reference while command is queued")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 2d9781668cb74a..979caeb85a42c7 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7417,6 +7417,9 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
+ rp.max_tx_power = HCI_TX_POWER_INVALID;
+ }
+
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
+ &rp, sizeof(rp));
+
+@@ -7431,6 +7434,8 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ int err;
+ __le16 handle;
+
++ hci_dev_lock(hdev);
++
+ /* Make sure we are still connected */
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+@@ -7438,12 +7443,16 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ else
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
+
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ handle = cpu_to_le16(conn->handle);
+
++ hci_dev_unlock(hdev);
++
+ /* Refresh RSSI each time */
+ err = hci_read_rssi_sync(hdev, handle);
+
+@@ -7577,6 +7586,9 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
+ }
+
+ complete:
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
+ sizeof(rp));
+
+@@ -7593,15 +7605,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
+ memset(&hci_cp, 0, sizeof(hci_cp));
+ hci_read_clock_sync(hdev, &hci_cp);
+
++ hci_dev_lock(hdev);
++
+ /* Make sure connection still exists */
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ hci_cp.handle = cpu_to_le16(conn->handle);
+ hci_cp.which = 0x01; /* Piconet clock */
+
++ hci_dev_unlock(hdev);
++
+ return hci_read_clock_sync(hdev, &hci_cp);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f985439a532e8a7c9c50e9346fdffc72af23625c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index 5b34da23adce7c..09ef7df5c231bf 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -430,7 +430,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From b54ac57221e3a728cc23301e5e7de8866cea4dea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 06:23:57 +0200
+Subject: bpf, sockmap: Reject unhashed UDP sockets on sockmap update
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 66efd3368ae10d05e08fbe6425b50fdec7186ac7 ]
+
+UDP sockets get SOCK_RCU_FREE set when (auto-)bound. This means
+sk_is_refcounted(unbound) = true, while sk_is_refcounted(bound) = false.
+
+Because sockmap accepts unbound UDP sockets, a BPF program can increment a
+socket's refcount via lookup. If the socket is subsequently bound, the
+transition from unbound to bound causes bpf_sk_release() to skip the
+decrement of the refcount, causing a memory leak.
+
+unreferenced object 0xffff88810bc2eb40 (size 1984):
+ comm "test_progs", pid 2451, jiffies 4295320596
+ hex dump (first 32 bytes):
+ 7f 00 00 01 7f 00 00 01 d2 04 1b b7 04 d2 00 00 ................
+ 02 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace (crc bdee079d):
+ kmem_cache_alloc_noprof+0x557/0x660
+ sk_prot_alloc+0x69/0x240
+ sk_alloc+0x30/0x460
+ inet_create+0x2ce/0xf80
+ __sock_create+0x25b/0x5c0
+ __sys_socket+0x119/0x1d0
+ __x64_sys_socket+0x72/0xd0
+ do_syscall_64+0xa1/0x5f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Instead of special-casing for refcounted sockets, reject unhashed UDP
+sockets during sockmap updates, as there is no benefit to supporting those.
+This effectively reverts the commit under Fixes, with two exceptions:
+
+1. sock_map_sk_state_allowed() maintains a fall-through `return true`.
+2. In the spirit of commit b8b8315e39ff ("bpf, sockmap: Remove unhash
+ handler for BPF sockmap usage"), the proto::unhash BPF handler is not
+ reintroduced.
+
+Historical note: this issue is related to commit 67312adc96b5 ("bpf: reject
+unhashed sockets in bpf_sk_assign").
+
+Fixes: 0c48eefae712 ("sock_map: Lift socket state restriction for datagram sockets")
+Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20260707-sockmap-lookup-udp-leak-v4-2-f878346f27ab@rbox.co
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 3a53b6a0e76e2b..052057303cff11 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -539,6 +539,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+ {
+ if (sk_is_tcp(sk))
+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
++ if (sk_is_udp(sk))
++ return sk_hashed(sk);
+ if (sk_is_stream_unix(sk))
+ return (1 << sk->sk_state) & TCPF_ESTABLISHED;
+ if (sk_is_vsock(sk) &&
+--
+2.53.0
+
--- /dev/null
+From f0b4983acccece1380927134dde9c89363defe42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 0f05eb97925fdd..90aacda2523eb5 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1991,6 +1991,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From fb06b5ea70e89228bd02433f2959afe47e3a15f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index c6e3b9a2921ab1..8be5614ae9b620 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -559,6 +559,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From 71531bd2ca42e5635894c250ff1044742337fe3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 6c37562a50f72e..d8dada03b3cd12 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -350,6 +350,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -358,8 +370,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2021,8 +2032,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From 735966ebdde72beb6fa06343f3069c8db3040f9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index d304e0a948f0d1..13b27ee9e7bef2 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -260,7 +260,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From 4e64b88750d16f37967b76e0e8a9981226de64f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index 0971241707ce83..d396fbd55b740b 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -16,9 +16,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -28,9 +28,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From c1c76ef67b595de535ef503708b058408c57fa17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index ece91d8d820b51..2309a31549e25a 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -582,7 +582,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From 429e0a9ec869f466a8c9e44079424e254dffc82c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 4782b115e6ec51..1bc715fe3968c3 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -595,9 +595,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 4701b6916689bc938628639a8d799a90184f81dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 242434c09e8d8f..bddb1c607aff62 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1778,6 +1778,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ &mad_send_wr->mad_agent_priv->done_list);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -1796,6 +1814,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From 50c2f63ea3e7504935fdd663a4c6f34f753beb5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index c9e1526e749b2b..53e7664eeb0a2a 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1390,7 +1390,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From 0e53619c02fb79c9145174ebc9d07440d7861baa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 22:49:55 +0800
+Subject: ksmbd: pin conn during async oplock break notification
+
+From: Qihang <q.h.hack.winter@gmail.com>
+
+[ Upstream commit aa5d8f3f96aa11a4a54ce993c11ce8af11c546f9 ]
+
+smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn
+pointer in an async ksmbd_work and then queue that work on ksmbd-io. The
+work only increments conn->r_count, which prevents teardown from passing
+the pending-request wait after the increment, but it does not pin the
+struct ksmbd_conn object.
+
+If connection teardown races with an oplock break notification, the last
+conn reference can be dropped before the queued worker finishes. The
+worker then uses the freed conn in ksmbd_conn_write() and
+ksmbd_conn_r_count_dec().
+
+Take a real conn reference when publishing the conn pointer to the async
+work item, and drop it after the notification work has decremented
+r_count. Apply the same lifetime rule to lease break notification, which
+uses the same work->conn pattern.
+
+Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification")
+Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index 82a7709b3e9ac8..109bb71d06adff 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -705,6 +705,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -740,7 +741,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
+ br_info->open_trunc = opinfo->open_trunc;
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+@@ -814,6 +815,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -853,7 +855,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
+ memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+--
+2.53.0
+
--- /dev/null
+From baeb0952b39688fdc919a805c9d1cca476c59378 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
+index 727cb49926ee52..ffbddf00d24e95 100644
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -400,6 +400,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From 5df6f66914760a65857caa8fb2bd47f92f3ec5ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 0561a530ecf0d9..2099ce095edc8e 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2125,6 +2125,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = __dev_get_by_index(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From e23ae0ea5cd3d6845d8c4d1b5c073b06391e76f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 20:10:42 +0800
+Subject: mtd: fix double free and WARN_ON in add_mtd_device() error paths
+
+From: Xue Lei <Xue.Lei@windriver.com>
+
+[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]
+
+When device_register() or mtd_nvmem_add() fails inside
+add_mtd_device() for a partition, the error handling triggers
+mtd_release() via put_device() or device_unregister(). mtd_release()
+calls release_mtd_partition() which frees the mtd_info structure.
+However, callers such as mtd_add_partition() and add_mtd_partitions()
+also call free_partition() in their error paths, resulting in a double
+free.
+
+Additionally, release_mtd_partition() hits WARN_ON(!list_empty(
+&mtd->part.node)) because the partition node is still linked in the
+parent's partitions list when the release callback fires from the
+add_mtd_device() error path.
+
+Fix this by overriding dev->type and dev->release before put_device()
+in the error paths, so that device_release() invokes a no-op function
+instead of mtd_release(). For the mtd_nvmem_add() failure case,
+device_unregister() is replaced with device_del() to separate the
+device removal from the final kobject reference drop, allowing the
+override to take effect before put_device() is called.
+
+The callers' error paths (list_del + free_partition) remain the sole
+owners of mtd_info lifetime on add_mtd_device() failure, which is the
+expected contract.
+
+The normal partition teardown path is not affected: del_mtd_device()
+goes through kref_put() -> mtd_device_release() -> device_unregister()
+with dev->type still set to &mtd_devtype, so mtd_release() ->
+release_mtd_partition() continues to work correctly for the regular
+removal case.
+
+Reported-by: syzbot+e9c76b56dc05023b8117@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e9c76b56dc05023b8117
+Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
+Signed-off-by: Xue Lei <Xue.Lei@windriver.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 97ca2a897f1d49..506ebd4ba1b458 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -103,6 +103,15 @@ static void mtd_release(struct device *dev)
+ device_destroy(&mtd_class, index + 1);
+ }
+
++/*
++ * No-op device release used in add_mtd_device() error paths.
++ * Prevents mtd_release() from being called via device_release(),
++ * which would free the mtd_info that the caller still manages.
++ */
++static void mtd_dev_release_nop(struct device *dev)
++{
++}
++
+ static void mtd_device_release(struct kref *kref)
+ {
+ struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+@@ -745,10 +754,8 @@ int add_mtd_device(struct mtd_info *mtd)
+ mtd_check_of_node(mtd);
+ of_node_get(mtd_get_of_node(mtd));
+ error = device_register(&mtd->dev);
+- if (error) {
+- put_device(&mtd->dev);
++ if (error)
+ goto fail_added;
+- }
+
+ /* Add the nvmem provider */
+ error = mtd_nvmem_add(mtd);
+@@ -786,8 +793,16 @@ int add_mtd_device(struct mtd_info *mtd)
+ return 0;
+
+ fail_nvmem_add:
+- device_unregister(&mtd->dev);
++ device_del(&mtd->dev);
+ fail_added:
++ /*
++ * Clear type and set nop release to prevent mtd_release() ->
++ * release_mtd_partition() -> free_partition() from freeing mtd.
++ * The caller handles cleanup on failure.
++ */
++ mtd->dev.type = NULL;
++ mtd->dev.release = mtd_dev_release_nop;
++ put_device(&mtd->dev);
+ of_node_put(mtd_get_of_node(mtd));
+ idr_remove(&mtd_idr, i);
+ fail_locked:
+--
+2.53.0
+
--- /dev/null
+From bfc22a57c7ddf543462126cd612d13d26037b2ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 680366616da240..4d695875ea1b23 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From 04237dc10029c01d84808bc978fbddc2f33ecf31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/ecc-mtk.c b/drivers/mtd/nand/ecc-mtk.c
+index c75bb8b80cc1e1..96703f0a418ea2 100644
+--- a/drivers/mtd/nand/ecc-mtk.c
++++ b/drivers/mtd/nand/ecc-mtk.c
+@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From ae5f5693138c94b6eae630935068afe776c45f21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index e9a9bb0dee065a..a7b95590f6c96c 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2090,6 +2090,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2139,6 +2141,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f6f40cd903b73cc252fe4e476961c04b5b424c86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 99fb869aee91b7..65664e530c73b5 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -344,14 +344,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 3ee02603e5e21fe6047a9aceb0de8157211593f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2026 15:16:37 +0200
+Subject: powerpc/time: Prepare to stop elapsing in dynticks-idle
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit c8ba971cf8567d49eb5f43ee90c4e50424331c18 ]
+
+Currently the tick subsystem stores the idle cputime accounting in
+private fields, allowing cohabitation with architecture idle vtime
+accounting. The former is fetched on online CPUs, the latter on offline
+CPUs.
+
+For consolidation purpose, architecture vtime accounting will continue
+to account the cputime but will make a break when the idle tick is
+stopped. The dyntick cputime accounting will then be relayed by the tick
+subsystem so that the idle cputime is still seen advancing coherently
+even when the tick isn't there to flush the idle vtime.
+
+Prepare for that and introduce three new APIs which will be used in
+subsequent patches:
+
+ - vtime_dynticks_start() is deemed to be called when idle enters in
+ dyntick mode. The idle cputime that elapsed so far is accumulated.
+
+ - vtime_dynticks_stop() is deemed to be called when idle exits from
+ dyntick mode. The vtime entry clocks are fast-forward to current time
+ so that idle accounting restarts elapsing from now.
+
+ - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
+ fast-forward the clock to current time so that the IRQ time is still
+ accounted by vtime while nohz cputime is paused.
+
+Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
+accounting twice the idle cputime, along with nohz accounting.
+
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Link: https://patch.msgid.link/20260508131647.43868-6-frederic@kernel.org
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
+ include/linux/vtime.h | 6 ++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 7fce6adb6f05fd..4287f2bd5450c1 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
+ acct->starttime = acct0->starttime;
+ }
+ }
++
++#ifdef CONFIG_NO_HZ_COMMON
++/**
++ * vtime_reset - Fast forward vtime entry clocks
++ *
++ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
++ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
++ */
++void vtime_reset(void)
++{
++ struct cpu_accounting_data *acct = get_accounting(current);
++
++ acct->starttime = mftb();
++#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
++ acct->startspurr = read_spurr(acct->starttime);
++#endif
++}
++
++/**
++ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
++ *
++ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
++ * is accumulated and the tick subsystem takes over the idle cputime accounting.
++ */
++void vtime_dyntick_start(void)
++{
++ vtime_account_idle(current);
++}
++
++/**
++ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
++ *
++ * Called when idle exits from dyntick mode. The vtime entry clocks are
++ * fast-forward to current time so that idle accounting restarts elapsing from
++ * now.
++ */
++void vtime_dyntick_stop(void)
++{
++ vtime_reset();
++}
++#endif /* CONFIG_NO_HZ_COMMON */
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/include/linux/vtime.h b/include/linux/vtime.h
+index 3684487d01e1c6..7cee518fde3a24 100644
+--- a/include/linux/vtime.h
++++ b/include/linux/vtime.h
+@@ -37,11 +37,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
+ extern void vtime_account_softirq(struct task_struct *tsk);
+ extern void vtime_account_hardirq(struct task_struct *tsk);
+ extern void vtime_flush(struct task_struct *tsk);
++extern void vtime_reset(void);
++extern void vtime_dyntick_start(void);
++extern void vtime_dyntick_stop(void);
+ #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+ static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
+ static inline void vtime_account_softirq(struct task_struct *tsk) { }
+ static inline void vtime_account_hardirq(struct task_struct *tsk) { }
+ static inline void vtime_flush(struct task_struct *tsk) { }
++static inline void vtime_reset(void) { }
++static inline void vtime_dyntick_start(void) { }
++static inline void vtime_dyntick_stop(void) { }
+ #endif
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 664fe818fd32ff55cd938a71c7658b147aee7dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:13:29 +0530
+Subject: powerpc/vtime: Initialize starttime at boot for native accounting
+
+From: Shrikanth Hegde <sshegde@linux.ibm.com>
+
+[ Upstream commit c1c1ffa490fc33591e90852ed0d38804dd20bc36 ]
+
+It was observed that /proc/stat had very large value for one ore more
+CPUs. It was more visible after recent code simplifications around
+cpustats.
+
+System has 240 CPUs.
+
+cat /proc/uptime;
+194.18 46500.55
+cat /proc/stat
+cpu 5966 39 837032887 4650070 164 185 100 0 0 0
+cpu0 108 0 837030890 19109 24 4 23 0 0 0
+
+Since uptime is 194s, system time of each CPU can't be more than 19400.
+Sum of system time of all CPUs can't be more than 19400*240 4656000.
+In fact huge value is close to mftb(). Note mftb doesn't reset on powerVM
+when the LPAR restart. It only resets when whole system resets. The same
+issue exists for kexec too.
+
+This happens since starttime is not setup at init time. Once it is set
+then subsequent vtime_delta will return the right delta.
+
+Fix it by initializing the starttime during CPU initialization. This
+fixes the large times seen.
+
+cat /proc/uptime; cat /proc/stat
+15.78 3694.63
+cpu 6035 35 1347 369479 23 144 49 0 0 0
+cpu0 19 0 38 1508 0 1 14 0 0 0
+
+Now, system time is reported as expected.
+
+Fixes: cf9efce0ce31 ("powerpc: Account time using timebase rather than PURR")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Suggested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260605124329.377533-1-sshegde@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 4287f2bd5450c1..dce831af31662e 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -377,7 +377,6 @@ void vtime_task_switch(struct task_struct *prev)
+ }
+ }
+
+-#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_reset - Fast forward vtime entry clocks
+ *
+@@ -394,6 +393,7 @@ void vtime_reset(void)
+ #endif
+ }
+
++#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
+ *
+@@ -927,6 +927,7 @@ static void __init set_decrementer_max(void)
+ static void __init init_decrementer_clockevent(void)
+ {
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ void secondary_cpu_time_init(void)
+@@ -942,6 +943,7 @@ void secondary_cpu_time_init(void)
+ /* FIME: Should make unrelated change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ /* This function is only called on the boot processor */
+--
+2.53.0
+
--- /dev/null
+From 0949947b1e83d9da594240e3f4dfb6182439df24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 2b5843d14cbb84..53e96a8740397c 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -192,6 +192,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ rwlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3555,6 +3556,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Free up the resources used by a ppp channel.
+ */
+@@ -3570,9 +3583,7 @@ static void ppp_destroy_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3585,6 +3596,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_destroy(ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From a7895fc18177e74860b3c63cd87aa507757128f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:21:05 +0300
+Subject: RDMA/cma: Fix hardware address comparison length in netevent callback
+
+From: Or Gerlitz <ogerlitz@ddn.com>
+
+[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
+
+The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
+
+This breaks IPoIB, which uses 20-byte addresses. By truncating the
+memcmp, the CMA may incorrectly assume the target address is
+unchanged and fails to abort the stalled connection.
+
+Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len
+to correctly evaluate the full address regardless of the link layer.
+
+Fixes: 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
+Signed-off-by: Or Gerlitz <ogerlitz@ddn.com>
+Link: https://patch.msgid.link/20260617-fix-cma-ipoib-v1-1-03f869344304@ddn.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 7db79ff3fa06c3..87164dd745ecb5 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5215,7 +5215,7 @@ static int cma_netevent_callback(struct notifier_block *self,
+
+ list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
+ if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
+- neigh->ha, ETH_ALEN))
++ neigh->ha, neigh->dev->addr_len))
+ continue;
+ cma_id_get(current_id);
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
+--
+2.53.0
+
--- /dev/null
+From aa1a55447ce6233e8ce7cad1b879998491277fb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:51 +0800
+Subject: RDMA/erdma: initialize ret for empty receive WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
+
+erdma_post_recv() returns ret after walking the receive work request list.
+If the caller passes an empty list, the loop is skipped and ret is not
+assigned.
+
+Initialize ret to 0 so an empty receive work request list returns success
+instead of stack data.
+
+Fixes: 155055771704 ("RDMA/erdma: Add verbs implementation")
+Link: https://patch.msgid.link/r/20260618041752.481193-1-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_qp.c b/drivers/infiniband/hw/erdma/erdma_qp.c
+index 6d0330badd68e8..e3a731a45e8861 100644
+--- a/drivers/infiniband/hw/erdma/erdma_qp.c
++++ b/drivers/infiniband/hw/erdma/erdma_qp.c
+@@ -573,7 +573,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
+ const struct ib_recv_wr *wr = recv_wr;
+ struct erdma_qp *qp = to_eqp(ibqp);
+ unsigned long flags;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&qp->lock, flags);
+
+--
+2.53.0
+
--- /dev/null
+From 6b8f33774c5bb1f1c0f48e5fcedf6ba0a1784f95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index d6fcb1a4bd4fca..112248ddf02367 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -907,7 +907,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From eb7db8eb8b1ae9c013798dfa6d55be3354073043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 1779d2a9945945..136e367b40d874 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2366,7 +2366,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2399,7 +2399,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From cf41ad7a0f507dfdd962799005671cb5133f02c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:19:36 +0000
+Subject: RDMA/irdma: Prevent rereg_mr for non-mem regions
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]
+
+When a QP/CQ/SRQ is created, a two step process is used
+where the buffer is allocated in userspace and explicitly
+registered with the normal reg_mr mechanism prior to creating
+the actual QP/CQ/SRQ object.
+
+These special registrations are indicated via an ABI field
+so the driver knows that they do not have a valid mkey and
+to skip the actual CQP command submission.
+
+Since these are real MR objects from the core's perspective,
+it is possible for a user application to invoke rereg_mr on them
+and cause a real CQP op to be emitted with the zero-initialized
+mkey value of 0.
+
+Fix this by preventing rereg_mr on these special regions.
+
+Fixes: 5ac388db27c4 ("RDMA/irdma: Add support to re-register a memory region")
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 8ffbc790c1681e..1779d2a9945945 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -3251,6 +3251,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
+ return ERR_PTR(-EOPNOTSUPP);
+
++ if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
++ return ERR_PTR(-EINVAL);
++
+ ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
+ if (ret)
+ return ERR_PTR(ret);
+--
+2.53.0
+
--- /dev/null
+From 76f72e296857861765ca657660b5507678a9739d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Nov 2023 19:57:24 +0800
+Subject: RDMA/siw: Only check attrs->cap.max_send_wr in siw_create_qp
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit 788bbf4c2fc6e0c35bae9ed5068f484272539d3e ]
+
+We can just check max_send_wr here given both max_send_wr and
+max_recv_wr are defined as u32 type, and we also need to ensure
+num_sqe (derived from max_send_wr) shouldn't be zero.
+
+Acked-by: Bernard Metzler <bmt@zurich.ibm.com>
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Link: https://lore.kernel.org/r/20231113115726.12762-16-guoqing.jiang@linux.dev
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: bb27fcc67c42 ("RDMA/siw: publish QP after initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 1768b8695c45ad..75a7ad323c8230 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -336,11 +336,10 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ goto err_atomic;
+ }
+ /*
+- * NOTE: we allow for zero element SQ and RQ WQE's SGL's
+- * but not for a QP unable to hold any WQE (SQ + RQ)
++ * NOTE: we don't allow for a QP unable to hold any SQ WQE
+ */
+- if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) {
+- siw_dbg(base_dev, "QP must have send or receive queue\n");
++ if (attrs->cap.max_send_wr == 0) {
++ siw_dbg(base_dev, "QP must have send queue\n");
+ rv = -EINVAL;
+ goto err_atomic;
+ }
+@@ -360,21 +359,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_atomic;
+
+- num_sqe = attrs->cap.max_send_wr;
+- num_rqe = attrs->cap.max_recv_wr;
+
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+ * avoids handling counter wrap around.
+ */
+- if (num_sqe)
+- num_sqe = roundup_pow_of_two(num_sqe);
+- else {
+- /* Zero sized SQ is not supported */
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++ num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr);
++ num_rqe = attrs->cap.max_recv_wr;
+ if (num_rqe)
+ num_rqe = roundup_pow_of_two(num_rqe);
+
+--
+2.53.0
+
--- /dev/null
+From fb9c215ee67a19c1a5e3483e0b29ede32d4c2493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 75a7ad323c8230..40e0e0a2486db5 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -302,6 +302,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -355,11 +356,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -377,14 +373,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -410,7 +406,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -425,11 +421,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -438,7 +431,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -450,9 +443,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -462,22 +469,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From df10b8da39960b67f5f5115c98f6b5b29ef9d56c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:25 +0000
+Subject: RDMA/umem: Add helpers for umem dmabuf revoke lock
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit 3a0b171302eea1732a168e26db3b8461f51cc1f9 ]
+
+Added helpers to acquire and release the umem dmabuf revoke
+lock. The intent is to avoid the need for drivers to peek
+into the ib_umem_dmabuf internals to get the dma_resv_lock
+and bring us one step closer to abstracting ib_umem_dmabuf
+away from drivers in general.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-5-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 16 ++++++++++++++++
+ include/rdma/ib_umem.h | 4 ++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index 091af1f7aa29db..1206993e2e3e83 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -337,6 +337,22 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned);
+
++void ib_umem_dmabuf_revoke_lock(struct ib_umem_dmabuf *umem_dmabuf)
++{
++ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
++
++ dma_resv_lock(dmabuf->resv, NULL);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_revoke_lock);
++
++void ib_umem_dmabuf_revoke_unlock(struct ib_umem_dmabuf *umem_dmabuf)
++{
++ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
++
++ dma_resv_unlock(dmabuf->resv);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_revoke_unlock);
++
+ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf)
+ {
+ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 7637ff06bb5b10..4c5329b504d0cb 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -138,6 +138,8 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf);
++void ib_umem_dmabuf_revoke_lock(struct ib_umem_dmabuf *umem_dmabuf);
++void ib_umem_dmabuf_revoke_unlock(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
+
+ int ib_umem_check_rereg(struct ib_umem *umem, int flags, int new_access_flags);
+@@ -212,6 +214,8 @@ static inline int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
+ }
+ static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) { }
+ static inline void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) { }
++static inline void ib_umem_dmabuf_revoke_lock(struct ib_umem_dmabuf *umem_dmabuf) {}
++static inline void ib_umem_dmabuf_revoke_unlock(struct ib_umem_dmabuf *umem_dmabuf) {}
+ static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {}
+
+ static inline int ib_umem_check_rereg(struct ib_umem *umem, int flags,
+--
+2.53.0
+
--- /dev/null
+From e8716a6fbe84676dda77f5999b9e6910ad41f6b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:22 +0000
+Subject: RDMA/umem: Add ib_umem_dmabuf_get_pinned_and_lock helper
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit 553dfa8cbd0c6d36adae042d9738ddf8f8765ac7 ]
+
+Move the inner logic of ib_umem_dmabuf_get_pinned_with_dma_device()
+to a new static function that returns with the lock held upon success.
+
+The intent is to allow reuse for the future get_pinned_revocable_and_lock
+function.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-2-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 35 ++++++++++++++++++++-------
+ 1 file changed, 26 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index 44bb7449738cf4..acb0922a786131 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -198,18 +198,19 @@ static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_ops = {
+ .move_notify = ib_umem_dmabuf_unsupported_move_notify,
+ };
+
+-struct ib_umem_dmabuf *
+-ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+- struct device *dma_device,
+- unsigned long offset, size_t size,
+- int fd, int access)
++static struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset,
++ size_t size, int fd, int access,
++ const struct dma_buf_attach_ops *ops)
+ {
+ struct ib_umem_dmabuf *umem_dmabuf;
+ int err;
+
+- umem_dmabuf = ib_umem_dmabuf_get_with_dma_device(device, dma_device, offset,
+- size, fd, access,
+- &ib_umem_dmabuf_attach_pinned_ops);
++ umem_dmabuf =
++ ib_umem_dmabuf_get_with_dma_device(device, dma_device, offset,
++ size, fd, access, ops);
+ if (IS_ERR(umem_dmabuf))
+ return umem_dmabuf;
+
+@@ -222,7 +223,6 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ err = ib_umem_dmabuf_map_pages(umem_dmabuf);
+ if (err)
+ goto err_release;
+- dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
+
+ return umem_dmabuf;
+
+@@ -231,6 +231,23 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ ib_umem_release(&umem_dmabuf->umem);
+ return ERR_PTR(err);
+ }
++
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ struct ib_umem_dmabuf *umem_dmabuf =
++ ib_umem_dmabuf_get_pinned_and_lock(device, dma_device, offset,
++ size, fd, access,
++ &ib_umem_dmabuf_attach_pinned_ops);
++ if (IS_ERR(umem_dmabuf))
++ return umem_dmabuf;
++
++ dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
++ return umem_dmabuf;
++}
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
+
+ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+--
+2.53.0
+
--- /dev/null
+From 0ccc33fa4c063bf33215c82c57bcce9ca1df33a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:24 +0000
+Subject: RDMA/umem: Add pinned revocable dmabuf import interface
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c ]
+
+Added an interface for importing a pinned but revocable dmabuf.
+This interface can be used by drivers that are capable of revocation
+so that they can import dmabufs from exporters that may require it,
+such as VFIO.
+
+This interface implements a two step process, where drivers will first
+call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and
+map the dmabuf (and provide a functional move_notify/invalidate_mappings
+callback), but will return with the lock still held so that the
+driver can then populate the callback via
+ib_umem_dmabuf_set_revoke_locked() without races from concurrent
+revocations. This scheme also allows for easier integration with drivers
+that may not have actually allocated their internal MR objects at the time
+of the get_pinned_revocable* call.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-4-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 61 +++++++++++++++++++++++++++
+ include/rdma/ib_umem.h | 19 +++++++++
+ 2 files changed, 80 insertions(+)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index be5977daafa1de..091af1f7aa29db 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -206,6 +206,10 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+
+ if (umem_dmabuf->revoked)
+ return;
++
++ if (umem_dmabuf->pinned_revoke)
++ umem_dmabuf->pinned_revoke(umem_dmabuf->private);
++
+ ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+ if (umem_dmabuf->pinned) {
+ dma_buf_unpin(umem_dmabuf->attach);
+@@ -214,6 +218,11 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
+ umem_dmabuf->revoked = 1;
+ }
+
++static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = {
++ .allow_peer2peer = true,
++ .move_notify = ib_umem_dmabuf_revoke_locked,
++};
++
+ static struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
+ struct device *dma_device,
+@@ -266,6 +275,58 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
+
++/**
++ * ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf
++ * @device: IB device.
++ * @offset: Start offset.
++ * @size: Length.
++ * @fd: dmabuf fd.
++ * @access: Access flags.
++ *
++ * Obtains a umem from a dmabuf for drivers/devices that can support revocation.
++ *
++ * Returns with dma_resv_lock held upon success. The driver must set the revoke
++ * callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked().
++ *
++ * When a revocation occurs, the revoke callback will be called. The driver must
++ * ensure that the region is no longer accessed when the callback returns. Any
++ * subsequent access attempts should also probably cause an AE for MRs.
++ *
++ * If the umem is used for an MR, the driver must ensure that the key remains in
++ * use such that it cannot be obtained by a new region until this region is
++ * fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with
++ * revoke calls, it can use dma_resv_lock.
++ *
++ * If successful, then the revoke callback may be called at any time and will
++ * also be called automatically upon ib_umem_release (serialized). The revoke
++ * callback will be called one time at most.
++ *
++ * Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure.
++ */
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ const struct dma_buf_attach_ops *ops =
++ &ib_umem_dmabuf_attach_pinned_revocable_ops;
++
++ return ib_umem_dmabuf_get_pinned_and_lock(device, device->dma_device,
++ offset, size, fd, access,
++ ops);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_revocable_and_lock);
++
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv)
++{
++ dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
++
++ umem_dmabuf->pinned_revoke = revoke;
++ umem_dmabuf->private = priv;
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_set_revoke_locked);
++
+ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ unsigned long offset,
+ size_t size, int fd,
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 3ec9f1deca7db4..7637ff06bb5b10 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -36,6 +36,7 @@ struct ib_umem_dmabuf {
+ struct scatterlist *last_sg;
+ unsigned long first_sg_offset;
+ unsigned long last_sg_trim;
++ void (*pinned_revoke)(void *priv);
+ void *private;
+ u8 pinned : 1;
+ u8 revoked : 1;
+@@ -124,6 +125,12 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ size_t size, int fd,
+ int access);
+ struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access);
++void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv);
++struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+ unsigned long offset, size_t size,
+@@ -178,6 +185,18 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
++static inline struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ return ERR_PTR(-EOPNOTSUPP);
++}
++
++static inline void
++ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
++ void (*revoke)(void *priv), void *priv) {}
++
+ static inline struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+--
+2.53.0
+
--- /dev/null
+From 0a8214db307121d59e27c82f22c17771c19a5486 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 15:05:13 +0300
+Subject: RDMA/umem: Add support for creating pinned DMABUF umem with a given
+ dma device
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit 682358fd35dece838e6ae2d9d6a69fc0b9a9d411 ]
+
+Add support for creating pinned DMABUF umem with a specified DMA device
+instead of the DMA device of the given IB device.
+
+This API will be utilized in the upcoming patches of the series when
+multiple path DMAs are implemented.
+
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://patch.msgid.link/038aad36a43797e5591b20ba81051fc5758124f9.1722512548.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 45 ++++++++++++++++++++-------
+ include/rdma/ib_umem.h | 15 +++++++++
+ 2 files changed, 49 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index 66f5760197479d..674a4b45e7bfe7 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -110,10 +110,12 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf)
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_unmap_pages);
+
+-struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
+- unsigned long offset, size_t size,
+- int fd, int access,
+- const struct dma_buf_attach_ops *ops)
++static struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_with_dma_device(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset, size_t size,
++ int fd, int access,
++ const struct dma_buf_attach_ops *ops)
+ {
+ struct dma_buf *dmabuf;
+ struct ib_umem_dmabuf *umem_dmabuf;
+@@ -152,7 +154,7 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
+
+ umem_dmabuf->attach = dma_buf_dynamic_attach(
+ dmabuf,
+- device->dma_device,
++ dma_device,
+ ops,
+ umem_dmabuf);
+ if (IS_ERR(umem_dmabuf->attach)) {
+@@ -168,6 +170,15 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
+ dma_buf_put(dmabuf);
+ return ret;
+ }
++
++struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
++ unsigned long offset, size_t size,
++ int fd, int access,
++ const struct dma_buf_attach_ops *ops)
++{
++ return ib_umem_dmabuf_get_with_dma_device(device, device->dma_device,
++ offset, size, fd, access, ops);
++}
+ EXPORT_SYMBOL(ib_umem_dmabuf_get);
+
+ static void
+@@ -184,16 +195,18 @@ static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_ops = {
+ .move_notify = ib_umem_dmabuf_unsupported_move_notify,
+ };
+
+-struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+- unsigned long offset,
+- size_t size, int fd,
+- int access)
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset, size_t size,
++ int fd, int access)
+ {
+ struct ib_umem_dmabuf *umem_dmabuf;
+ int err;
+
+- umem_dmabuf = ib_umem_dmabuf_get(device, offset, size, fd, access,
+- &ib_umem_dmabuf_attach_pinned_ops);
++ umem_dmabuf = ib_umem_dmabuf_get_with_dma_device(device, dma_device, offset,
++ size, fd, access,
++ &ib_umem_dmabuf_attach_pinned_ops);
+ if (IS_ERR(umem_dmabuf))
+ return umem_dmabuf;
+
+@@ -215,6 +228,16 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ ib_umem_release(&umem_dmabuf->umem);
+ return ERR_PTR(err);
+ }
++EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
++
++struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
++ unsigned long offset,
++ size_t size, int fd,
++ int access)
++{
++ return ib_umem_dmabuf_get_pinned_with_dma_device(device, device->dma_device,
++ offset, size, fd, access);
++}
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned);
+
+ void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index eac3c05278c153..3441ba9f2a0daf 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -122,6 +122,11 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ unsigned long offset,
+ size_t size, int fd,
+ int access);
++struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset, size_t size,
++ int fd, int access);
+ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf);
+@@ -170,6 +175,16 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
+ {
+ return ERR_PTR(-EOPNOTSUPP);
+ }
++
++static inline struct ib_umem_dmabuf *
++ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
++ struct device *dma_device,
++ unsigned long offset, size_t size,
++ int fd, int access)
++{
++ return ERR_PTR(-EOPNOTSUPP);
++}
++
+ static inline int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
+ {
+ return -EOPNOTSUPP;
+--
+2.53.0
+
--- /dev/null
+From 1480aecc4b7958d2cf9fc4bb1c987b129da174f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 15:05:14 +0300
+Subject: RDMA/umem: Introduce an option to revoke DMABUF umem
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit 253c61dc256b3e6be65657f78b4a8452163ce00f ]
+
+Introduce an option to revoke DMABUF umem.
+
+This option will retain the umem allocation while revoking its DMA
+mapping. Furthermore, any subsequent attempts to map the pages should
+fail once the umem has been revoked.
+
+This functionality will be utilized in the upcoming patches in the
+series, where we aim to delay umem deallocation until the mkey
+deregistration. However, we must unmap its pages immediately.
+
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://patch.msgid.link/a38270f2fe4a194868ca2312f4c1c760e51bcbff.1722512548.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 21 +++++++++++++++++++--
+ include/rdma/ib_umem.h | 3 +++
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index 674a4b45e7bfe7..44bb7449738cf4 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -23,6 +23,9 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
+
+ dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
+
++ if (umem_dmabuf->revoked)
++ return -EINVAL;
++
+ if (umem_dmabuf->sgt)
+ goto wait_fence;
+
+@@ -240,15 +243,29 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned);
+
+-void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
++void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf)
+ {
+ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
+
+ dma_resv_lock(dmabuf->resv, NULL);
++ if (umem_dmabuf->revoked)
++ goto end;
+ ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+- if (umem_dmabuf->pinned)
++ if (umem_dmabuf->pinned) {
+ dma_buf_unpin(umem_dmabuf->attach);
++ umem_dmabuf->pinned = 0;
++ }
++ umem_dmabuf->revoked = 1;
++end:
+ dma_resv_unlock(dmabuf->resv);
++}
++EXPORT_SYMBOL(ib_umem_dmabuf_revoke);
++
++void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
++{
++ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
++
++ ib_umem_dmabuf_revoke(umem_dmabuf);
+
+ dma_buf_detach(dmabuf, umem_dmabuf->attach);
+ dma_buf_put(dmabuf);
+diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
+index 3441ba9f2a0daf..3ec9f1deca7db4 100644
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -38,6 +38,7 @@ struct ib_umem_dmabuf {
+ unsigned long last_sg_trim;
+ void *private;
+ u8 pinned : 1;
++ u8 revoked : 1;
+ };
+
+ static inline struct ib_umem_dmabuf *to_ib_umem_dmabuf(struct ib_umem *umem)
+@@ -130,6 +131,7 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);
+ void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf);
++void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
+
+ int ib_umem_check_rereg(struct ib_umem *umem, int flags, int new_access_flags);
+
+@@ -191,6 +193,7 @@ static inline int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
+ }
+ static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) { }
+ static inline void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) { }
++static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {}
+
+ static inline int ib_umem_check_rereg(struct ib_umem *umem, int flags,
+ int new_access_flags)
+--
+2.53.0
+
--- /dev/null
+From 05eba777f42bb9fcb1b3bf363f5256bd87f8c64d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 17:08:23 +0000
+Subject: RDMA/umem: Move umem dmabuf revoke logic into helper function
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit 797291a66ce346c96114b72222fc290d402da005 ]
+
+This same logic will eventually be reused from within the
+invalidate_mappings callback which already has the dma_resv_lock
+held, so break it out into a separate function so it can be reused.
+
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Link: https://patch.msgid.link/20260305170826.3803155-3-jmoroni@google.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/umem_dmabuf.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
+index acb0922a786131..be5977daafa1de 100644
+--- a/drivers/infiniband/core/umem_dmabuf.c
++++ b/drivers/infiniband/core/umem_dmabuf.c
+@@ -198,6 +198,22 @@ static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_ops = {
+ .move_notify = ib_umem_dmabuf_unsupported_move_notify,
+ };
+
++static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
++{
++ struct ib_umem_dmabuf *umem_dmabuf = attach->importer_priv;
++
++ dma_resv_assert_held(attach->dmabuf->resv);
++
++ if (umem_dmabuf->revoked)
++ return;
++ ib_umem_dmabuf_unmap_pages(umem_dmabuf);
++ if (umem_dmabuf->pinned) {
++ dma_buf_unpin(umem_dmabuf->attach);
++ umem_dmabuf->pinned = 0;
++ }
++ umem_dmabuf->revoked = 1;
++}
++
+ static struct ib_umem_dmabuf *
+ ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
+ struct device *dma_device,
+@@ -265,15 +281,7 @@ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf)
+ struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
+
+ dma_resv_lock(dmabuf->resv, NULL);
+- if (umem_dmabuf->revoked)
+- goto end;
+- ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+- if (umem_dmabuf->pinned) {
+- dma_buf_unpin(umem_dmabuf->attach);
+- umem_dmabuf->pinned = 0;
+- }
+- umem_dmabuf->revoked = 1;
+-end:
++ ib_umem_dmabuf_revoke_locked(umem_dmabuf->attach);
+ dma_resv_unlock(dmabuf->resv);
+ }
+ EXPORT_SYMBOL(ib_umem_dmabuf_revoke);
+--
+2.53.0
+
--- /dev/null
+From ec3120c916d5695a70e5046d07563dac4d5d76b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 17:09:45 +0200
+Subject: sched/vtime: Get rid of generic vtime_task_switch() implementation
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 89d6910cc562ab34d1f1c08f3cf0a9700b8bf2c4 ]
+
+The generic vtime_task_switch() implementation gets built only
+if __ARCH_HAS_VTIME_TASK_SWITCH is not defined, but requires an
+architecture to implement arch_vtime_task_switch() callback at
+the same time, which is confusing.
+
+Further, arch_vtime_task_switch() is implemented for 32-bit PowerPC
+architecture only and vtime_task_switch() generic variant is rather
+superfluous.
+
+Simplify the whole vtime_task_switch() wiring by moving the existing
+generic implementation to PowerPC.
+
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/2cb6e3caada93623f6d4f78ad938ac6cd0e2fda8.1712760275.git.agordeev@linux.ibm.com
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/cputime.h | 13 -------------
+ arch/powerpc/kernel/time.c | 22 ++++++++++++++++++++++
+ kernel/sched/cputime.c | 13 -------------
+ 3 files changed, 22 insertions(+), 26 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
+index 4961fb38e4385f..aff858ca99c05d 100644
+--- a/arch/powerpc/include/asm/cputime.h
++++ b/arch/powerpc/include/asm/cputime.h
+@@ -32,23 +32,10 @@
+ #ifdef CONFIG_PPC64
+ #define get_accounting(tsk) (&get_paca()->accounting)
+ #define raw_get_accounting(tsk) (&local_paca->accounting)
+-static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+
+ #else
+ #define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
+ #define raw_get_accounting(tsk) get_accounting(tsk)
+-/*
+- * Called from the context switch with interrupts disabled, to charge all
+- * accumulated times to the current process, and to prepare accounting on
+- * the next process.
+- */
+-static inline void arch_vtime_task_switch(struct task_struct *prev)
+-{
+- struct cpu_accounting_data *acct = get_accounting(current);
+- struct cpu_accounting_data *acct0 = get_accounting(prev);
+-
+- acct->starttime = acct0->starttime;
+-}
+ #endif
+
+ /*
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index dda35c404a6761..7fce6adb6f05fd 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -354,6 +354,28 @@ void vtime_flush(struct task_struct *tsk)
+ acct->hardirq_time = 0;
+ acct->softirq_time = 0;
+ }
++
++/*
++ * Called from the context switch with interrupts disabled, to charge all
++ * accumulated times to the current process, and to prepare accounting on
++ * the next process.
++ */
++void vtime_task_switch(struct task_struct *prev)
++{
++ if (is_idle_task(prev))
++ vtime_account_idle(prev);
++ else
++ vtime_account_kernel(prev);
++
++ vtime_flush(prev);
++
++ if (!IS_ENABLED(CONFIG_PPC64)) {
++ struct cpu_accounting_data *acct = get_accounting(current);
++ struct cpu_accounting_data *acct0 = get_accounting(prev);
++
++ acct->starttime = acct0->starttime;
++ }
++}
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
+index b453f8a6a7c764..4feef0d4e4494d 100644
+--- a/kernel/sched/cputime.c
++++ b/kernel/sched/cputime.c
+@@ -424,19 +424,6 @@ static inline void irqtime_account_process_tick(struct task_struct *p, int user_
+ */
+ #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+
+-# ifndef __ARCH_HAS_VTIME_TASK_SWITCH
+-void vtime_task_switch(struct task_struct *prev)
+-{
+- if (is_idle_task(prev))
+- vtime_account_idle(prev);
+- else
+- vtime_account_kernel(prev);
+-
+- vtime_flush(prev);
+- arch_vtime_task_switch(prev);
+-}
+-# endif
+-
+ void vtime_account_irq(struct task_struct *tsk, unsigned int offset)
+ {
+ unsigned int pc = irq_count() - offset;
+--
+2.53.0
+
--- /dev/null
+From e760d764bd4310ffba7ec96600b727d9b46788a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index d943bb454b1769..5baf98eac3db9d 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -322,7 +322,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
--- /dev/null
+From 606adfd90c63f599ab60a5d50e3648d42a708b54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:27:36 +0530
+Subject: selftests/alsa: Fix memory leak in find_controls error path
+
+From: Malaya Kumar Rout <malayarout91@gmail.com>
+
+[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
+
+In find_controls(), card_data is allocated with malloc() but when
+snd_ctl_open_lconf() fails, the code jumps to next_card without
+freeing the allocated memory. This results in a memory leak for
+each card where snd_ctl_open_lconf() fails.
+
+Add free(card_data) before goto next_card to ensure proper cleanup
+of the allocated memory in the error path.
+
+Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
+Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
+Link: https://patch.msgid.link/20260704105736.94874-1-malayarout91@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/alsa/mixer-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
+index df942149c6f6c5..6fe4be43072fb1 100644
+--- a/tools/testing/selftests/alsa/mixer-test.c
++++ b/tools/testing/selftests/alsa/mixer-test.c
+@@ -82,6 +82,7 @@ static void find_controls(void)
+ if (err < 0) {
+ ksft_print_msg("Failed to get hctl for card %d: %s\n",
+ card, snd_strerror(err));
++ free(card_data);
+ goto next_card;
+ }
+
+--
+2.53.0
+
input-ims-pcu-fix-heap-buffer-overflow-in-ims_pcu_pr.patch
input-ims-pcu-fix-logic-error-in-packet-reset.patch
mm-refactor-mm_access-to-not-return-null.patch
+arm64-tegra-fix-cpu-compatible-string-to-cortex-a78a.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+rdma-cma-fix-hardware-address-comparison-length-in-n.patch
+rdma-umem-add-support-for-creating-pinned-dmabuf-ume.patch
+rdma-umem-introduce-an-option-to-revoke-dmabuf-umem.patch
+rdma-umem-add-ib_umem_dmabuf_get_pinned_and_lock-hel.patch
+rdma-umem-move-umem-dmabuf-revoke-logic-into-helper-.patch
+rdma-umem-add-pinned-revocable-dmabuf-import-interfa.patch
+rdma-umem-add-helpers-for-umem-dmabuf-revoke-lock.patch
+rdma-irdma-prevent-rereg_mr-for-non-mem-regions.patch
+rdma-erdma-initialize-ret-for-empty-receive-wr-lists.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-only-check-attrs-cap.max_send_wr-in-siw_cre.patch
+rdma-siw-publish-qp-after-initialization.patch
+mtd-fix-double-free-and-warn_on-in-add_mtd_device-er.patch
+selftests-alsa-fix-memory-leak-in-find_controls-erro.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm6-clear-dst.dev-on-error-to-avoid-double-netdev_.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-nl80211-free-rnr-data-on-mbssid-mismatch.patch
+wifi-nl80211-validate-nested-mbssid-ie-blobs.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-amd-ps-fix-wrong-acp-version-string-in-pci_requ.patch
+asoc-cs42l43-correct-report-for-forced-microphone-ja.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-use-platform_get_irq.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+bluetooth-mgmt-fix-locking-in-unpair_device-disconne.patch
+bluetooth-mgmt-hold-reference-for-hci_conn-in-mgmt_p.patch
+bluetooth-hci_qca-clear-memdump-state-on-invalid-dum.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+sched-vtime-get-rid-of-generic-vtime_task_switch-imp.patch
+powerpc-time-prepare-to-stop-elapsing-in-dynticks-id.patch
+powerpc-vtime-initialize-starttime-at-boot-for-nativ.patch
+bpf-sockmap-reject-unhashed-udp-sockets-on-sockmap-u.patch
+can-j1939-fix-lockless-local-destination-check.patch
+ksmbd-pin-conn-during-async-oplock-break-notificatio.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From e71bc2b578a8a2893f421fb3df44389b5260f02e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index c66b02f67d3391..8a15694c1bbb56 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3417,6 +3417,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3453,13 +3454,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3476,11 +3485,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 83ac3b585e11ff08709d134ee8a6dfb2ebcd2557 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index a4d0db371c8976..1ab0f501017bcf 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4458,6 +4458,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4471,7 +4472,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From 81d3347cdac3e5a2bf1815c117929b03cdeb29b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index b12508188a18d2..c978e6252f7a1e 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -243,7 +243,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 6326f62ad46a6e24a355710b83ad31096acaf579 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index d07c4baa32d9f4..800fbfd5919491 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1132,6 +1132,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From d4f7b8d1257d12d4ef01df5b7dbf3f2dfeadbb59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index f9de0057085f93..678bbe5bf455fe 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From cffe19106d039a5183064a5b79d9b0e282a72db9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 93dac673f2a348..545f7ecaad76ff 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -309,7 +309,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 482f7c81a1f2ca59fe0eed0e7516b21dfd60e572 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 77cb1de9fc13b4..f9de0057085f93 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -188,6 +188,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -240,6 +241,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -249,10 +258,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 7d815d5b5e5fbdca7f8727b3908df41a9d1fe49e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index 9e9ff0cb724cac..a1eb69efecc6d1 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6172,6 +6172,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6184,16 +6186,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From e451f9c756147bf5ac33d52c298d1c8586f77f18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 964ff284138ac3de75248167174db221ee1b8b07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index c8c53f4d1bdbfa..d4a554d6d5de5a 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -591,6 +591,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -598,10 +599,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From 73958f77f62251ac2f51359dd3f08b18eda0dabf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index bf12ff0ab06ab3..c9bfea77d0ecae 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -6383,6 +6383,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From 1d2b31c2d0bf39544c456f779a058b1f7da111d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 19:22:09 +0800
+Subject: wifi: nl80211: free RNR data on MBSSID mismatch
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
+
+nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR
+entries than MBSSID entries.
+
+The rejected RNR allocation has not been attached to the beacon data yet,
+so free it before returning the error.
+
+Fixes: dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260610112208.1308-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index e4a490d12b504e..15c8f98bf5e235 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5651,8 +5651,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (IS_ERR(rnr))
+ return PTR_ERR(rnr);
+
+- if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
++ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
++ kfree(rnr);
+ return -EINVAL;
++ }
+
+ bcn->rnr_ies = rnr;
+ }
+--
+2.53.0
+
--- /dev/null
+From f86c2031b04eac3fa2a51e6a16d42894ef38cfce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:55 +0800
+Subject: wifi: nl80211: validate nested MBSSID IE blobs
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
+
+Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed
+information-element stream before storing it for beacon construction.
+
+RNR parsing already validates each nested blob with validate_ie_attr()
+before storing it. Apply the same syntactic IE validation to MBSSID
+entries before counting and copying their data and length pointers.
+
+Fixes: dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-3-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 15c8f98bf5e235..93dac673f2a348 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5453,7 +5453,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
+ }
+
+ static struct cfg80211_mbssid_elems *
+-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
++nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
++ struct netlink_ext_ack *extack)
+ {
+ struct nlattr *nl_elems;
+ struct cfg80211_mbssid_elems *elems;
+@@ -5464,6 +5465,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+ return ERR_PTR(-EINVAL);
+
+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
++ int ret;
++
++ ret = validate_ie_attr(nl_elems, extack);
++ if (ret)
++ return ERR_PTR(ret);
++
+ if (num_elems >= 255)
+ return ERR_PTR(-EINVAL);
+ num_elems++;
+@@ -5635,7 +5642,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
+ struct cfg80211_mbssid_elems *mbssid =
+ nl80211_parse_mbssid_elems(&rdev->wiphy,
+- attrs[NL80211_ATTR_MBSSID_ELEMS]);
++ attrs[NL80211_ATTR_MBSSID_ELEMS],
++ extack);
+
+ if (IS_ERR(mbssid))
+ return PTR_ERR(mbssid);
+--
+2.53.0
+
--- /dev/null
+From b47db3ef7c7e22eecc5e1fb20fcd8f4e7cfeb45e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 2deb1bb54f24bd..dc7bf54e30bba1 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From b1ed50c32e174abe8cff828a2e6b1a98de44820e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 7eaaaf56e631a0..00d9693c13ae72 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1298,8 +1298,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 3003f24df89f9b024e81ee781e811ab56c3fac41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 01:05:16 +0000
+Subject: xfrm6: clear dst.dev on error to avoid double netdev_put in
+ xfrm6_fill_dst()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
+
+On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst()
+releases the device reference with netdev_put() but leaves
+xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev)
+again, so the same net_device reference is released twice, underflowing
+its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for
+<dev> to become free").
+
+Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM
+device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in
+net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
+
+ ref_tracker: reference already released.
+ ref_tracker: allocated in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
+ ...
+ udpv6_sendmsg (net/ipv6/udp.c:1696)
+ ...
+ ref_tracker: freed in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
+ ...
+ WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
+ dst_destroy (net/core/dst.c:115)
+ rcu_core
+ handle_softirqs
+ ...
+
+Fixes: 84c4a9dfbf43 ("xfrm6: release dev before returning error")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index e5d76e782b9613..6bf22fd9cd3802 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+ if (!xdst->u.rt6.rt6i_idev) {
+ netdev_put(dev, &xdst->u.dst.dev_tracker);
++ xdst->u.dst.dev = NULL;
+ return -ENODEV;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 534e93aa75419726d993dc58b2213954a231e9b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 08:13:05 -0700
+Subject: accel/amdxdna: Fix use-after-free of mm_struct in job scheduler
+
+From: Lizhi Hou <lizhi.hou@amd.com>
+
+[ Upstream commit faebb7ba1ac65fa5810b640df02ce04e509fdc11 ]
+
+amdxdna_cmd_submit() stores current->mm in job->mm without holding any
+reference. aie2_sched_job_run() later access job->mm from the DRM
+scheduler worker thread. With only a raw pointer and no structural
+reference, the mm_struct can be freed before the scheduler runs the job.
+
+Fix this by calling mmgrab() to hold a structural mm_count reference for
+the lifetime of the job, paired with mmdrop() in every cleanup path.
+
+Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
+Reviewed-by: Max Zhen <max.zhen@amd.com>
+Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
+Link: https://patch.msgid.link/20260716151305.1595780-1-lizhi.hou@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/amdxdna/amdxdna_ctx.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c
+index 5315466f137b55..f6fece060dfedf 100644
+--- a/drivers/accel/amdxdna/amdxdna_ctx.c
++++ b/drivers/accel/amdxdna/amdxdna_ctx.c
+@@ -483,6 +483,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job)
+ amdxdna_arg_bos_put(job);
+ amdxdna_gem_put_obj(job->cmd_bo);
+ dma_fence_put(job->fence);
++ mmdrop(job->mm);
+ }
+
+ int amdxdna_cmd_submit(struct amdxdna_client *client,
+@@ -549,6 +550,7 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
+
+ job->hwctx = hwctx;
+ job->mm = current->mm;
++ mmgrab(job->mm);
+
+ job->fence = amdxdna_fence_create(hwctx);
+ if (!job->fence) {
+@@ -583,6 +585,8 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
+ cmd_put:
+ amdxdna_gem_put_obj(job->cmd_bo);
+ free_job:
++ if (job->mm)
++ mmdrop(job->mm);
+ kfree(job);
+ return ret;
+ }
+--
+2.53.0
+
--- /dev/null
+From e9a808c7a6224d4309339a7fe8f4ea2937a9a006 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 12:13:31 +0200
+Subject: accel/ivpu: Fix wrong register read in LNL failure diagnostics
+
+From: Karol Wachowski <karol.wachowski@linux.intel.com>
+
+[ Upstream commit e4159045c2704dfe146f0ccb0445d9d074cd6882 ]
+
+diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of
+VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a
+different register with a different bit layout, so failure diagnostics
+decoded the wrong register and reported a bogus error cause.
+Read the LNL interrupt status register instead.
+
+Fixes: 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
+Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Link: https://patch.msgid.link/20260710101331.1899505-1-karol.wachowski@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c
+index 06e65c59261854..992addabbd3c65 100644
+--- a/drivers/accel/ivpu/ivpu_hw_btrs.c
++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c
+@@ -861,7 +861,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev)
+
+ static void diagnose_failure_lnl(struct ivpu_device *vdev)
+ {
+- u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
++ u32 reg = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) {
+ ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
+--
+2.53.0
+
--- /dev/null
+From 10c485c077b92499065e064d4a4b3988484786d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 02:19:31 +0800
+Subject: ALSA: usb-audio: Fix imbalance per-channel volume of sticky mixers
+
+From: Rong Zhang <i@rong.moe>
+
+[ Upstream commit ea588e4c7484ea883d3dab308f1f2c2f0f51f7d6 ]
+
+I accidentally made an off-by-a-line mistake when mimicking other code
+paths that set all channels. The mistake breaks sticky mixers with
+multiple channels.
+
+I didn't realize this mistake at that time, as my device's mixer is
+single-channel.
+
+Fix it, so that per-channel volume of sticky mixers is balanced.
+
+Fixes: aa2f4addab44 ("ALSA: usb-audio: Set the value of potential sticky mixers to maximum")
+Signed-off-by: Rong Zhang <i@rong.moe>
+Link: https://patch.msgid.link/20260706-uac-sticky-channels-fix-v1-1-92741c538283@rong.moe
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index fb37bb8ad9a9a6..dbcefcaf7c3612 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -1447,8 +1447,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
+ if (!cval->cmask) {
+ snd_usb_set_cur_mix_value(cval, 0, 0, cval->max);
+ } else {
++ idx = 0;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+- idx = 0;
+ if (cval->cmask & BIT(i)) {
+ snd_usb_set_cur_mix_value(cval, i + 1, idx, cval->max);
+ idx++;
+--
+2.53.0
+
--- /dev/null
+From 08edfe85ebd7fa634caac260f044b6cb671c3f4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:56:06 +0200
+Subject: ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
+
+Salvador reported that the recent fix for applying the DSD quirk to
+Musical Fidelity devices broke for his M6s DAC model (2772:0502).
+
+Although this is basically a firmware bug, the model in question is
+fairly old, and no further firmware update can be expected, so it'd be
+better to address in the driver side.
+
+As an ad hoc workaround, skip the DSD quirk for this device by adding
+an empty quirk entry of 2772:0502; this essentially skips the later
+DSD quirk entry by the match with the vendor 2772.
+
+Fixes: da3a7efff64e ("ALSA: usb-audio: Update for native DSD support quirks")
+Reported-by: Salvador Blaya <tiniebla6@gmail.com>
+Closes: https://lore.kernel.org/CAOdyq+qFaqCh=tK_wNnA64hv5pQuA1Y09ANxQ=xK8yR-t4mf9Q@mail.gmail.com
+Tested-by: Salvador Blaya <tiniebla6@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260709095614.1418838-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index ed66e2af95143b..33eb8be48af876 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2457,6 +2457,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ QUIRK_FLAG_DSD_RAW),
+ DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
++ DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
++ 0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
+--
+2.53.0
+
--- /dev/null
+From 94a1e1206bbe78c56a3d4eb300cd922a3e094380 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 16:15:34 +0530
+Subject: arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
+
+The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the
+compatible string for all CPU nodes to match the actual hardware.
+
+Tegra234 hardware reports:
+ # head /proc/cpuinfo | egrep 'implementer|part'
+ CPU implementer : 0x41
+ CPU part : 0xd42
+
+Which maps to (from arch/arm64/include/asm/cputype.h):
+ #define ARM_CPU_IMP_ARM 0x41
+ #define ARM_CPU_PART_CORTEX_A78AE 0xD42
+
+Fixes: a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 18220cdac9f9bb..eda23431ed05ea 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -5339,7 +5339,7 @@ cpus {
+ #size-cells = <0>;
+
+ cpu0_0: cpu@0 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00000>;
+
+@@ -5358,7 +5358,7 @@ cpu0_0: cpu@0 {
+ };
+
+ cpu0_1: cpu@100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00100>;
+
+@@ -5377,7 +5377,7 @@ cpu0_1: cpu@100 {
+ };
+
+ cpu0_2: cpu@200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00200>;
+
+@@ -5396,7 +5396,7 @@ cpu0_2: cpu@200 {
+ };
+
+ cpu0_3: cpu@300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x00300>;
+
+@@ -5415,7 +5415,7 @@ cpu0_3: cpu@300 {
+ };
+
+ cpu1_0: cpu@10000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10000>;
+
+@@ -5434,7 +5434,7 @@ cpu1_0: cpu@10000 {
+ };
+
+ cpu1_1: cpu@10100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10100>;
+
+@@ -5453,7 +5453,7 @@ cpu1_1: cpu@10100 {
+ };
+
+ cpu1_2: cpu@10200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10200>;
+
+@@ -5472,7 +5472,7 @@ cpu1_2: cpu@10200 {
+ };
+
+ cpu1_3: cpu@10300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x10300>;
+
+@@ -5491,7 +5491,7 @@ cpu1_3: cpu@10300 {
+ };
+
+ cpu2_0: cpu@20000 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20000>;
+
+@@ -5510,7 +5510,7 @@ cpu2_0: cpu@20000 {
+ };
+
+ cpu2_1: cpu@20100 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20100>;
+
+@@ -5529,7 +5529,7 @@ cpu2_1: cpu@20100 {
+ };
+
+ cpu2_2: cpu@20200 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20200>;
+
+@@ -5548,7 +5548,7 @@ cpu2_2: cpu@20200 {
+ };
+
+ cpu2_3: cpu@20300 {
+- compatible = "arm,cortex-a78";
++ compatible = "arm,cortex-a78ae";
+ device_type = "cpu";
+ reg = <0x20300>;
+
+--
+2.53.0
+
--- /dev/null
+From b05b9529f015915b7fc738d982aee21fc738ae07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 15:52:55 +0530
+Subject: arm64: tegra: Remove fallback compatible for GPCDMA
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit ee7863e43228a3143398dc5bbb943c9a735a8fca ]
+
+Remove the fallback compatible string "nvidia,tegra186-gpcdma" for GPCDMA
+in Tegra264. Tegra186 compatible cannot work on Tegra264 because of the
+register offset changes and absence of the reset property.
+
+Fixes: 65ef237e4810 ("arm64: tegra: Add Tegra264 support")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+index 2d8e7e37830ff2..3dfdd7bb28a911 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+@@ -3208,7 +3208,7 @@ agic_page5: interrupt-controller@99b0000 {
+ };
+
+ gpcdma: dma-controller@8400000 {
+- compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma";
++ compatible = "nvidia,tegra264-gpcdma";
+ reg = <0x0 0x08400000 0x0 0x210000>;
+ interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.53.0
+
--- /dev/null
+From d15e85a5b7a56f6c6b17e09828fea441c5b57c62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 18:02:47 +0530
+Subject: ASoC: amd: acp: Fix linker error with SDCA quirks
+
+From: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+
+[ Upstream commit dbbb5bc5176e36b13aa22e2174ab4779c5ae1dca ]
+
+Fix undefined reference to `snd_soc_acpi_amd_sdca_is_device_rt712_vb`
+linker error when CONFIG_SND_SOC_ACPI_AMD_MATCH=y and
+CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS=m, which causes built-in code to
+reference a symbol only available in a module.
+
+Fix this by changing SND_SOC_ACPI_AMD_SDCA_QUIRKS from tristate to bool
+and compiling the quirks code directly into snd-soc-acpi-amd-match
+rather than as a separate module. This ensures the quirks symbols are
+always available at link time when the match tables reference them.
+
+Fixes: 10d366a846be ("ASoC: amd: acp: Fix Kconfig dependencies for SND_SOC_ACPI_AMD_SDCA_QUIRKS")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Tested-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Syed Saba Kareem <Syed.SabaKareem@amd.com>
+Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Link: https://patch.msgid.link/20260703123314.147977-1-syed.sabakareem@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/Kconfig | 10 +++++++---
+ sound/soc/amd/acp/Makefile | 3 +--
+ sound/soc/amd/acp/amd-acp70-acpi-match.c | 2 +-
+ sound/soc/amd/acp/soc-acpi-amd-sdca-quirks.c | 4 ----
+ 4 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig
+index 977e4f2a7a7015..a04c301df4d616 100644
+--- a/sound/soc/amd/acp/Kconfig
++++ b/sound/soc/amd/acp/Kconfig
+@@ -15,13 +15,17 @@ config SND_SOC_AMD_ACP_COMMON
+
+ config SND_SOC_ACPI_AMD_MATCH
+ tristate
+- select SND_SOC_ACPI_AMD_SDCA_QUIRKS if SND_SOC_SDCA
+ select SND_SOC_ACPI if ACPI
+
+ config SND_SOC_ACPI_AMD_SDCA_QUIRKS
+- tristate
+- depends on ACPI
++ bool "AMD ACPI SDCA quirks"
++ depends on SND_SOC_ACPI_AMD_MATCH
+ depends on SND_SOC_SDCA
++ depends on SND_SOC_ACPI_AMD_MATCH = m || SND_SOC_SDCA = y
++ default y
++ help
++ Enable SDCA quirk support for AMD ACPI match tables.
++ This is compiled into the snd-soc-acpi-amd-match module.
+
+ if SND_SOC_AMD_ACP_COMMON
+
+diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile
+index 81d23aded348d1..ab5f9dc871a677 100644
+--- a/sound/soc/amd/acp/Makefile
++++ b/sound/soc/amd/acp/Makefile
+@@ -24,10 +24,10 @@ snd-acp-mach-y := acp-mach-common.o
+ snd-acp-legacy-mach-y := acp-legacy-mach.o acp3x-es83xx/acp3x-es83xx.o
+ snd-acp-sof-mach-y := acp-sof-mach.o
+ snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o amd-acp70-acpi-match.o
++snd-soc-acpi-amd-match-$(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS) += soc-acpi-amd-sdca-quirks.o
+ snd-acp-sdw-mach-y := acp-sdw-mach-common.o
+ snd-acp-sdw-sof-mach-y += acp-sdw-sof-mach.o
+ snd-acp-sdw-legacy-mach-y += acp-sdw-legacy-mach.o
+-snd-soc-acpi-amd-sdca-quirks-y += soc-acpi-amd-sdca-quirks.o
+
+ obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
+ obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
+@@ -41,7 +41,6 @@ obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o
+ obj-$(CONFIG_SND_AMD_ASOC_ACP63) += snd-acp63.o
+ obj-$(CONFIG_SND_AMD_ASOC_ACP70) += snd-acp70.o
+
+-obj-$(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS) += snd-soc-acpi-amd-sdca-quirks.o
+ obj-$(CONFIG_SND_AMD_SOUNDWIRE_ACPI) += snd-amd-sdw-acpi.o
+ obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
+ obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
+diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c
+index 18f2918d4ada4d..9e97a805d0dffa 100644
+--- a/sound/soc/amd/acp/amd-acp70-acpi-match.c
++++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c
+@@ -775,5 +775,5 @@ MODULE_DESCRIPTION("AMD ACP7.0 & ACP7.1 tables and support for ACPI enumeration"
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+ #if IS_ENABLED(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS)
+-MODULE_IMPORT_NS("SND_SOC_ACPI_AMD_SDCA_QUIRKS");
++MODULE_IMPORT_NS("SND_SOC_SDCA");
+ #endif
+diff --git a/sound/soc/amd/acp/soc-acpi-amd-sdca-quirks.c b/sound/soc/amd/acp/soc-acpi-amd-sdca-quirks.c
+index 63bf9e3c0ae180..9248b6d09e76fe 100644
+--- a/sound/soc/amd/acp/soc-acpi-amd-sdca-quirks.c
++++ b/sound/soc/amd/acp/soc-acpi-amd-sdca-quirks.c
+@@ -35,8 +35,4 @@ bool snd_soc_acpi_amd_sdca_is_device_rt712_vb(void *arg)
+
+ return false;
+ }
+-EXPORT_SYMBOL_NS(snd_soc_acpi_amd_sdca_is_device_rt712_vb, "SND_SOC_ACPI_AMD_SDCA_QUIRKS");
+
+-MODULE_DESCRIPTION("ASoC ACPI AMD SDCA quirks");
+-MODULE_LICENSE("GPL");
+-MODULE_IMPORT_NS("SND_SOC_SDCA");
+--
+2.53.0
+
--- /dev/null
+From 4e02b9fa26267533105b03c809a6670dde9fc296 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:36 +0530
+Subject: ASoC: amd: ps: disable MSI on resume in ACP PCI driver
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 5893013efabb056399a01e267f410cf76eba25eb ]
+
+BIOS/firmware may re-enable MSI in PCI config space during system
+level resume even though this driver only uses legacy INTx interrupts.
+If MSI is left enabled with stale address/data registers, the device
+will write interrupts to a bogus address causing IOMMU IO_PAGE_FAULT
+and interrupt delivery failure.
+
+Clear the MSI Enable bit before reinitializing the ACP hardware on
+system level resume.
+
+Fixes: 491628388005 ("ASoC: amd: ps: add callback functions for acp pci driver pm ops")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-2-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index 9751cf0784a6db..cccf9d85c860f0 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -692,8 +692,37 @@ static int snd_acp_runtime_resume(struct device *dev)
+ return acp_hw_runtime_resume(dev);
+ }
+
++static void acp_disable_msi_on_resume(struct pci_dev *pdev)
++{
++ u16 control;
++
++ if (!pdev->msi_cap)
++ return;
++
++ pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &control);
++ if (control & PCI_MSI_FLAGS_ENABLE) {
++ dev_warn(&pdev->dev,
++ "ACP: MSI unexpectedly enabled after resume (flags=0x%04x), disabling\n",
++ control);
++ control &= ~PCI_MSI_FLAGS_ENABLE;
++ pci_write_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, control);
++ }
++}
++
+ static int snd_acp_resume(struct device *dev)
+ {
++ struct pci_dev *pdev = to_pci_dev(dev);
++
++ /*
++ * BIOS/firmware may re-enable MSI in PCI config space during
++ * system resume even though this driver only uses legacy INTx
++ * interrupts. If MSI is left enabled with stale address/data
++ * registers, the device will write interrupts to a bogus address
++ * causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.
++ * Explicitly clear the MSI Enable bit before reinitializing
++ * the ACP hardware.
++ */
++ acp_disable_msi_on_resume(pdev);
+ return acp_hw_resume(dev);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 98e764bd0446d581d488aba49f05583c1cfb7030 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:37 +0530
+Subject: ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
+
+The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was
+claimed with the stale name "AMD ACP6.2 audio" left over from the
+original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
+
+Fixes: 95e43a170bb1 ("ASoC: amd: add Pink Sardine ACP PCI driver")
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Link: https://patch.msgid.link/20260707060130.2514138-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index cccf9d85c860f0..edff7f274a39d5 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -601,7 +601,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
+ return -ENODEV;
+ }
+
+- ret = pci_request_regions(pci, "AMD ACP6.2 audio");
++ ret = pci_request_regions(pci, "AMD ACP6.3 audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+--
+2.53.0
+
--- /dev/null
+From bc718557f972039489caef02a195f2f565b6f66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 11:29:38 +0530
+Subject: ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit dec5aaa27603e1d7b426ce3504af6d1a62e4d444 ]
+
+The condition 'irq_flag | wake_irq_flag' uses bitwise OR to combine two
+integer flags that are used as booleans. Replace with logical OR '||' to
+correctly express the intended boolean check.
+
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
+Fixes: 7f91f012c1df0 ("ASoC: amd: ps: fix for irq handler return status")
+Link: https://patch.msgid.link/20260707060130.2514138-4-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/ps/pci-ps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
+index edff7f274a39d5..5e73fb20e152a0 100644
+--- a/sound/soc/amd/ps/pci-ps.c
++++ b/sound/soc/amd/ps/pci-ps.c
+@@ -248,7 +248,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
+ if (sdw_dma_irq_flag)
+ return IRQ_WAKE_THREAD;
+
+- if (irq_flag | wake_irq_flag)
++ if (irq_flag || wake_irq_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+--
+2.53.0
+
--- /dev/null
+From 748aaa8413eef1831915c4ef699d2f5c7ee30189 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 11:34:30 +0100
+Subject: ASoC: cs42l43: Correct report for forced microphone jack
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]
+
+Currently if the jack is forced to the microphone mode, it will report
+as line in. Correct the report to microphone.
+
+Fixes: fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20260708103430.1395207-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l43-jack.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c
+index 3e04e6897b1423..e88109979c1831 100644
+--- a/sound/soc/codecs/cs42l43-jack.c
++++ b/sound/soc/codecs/cs42l43-jack.c
+@@ -310,6 +310,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
+ #define CS42L43_JACK_ABSENT 0x0
+
+ #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
++#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
+ #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
+ #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
+ #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
+@@ -871,7 +872,7 @@ static const struct cs42l43_jack_override_mode {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+ .mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
+ CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
+- .report = CS42L43_JACK_LINEIN,
++ .report = CS42L43_JACK_MICROPHONE,
+ },
+ [CS42L43_JACK_RAW_OPTICAL] = {
+ .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
+--
+2.53.0
+
--- /dev/null
+From 6f4d1b8501480386ad445ae9ec70de68c98c5db4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 13:12:05 +0000
+Subject: ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on
+ start/stop
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
+
+The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
+AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
+vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
+it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
+producing the "machine gun noise" buffer underrun - on start when switching
+outputs, and on stop when playback ends. The latter is audible on devices
+with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
+
+The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
+both enable and disable (audio_hw_958_enable), and when reconfiguring
+(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
+reset before enabling the DCU on start, and before disabling on stop.
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sound/soc/meson/aiu-fifo-spdif.c b/sound/soc/meson/aiu-fifo-spdif.c
+index e0e00ec026dcc4..a9861c5d663745 100644
+--- a/sound/soc/meson/aiu-fifo-spdif.c
++++ b/sound/soc/meson/aiu-fifo-spdif.c
+@@ -24,6 +24,7 @@
+ #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
+ #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
+ #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
++#define AIU_RST_SOFT_958_FAST BIT(2)
+
+ #define AIU_FIFO_SPDIF_BLOCK 8
+
+@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, true);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
++ snd_soc_component_write(component, AIU_RST_SOFT,
++ AIU_RST_SOFT_958_FAST);
+ fifo_spdif_dcu_enable(component, false);
+ break;
+ default:
+--
+2.53.0
+
--- /dev/null
+From b263ffc1639adec6f61b34bc12229b6151d9bb5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:01:09 +0530
+Subject: ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after
+ lookup
+
+From: Uday Khare <udaykhare77@gmail.com>
+
+[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
+
+In tas2562_parse_dt(), the fallback lookup for the deprecated
+"shut-down" GPIO property is broken due to a missing pair of braces.
+
+The code intends to reset sdz_gpio to NULL only when the lookup
+returns an error that is not -EPROBE_DEFER (so the driver gracefully
+continues without a GPIO). However, without braces the statement:
+
+ tas2562->sdz_gpio = NULL;
+
+falls outside the IS_ERR() check and is executed unconditionally
+for every path through the if block, including a successful GPIO
+lookup.
+
+This means any device using the deprecated 'shut-down' DT property
+will always have sdz_gpio == NULL after probe, making the GPIO
+completely non-functional.
+
+Fix this by adding the missing braces to scope the NULL assignment
+inside the IS_ERR() branch, matching the pattern already used for
+the primary 'shutdown' GPIO lookup above.
+
+Fixes: f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
+Signed-off-by: Uday Khare <udaykhare77@gmail.com>
+Link: https://patch.msgid.link/20260706153109.10953-1-udaykhare77@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2562.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
+index ceb367ae05ba5a..adc4fdef3beed3 100644
+--- a/sound/soc/codecs/tas2562.c
++++ b/sound/soc/codecs/tas2562.c
+@@ -675,11 +675,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
+ if (tas2562->sdz_gpio == NULL) {
+ tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
+ GPIOD_OUT_HIGH);
+- if (IS_ERR(tas2562->sdz_gpio))
++ if (IS_ERR(tas2562->sdz_gpio)) {
+ if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+- tas2562->sdz_gpio = NULL;
++ tas2562->sdz_gpio = NULL;
++ }
+ }
+
+ if (tas2562->model_id == TAS2110)
+--
+2.53.0
+
--- /dev/null
+From 754fe8cf5f51e37886b6258fa2de2be131cb2c44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:26 -0700
+Subject: ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is
+ registered
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
+
+sata_dwc_enable_interrupts() is called before platform_get_irq() and
+ata_host_activate(), leaving the SATA controller's interrupt mask
+enabled without a registered handler. If a later step fails (irq
+request, phy init, etc.) or if the controller asserts an interrupt
+during probe, the irq line may fire with no handler, causing a
+spurious interrupt storm.
+
+Move sata_dwc_enable_interrupts() after ata_host_activate() so that
+interrupts are only unmasked once the handler is registered and the
+core is fully initialized.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 64cb544903d888..47313dd4757859 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ /* Save dev for later use in dev_xxx() routines */
+ hsdev->dev = dev;
+
+- /* Enable SATA Interrupts */
+- sata_dwc_enable_interrupts(hsdev);
+-
+ /* Get SATA interrupt number */
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ if (err)
+ dev_err(dev, "failed to activate host");
+
++ /* Enable SATA Interrupts */
++ sata_dwc_enable_interrupts(hsdev);
+ return 0;
+
+ error_out:
+--
+2.53.0
+
--- /dev/null
+From fdc75635ae5f6d9ef208424ab8561145bf31f7e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:27 -0700
+Subject: ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending
+ interrupts
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
+
+clear_interrupt_bit() ignores the bit argument and performs a
+read-write-back of the entire INTPR register. If INTPR uses standard
+Write-1-to-Clear semantics, this clears every pending interrupt bit,
+not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP)
+would be cleared together, silently losing the second event.
+
+Write only the specific bit to clear so that other pending interrupts
+are preserved.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index e9b821d6fd6362..6c062efa2c6fda 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)
+
+ static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
+ {
+- sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
+- sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
++ sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
+ }
+
+ static u32 qcmd_tag_to_mask(u8 tag)
+--
+2.53.0
+
--- /dev/null
+From 57a96ebee4277e64b7ce7277f2bff063655ea45b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:28 -0700
+Subject: ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion
+ bit-scanning
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
+
+The hand-rolled bit-scanning loop in the NCQ completion path has an
+infinite loop bug. When tag_mask has only high bits set (e.g.
+0x80000000), the inner while loop left-shifts tag_mask until it
+overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1
+stays 0, causing an infinite loop in hardirq context with a spinlock
+held.
+
+Replace the open-coded bit-scanning with __ffs() which correctly
+finds the least significant set bit and is bounded by the width of
+the argument.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 6c062efa2c6fda..cf723ef39d7cc2 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
+ status = ap->ops->sff_check_status(ap);
+ dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
+
+- tag = 0;
+ while (tag_mask) {
+- while (!(tag_mask & 0x00000001)) {
+- tag++;
+- tag_mask <<= 1;
+- }
+-
+- tag_mask &= (~0x00000001);
++ tag = __ffs(tag_mask);
++ tag_mask &= ~(1U << tag);
+ qc = ata_qc_from_tag(ap, tag);
+ if (unlikely(!qc)) {
+ dev_err(ap->dev, "failed to get qc");
+--
+2.53.0
+
--- /dev/null
+From f6b98de9710acfb29661706b194dbe3622761732 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 14:37:25 -0700
+Subject: ata: sata_dwc_460ex: use platform_get_irq()
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]
+
+Replace irq_of_parse_and_map() with platform_get_irq() in both
+sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred
+way to obtain IRQs for platform devices and provides better error
+reporting. Remove the now-unnecessary #include <linux/of_irq.h>.
+
+irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.
+
+Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.
+
+Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_dwc_460ex.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
+index 47313dd4757859..e9b821d6fd6362 100644
+--- a/drivers/ata/sata_dwc_460ex.c
++++ b/drivers/ata/sata_dwc_460ex.c
+@@ -19,7 +19,6 @@
+ #include <linux/device.h>
+ #include <linux/dmaengine.h>
+ #include <linux/of.h>
+-#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/libata.h>
+@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ struct sata_dwc_device *hsdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *np = dev->of_node;
+
+ hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL);
+ if (!hsdev->dma)
+@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
+ hsdev->dma->id = pdev->id;
+
+ /* Get SATA DMA interrupt number */
+- hsdev->dma->irq = irq_of_parse_and_map(np, 1);
+- if (!hsdev->dma->irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ hsdev->dma->irq = platform_get_irq(pdev, 1);
++ if (hsdev->dma->irq < 0)
++ return hsdev->dma->irq;
+
+ /* Get physical SATA DMA register base address */
+ hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1);
+@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {
+ static int sata_dwc_probe(struct platform_device *ofdev)
+ {
+ struct device *dev = &ofdev->dev;
+- struct device_node *np = dev->of_node;
+ struct sata_dwc_device *hsdev;
+ u32 idr, versionr;
+ char *ver = (char *)&versionr;
+@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev)
+ hsdev->dev = dev;
+
+ /* Get SATA interrupt number */
+- irq = irq_of_parse_and_map(np, 0);
+- if (!irq) {
+- dev_err(dev, "no SATA DMA irq\n");
+- return -ENODEV;
+- }
++ irq = platform_get_irq(ofdev, 0);
++ if (irq < 0)
++ return irq;
+
+ #ifdef CONFIG_SATA_DWC_OLD_DMA
+- if (!of_property_present(np, "dmas")) {
++ if (!of_property_present(dev->of_node, "dmas")) {
+ err = sata_dwc_dma_init_old(ofdev, hsdev);
+ if (err)
+ return err;
+--
+2.53.0
+
--- /dev/null
+From 06876535d5e4a7b59022cd10f826da7723370c4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 14:22:50 +0800
+Subject: Bluetooth: hci_qca: Clear memdump state on invalid dump size
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bf587a10c33e5571a299742e45bc18960b9912e7 ]
+
+qca_controller_memdump() allocates qca->qca_memdump before processing
+the first dump packet. For a sequence-zero packet it then disables IBS,
+marks memdump collection active, and reads the advertised dump size.
+
+If the controller reports a zero dump size, the error path frees the
+local qca_memdump object and returns without clearing qca->qca_memdump
+or undoing the collection state. A later memdump work item initializes
+its local pointer from qca->qca_memdump and skips allocation when that
+pointer is non-NULL, so it can operate on freed memory. The stale
+collection and IBS-disabled flags can also leave waiters or later
+transmit handling blocked behind an aborted dump.
+
+Clear the saved pointer and memdump state before returning from the
+invalid-size path, matching the cleanup used when hci_devcd_init() fails.
+
+A static analysis checker reported the stale memdump state, and manual
+source review confirmed the invalid-size failure path.
+
+Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 2444471956197b..bd29d422c2090a 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1088,6 +1088,10 @@ static void qca_controller_memdump(struct work_struct *work)
+ if (!(qca_memdump->ram_dump_size)) {
+ bt_dev_err(hu->hdev, "Rx invalid memdump size");
+ kfree(qca_memdump);
++ qca->qca_memdump = NULL;
++ qca->memdump_state = QCA_MEMDUMP_COLLECTED;
++ clear_and_wake_up_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
++ clear_bit(QCA_IBS_DISABLED, &qca->flags);
+ kfree_skb(skb);
+ mutex_unlock(&qca->hci_memdump_lock);
+ return;
+--
+2.53.0
+
--- /dev/null
+From 3b76f4ae01c39f0631c7f592759679774662af26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:40 +0300
+Subject: Bluetooth: hci_sync: extend conn_hash lookup critical sections
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit d5efd6e4b8b0634af6843178fe1a7dd2b2178a3d ]
+
+Using RCU-protected pointers outside the critical sections without
+refcount is incorrect and may result to UAF.
+
+Extend critical section to cover both hci_conn_hash lookup and use of
+the returned conn.
+
+Add surrounding rcu_read_lock() also when return value is not used, in
+preparation for RCU lockdep requirement to hci_lookup_le_connect().
+
+This avoids concurrent deletion of the conn before we are done
+dereferencing it.
+
+Also, make sure to hold hdev->lock when accessing hdev->accept_list.
+
+Fixes: 6d0417e4e1cf ("Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 42 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 39 insertions(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index a3df69bdec1e06..eb216d86a6ddf3 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -1054,14 +1054,19 @@ static int hci_set_random_addr_sync(struct hci_dev *hdev, bdaddr_t *rpa)
+ * In this kind of scenario skip the update and let the random
+ * address be updated at the next cycle.
+ */
++ rcu_read_lock();
++
+ if (bacmp(&hdev->random_addr, BDADDR_ANY) &&
+ (hci_dev_test_flag(hdev, HCI_LE_ADV) ||
+ hci_lookup_le_connect(hdev))) {
+ bt_dev_dbg(hdev, "Deferring random address update");
+ hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
++ rcu_read_unlock();
+ return 0;
+ }
+
++ rcu_read_unlock();
++
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_RANDOM_ADDR,
+ 6, rpa, HCI_CMD_TIMEOUT);
+ }
+@@ -2647,12 +2652,17 @@ static int hci_pause_addr_resolution(struct hci_dev *hdev)
+ /* Cannot disable addr resolution if scanning is enabled or
+ * when initiating an LE connection.
+ */
++ rcu_read_lock();
++
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+ hci_lookup_le_connect(hdev)) {
++ rcu_read_unlock();
+ bt_dev_err(hdev, "Command not allowed when scan/LE connect");
+ return -EPERM;
+ }
+
++ rcu_read_unlock();
++
+ /* Cannot disable addr resolution if advertising is enabled. */
+ err = hci_pause_advertising_sync(hdev);
+ if (err) {
+@@ -2790,6 +2800,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
+ struct hci_conn *conn;
+
++ rcu_read_lock();
++
+ conn = hci_conn_hash_lookup_create_pa_sync(hdev);
+ if (conn) {
+ struct conn_params pa;
+@@ -2799,6 +2811,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ bacpy(&pa.addr, &conn->dst);
+ pa.addr_type = conn->dst_type;
+
++ rcu_read_unlock();
++
+ /* Clear first since there could be addresses left
+ * behind.
+ */
+@@ -2808,6 +2822,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ err = hci_le_add_accept_list_sync(hdev, &pa,
+ &num_entries);
+ goto done;
++ } else {
++ rcu_read_unlock();
+ }
+ }
+
+@@ -2818,10 +2834,13 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ * the controller.
+ */
+ list_for_each_entry_safe(b, t, &hdev->le_accept_list, list) {
+- if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type))
++ rcu_read_lock();
++
++ if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) {
++ rcu_read_unlock();
+ continue;
++ }
+
+- /* Pointers not dereferenced, no locks needed */
+ pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns,
+ &b->bdaddr,
+ b->bdaddr_type);
+@@ -2829,6 +2848,8 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
+ &b->bdaddr,
+ b->bdaddr_type);
+
++ rcu_read_unlock();
++
+ /* If the device is not likely to connect or report,
+ * remove it from the acceptlist.
+ */
+@@ -2955,6 +2976,8 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
+ if (sent) {
+ struct hci_conn *conn;
+
++ rcu_read_lock();
++
+ conn = hci_conn_hash_lookup_ba(hdev, PA_LINK,
+ &sent->bdaddr);
+ if (conn) {
+@@ -2979,8 +3002,12 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
+ phy++;
+ }
+
++ rcu_read_unlock();
++
+ if (num_phy)
+ goto done;
++ } else {
++ rcu_read_unlock();
+ }
+ }
+ }
+@@ -3231,12 +3258,16 @@ int hci_update_passive_scan_sync(struct hci_dev *hdev)
+ /* If there is at least one pending LE connection, we should
+ * keep the background scan running.
+ */
++ bool exists;
+
+ /* If controller is connecting, we should not start scanning
+ * since some controllers are not able to scan and connect at
+ * the same time.
+ */
+- if (hci_lookup_le_connect(hdev))
++ rcu_read_lock();
++ exists = hci_lookup_le_connect(hdev);
++ rcu_read_unlock();
++ if (exists)
+ return 0;
+
+ bt_dev_dbg(hdev, "start background scanning");
+@@ -3454,6 +3485,7 @@ int hci_write_fast_connectable_sync(struct hci_dev *hdev, bool enable)
+ }
+
+ static bool disconnected_accept_list_entries(struct hci_dev *hdev)
++ __must_hold(&hdev->lock)
+ {
+ struct bdaddr_list *b;
+
+@@ -3494,12 +3526,16 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ if (hdev->scanning_paused)
+ return 0;
+
++ hci_dev_lock(hdev);
++
+ if (hci_dev_test_flag(hdev, HCI_CONNECTABLE) ||
+ disconnected_accept_list_entries(hdev))
+ scan = SCAN_PAGE;
+ else
+ scan = SCAN_DISABLED;
+
++ hci_dev_unlock(hdev);
++
+ if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
+ scan |= SCAN_INQUIRY;
+
+--
+2.53.0
+
--- /dev/null
+From 305cb1f34d429c624071013089491cfae795d070 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:43 +0300
+Subject: Bluetooth: hci_sync: hold hdev->lock for hci_conn_params lookups
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit c363202ec841df36421ec280eea3d5f94f556143 ]
+
+hci_conn_params_lookup requires hdev->lock be held, otherwise the list
+iteration or param access is not safe.
+
+Hold hdev->lock for params lookups in hci_sync.
+
+Fixes: c530569adc19 ("Bluetooth: hci_core: Introduce HCI_CONN_FLAG_PAST")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index eb216d86a6ddf3..d20f69858d22d6 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6679,6 +6679,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
+ if (!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES))
+ hci_pause_advertising_sync(hdev);
+
++ hci_dev_lock(hdev);
++
+ params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+ if (params) {
+ conn->le_conn_min_interval = params->conn_min_interval;
+@@ -6692,6 +6694,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
+ conn->le_supv_timeout = hdev->le_supv_timeout;
+ }
+
++ hci_dev_unlock(hdev);
++
+ /* If controller is scanning, we stop it since some controllers are
+ * not able to scan and connect at the same time. Also set the
+ * HCI_LE_SCAN_INTERRUPTED flag so that the command complete
+@@ -7249,13 +7253,13 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
+ }
+
+ static int hci_le_past_params_sync(struct hci_dev *hdev, struct hci_conn *conn,
+- struct hci_conn *acl, struct bt_iso_qos *qos)
++ u16 acl_handle, struct bt_iso_qos *qos)
+ {
+ struct hci_cp_le_past_params cp;
+ int err;
+
+ memset(&cp, 0, sizeof(cp));
+- cp.handle = cpu_to_le16(acl->handle);
++ cp.handle = cpu_to_le16(acl_handle);
+ /* An HCI_LE_Periodic_Advertising_Sync_Transfer_Received event is sent
+ * to the Host. HCI_LE_Periodic_Advertising_Report events will be
+ * enabled with duplicate filtering enabled.
+@@ -7320,16 +7324,28 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)
+ * 2. Check if that HCI_CONN_FLAG_PAST has been set which indicates that
+ * user really intended to use PAST.
+ */
++ hci_dev_lock(hdev);
++
+ le = hci_conn_hash_lookup_le(hdev, &conn->dst, conn->dst_type);
+ if (le) {
+ struct hci_conn_params *params;
++ hci_conn_flags_t flags = 0;
++ u16 le_handle = le->handle;
+
+ params = hci_conn_params_lookup(hdev, &le->dst, le->dst_type);
+- if (params && params->flags & HCI_CONN_FLAG_PAST) {
+- err = hci_le_past_params_sync(hdev, conn, le, qos);
++ if (params)
++ flags = params->flags;
++
++ hci_dev_unlock(hdev);
++
++ if (flags & HCI_CONN_FLAG_PAST) {
++ err = hci_le_past_params_sync(hdev, conn, le_handle,
++ qos);
+ if (!err)
+ goto done;
+ }
++ } else {
++ hci_dev_unlock(hdev);
+ }
+
+ /* SID has not been set listen for HCI_EV_LE_EXT_ADV_REPORT to update
+--
+2.53.0
+
--- /dev/null
+From 9ab9ff78b3434912746ce4711209af67d70ad2f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:41 +0300
+Subject: Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 16cd66443957e4ad42155c6fec401012f600c6f8 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF.
+
+Take hdev->lock for hci_conn lookup and hci_abort_conn(). Don't use RCU
+to ensure the conn is fully initialized at this point.
+
+Fixes: 227a0cdf4a028 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index f24b7bbfcb5b6f..186850538a8bb5 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3094,6 +3094,8 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_unpair_device *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3101,6 +3103,11 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return 0;
+
+@@ -3108,6 +3115,7 @@ static int unpair_device_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+@@ -3255,6 +3263,8 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ struct mgmt_cp_disconnect *cp = cmd->param;
+ struct hci_conn *conn;
+
++ hci_dev_lock(hdev);
++
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+ &cp->addr.bdaddr);
+@@ -3262,6 +3272,11 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ conn = hci_conn_hash_lookup_le(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
++ if (conn)
++ hci_conn_get(conn);
++
++ hci_dev_unlock(hdev);
++
+ if (!conn)
+ return -ENOTCONN;
+
+@@ -3269,6 +3284,7 @@ static int disconnect_sync(struct hci_dev *hdev, void *data)
+ * will clean up the connection no matter the error.
+ */
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
++ hci_conn_put(conn);
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From b030faa3c4733f0e5767b1b10074a6cf38326673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 11:23:42 +0300
+Subject: Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit da55f570191d5d72f10c607a7043b947eb05ea46 ]
+
+Dereferencing RCU-protected pointers outside critical sections is
+invalid and may lead to UAF. Use of hci_conn in hci_sync callbacks also
+needs to hold refcount to avoid UAF.
+
+Take appropriate locks for hci_conn lookups, and take refcount for
+hci_conn pointers stored in mgmt_pending_cmd so that the pointer stays
+valid.
+
+When accessing conn->state, ensure hdev->lock is held to avoid data
+race.
+
+Fixes: 7b445e220db9 ("Bluetooth: MGMT: Fix holding hci_conn reference while command is queued")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 186850538a8bb5..9604c3025f7b7c 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7407,6 +7407,9 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
+ rp.max_tx_power = HCI_TX_POWER_INVALID;
+ }
+
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
+ &rp, sizeof(rp));
+
+@@ -7421,6 +7424,8 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ int err;
+ __le16 handle;
+
++ hci_dev_lock(hdev);
++
+ /* Make sure we are still connected */
+ if (cp->addr.type == BDADDR_BREDR)
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+@@ -7428,12 +7433,16 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
+ else
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
+
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ handle = cpu_to_le16(conn->handle);
+
++ hci_dev_unlock(hdev);
++
+ /* Refresh RSSI each time */
+ err = hci_read_rssi_sync(hdev, handle);
+
+@@ -7567,6 +7576,9 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
+ }
+
+ complete:
++ if (conn)
++ hci_conn_put(conn);
++
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
+ sizeof(rp));
+
+@@ -7583,15 +7595,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
+ memset(&hci_cp, 0, sizeof(hci_cp));
+ hci_read_clock_sync(hdev, &hci_cp);
+
++ hci_dev_lock(hdev);
++
+ /* Make sure connection still exists */
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
+- if (!conn || conn->state != BT_CONNECTED)
++ if (!conn || conn->state != BT_CONNECTED) {
++ hci_dev_unlock(hdev);
+ return MGMT_STATUS_NOT_CONNECTED;
++ }
+
+- cmd->user_data = conn;
++ cmd->user_data = hci_conn_get(conn);
+ hci_cp.handle = cpu_to_le16(conn->handle);
+ hci_cp.which = 0x01; /* Piconet clock */
+
++ hci_dev_unlock(hdev);
++
+ return hci_read_clock_sync(hdev, &hci_cp);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From adae0aa5c922460f7546f40a5cc8275adbc15ca0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 12:15:18 +0800
+Subject: Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 2bf282f8f715f5d05d6f4c49ffb3bd241c5e667e ]
+
+MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter
+update changes an existing LE central connection. The queued work currently
+stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later
+LOAD_CONN_PARAM request can clear disabled parameters and free that entry
+before hci_cmd_sync_work() runs the queued callback.
+
+Do not keep the borrowed hci_conn_params pointer in queued work. Queue the
+hci_conn instead and hold a reference until the queued callback completes.
+When the work runs, revalidate that the connection is still present, look
+up the current hci_conn_params entry, and cancel the update if userspace
+removed that entry while the work was pending.
+
+Copy the interval values from the current params entry under hdev->lock,
+then drop the lock and keep using hci_le_conn_update_sync() to issue the
+update.
+
+Validation reproduced this kernel report:
+BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth]
+Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377
+Workqueue: hci0 hci_cmd_sync_work [bluetooth]
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x5f0
+ kasan_report+0xe0/0x110
+ conn_update_sync+0x2a/0xf0 [bluetooth]
+ hci_cmd_sync_work+0x187/0x210 [bluetooth]
+ process_one_work+0x4fd/0xbc0
+ worker_thread+0x2d8/0x570
+ kthread+0x1ad/0x1f0
+ ret_from_fork+0x3c9/0x540
+ ret_from_fork_asm+0x1a/0x30
+
+Allocated by task 466:
+ hci_conn_params_add+0xa6/0x240 [bluetooth]
+ load_conn_param+0x4e1/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Freed by task 474:
+ kfree+0x313/0x590
+ hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth]
+ load_conn_param+0x4bf/0x850 [bluetooth]
+ hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
+
+Fixes: 0ece498c27d8c ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection")
+Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 44 +++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index e8544194a52424..f24b7bbfcb5b6f 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7940,14 +7940,36 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
+
+ static int conn_update_sync(struct hci_dev *hdev, void *data)
+ {
+- struct hci_conn_params *params = data;
+- struct hci_conn *conn;
++ struct hci_conn *conn = data;
++ struct hci_conn_params *params;
++ struct hci_conn_params local = {};
+
+- conn = hci_conn_hash_lookup_le(hdev, ¶ms->addr, params->addr_type);
+- if (!conn)
+- return -ECANCELED;
++ hci_dev_lock(hdev);
++
++ if (!hci_conn_valid(hdev, conn) || conn->role != HCI_ROLE_MASTER)
++ goto cancel;
++
++ params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
++ if (!params)
++ goto cancel;
++
++ local.conn_min_interval = params->conn_min_interval;
++ local.conn_max_interval = params->conn_max_interval;
++ local.conn_latency = params->conn_latency;
++ local.supervision_timeout = params->supervision_timeout;
+
+- return hci_le_conn_update_sync(hdev, conn, params);
++ hci_dev_unlock(hdev);
++
++ return hci_le_conn_update_sync(hdev, conn, &local);
++
++cancel:
++ hci_dev_unlock(hdev);
++ return -ECANCELED;
++}
++
++static void conn_update_sync_destroy(struct hci_dev *hdev, void *data, int err)
++{
++ hci_conn_put(data);
+ }
+
+ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+@@ -8057,9 +8079,13 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
+ (conn->le_conn_min_interval != min ||
+ conn->le_conn_max_interval != max ||
+ conn->le_conn_latency != latency ||
+- conn->le_supv_timeout != timeout))
+- hci_cmd_sync_queue(hdev, conn_update_sync,
+- hci_param, NULL);
++ conn->le_supv_timeout != timeout)) {
++ hci_conn_get(conn);
++ if (hci_cmd_sync_queue(hdev, conn_update_sync,
++ conn,
++ conn_update_sync_destroy) < 0)
++ hci_conn_put(conn);
++ }
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 8204c6d5e8ea6fd4220cd4cf1c083f39410b6e1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:47:31 +0500
+Subject: Bluetooth: mgmt: Translate HCI reason in Device Disconnected event
+
+From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+
+[ Upstream commit c1cec2bbbeb5922d42d28c6af1707c4f3f8647e3 ]
+
+MGMT_EV_DEVICE_DISCONNECTED carries a reason field which is defined to
+be one of MGMT_DEV_DISCONN_* (0x00..0x05). hci_disconn_complete_evt()
+converts the HCI error with hci_to_mgmt_reason(), but two other paths
+pass the raw HCI error straight through:
+
+ hci_cs_disconnect() -> cp->reason
+ mgmt_connect_failed() -> status
+
+The latter is reached whenever the adapter is powered off or suspended:
+hci_disconnect_all_sync() aborts every link with
+HCI_ERROR_REMOTE_POWER_OFF, hci_disconnect_sync() deliberately does not
+wait for HCI_EV_DISCONN_COMPLETE for that reason, so that
+hci_abort_conn_sync() finishes the connection off through
+hci_conn_failed() instead.
+
+As a result userspace sees an out of range reason:
+
+ @ MGMT Event: Device Disconnected (0x000c) plen 8
+ BR/EDR Address: 8C:A9:6F:2C:51:46
+ Reason: Reserved (0x15)
+
+ bluetoothd: btd_bearer_disconnected() Unknown disconnection value: 21
+ bluetoothd: device_disconnected() Unknown disconnection value: 21
+
+Export hci_to_mgmt_reason() and use it in both places, so that a power
+off is reported as MGMT_DEV_DISCONN_REMOTE rather than as the raw
+HCI_ERROR_REMOTE_POWER_OFF (0x15).
+
+Fixes: d47da6bd4cfa ("Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED")
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 1 +
+ net/bluetooth/hci_event.c | 18 +-----------------
+ net/bluetooth/mgmt.c | 19 ++++++++++++++++++-
+ 3 files changed, 20 insertions(+), 18 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index aa554c34f9ec35..02ba1cba6b236c 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -2433,6 +2433,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
+ bool persistent);
+ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
+ u8 *name, u8 name_len);
++u8 hci_to_mgmt_reason(u8 err);
+ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 link_type, u8 addr_type, u8 reason,
+ bool mgmt_connected);
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 1cd5f97daafe32..55a2de5c8c8e5a 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2766,7 +2766,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ }
+
+ mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
+- cp->reason, mgmt_conn);
++ hci_to_mgmt_reason(cp->reason), mgmt_conn);
+
+ hci_disconn_cfm(conn, cp->reason);
+
+@@ -3384,22 +3384,6 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
+ hci_dev_unlock(hdev);
+ }
+
+-static u8 hci_to_mgmt_reason(u8 err)
+-{
+- switch (err) {
+- case HCI_ERROR_CONNECTION_TIMEOUT:
+- return MGMT_DEV_DISCONN_TIMEOUT;
+- case HCI_ERROR_REMOTE_USER_TERM:
+- case HCI_ERROR_REMOTE_LOW_RESOURCES:
+- case HCI_ERROR_REMOTE_POWER_OFF:
+- return MGMT_DEV_DISCONN_REMOTE;
+- case HCI_ERROR_LOCAL_HOST_TERM:
+- return MGMT_DEV_DISCONN_LOCAL_HOST;
+- default:
+- return MGMT_DEV_DISCONN_UNKNOWN;
+- }
+-}
+-
+ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
+ struct sk_buff *skb)
+ {
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 9604c3025f7b7c..c18eea5eb78104 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9911,6 +9911,22 @@ bool mgmt_powering_down(struct hci_dev *hdev)
+ return false;
+ }
+
++u8 hci_to_mgmt_reason(u8 err)
++{
++ switch (err) {
++ case HCI_ERROR_CONNECTION_TIMEOUT:
++ return MGMT_DEV_DISCONN_TIMEOUT;
++ case HCI_ERROR_REMOTE_USER_TERM:
++ case HCI_ERROR_REMOTE_LOW_RESOURCES:
++ case HCI_ERROR_REMOTE_POWER_OFF:
++ return MGMT_DEV_DISCONN_REMOTE;
++ case HCI_ERROR_LOCAL_HOST_TERM:
++ return MGMT_DEV_DISCONN_LOCAL_HOST;
++ default:
++ return MGMT_DEV_DISCONN_UNKNOWN;
++ }
++}
++
+ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 link_type, u8 addr_type, u8 reason,
+ bool mgmt_connected)
+@@ -9972,7 +9988,8 @@ void mgmt_connect_failed(struct hci_dev *hdev, struct hci_conn *conn, u8 status)
+
+ if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
+ mgmt_device_disconnected(hdev, &conn->dst, conn->type,
+- conn->dst_type, status, true);
++ conn->dst_type,
++ hci_to_mgmt_reason(status), true);
+ return;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 0a083f1aebd0038a62c1b81ac5209e6269ffc381 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:10:30 -0700
+Subject: Bluetooth: qca: fix NVM tag length underflow in TLV parser
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
+
+In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is
+"while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed
+int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a
+size_t (12), so "length" is converted to size_t and any firmware-supplied
+"length" < 12 makes the subtraction wrap to a huge value. The loop body
+then reads a 12-byte struct tlv_type_nvm past the end of the short
+vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
+
+Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both
+operands are non-negative, so it no longer underflows and a "length" too
+small for one record correctly skips the loop.
+
+ BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
+ Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
+ Workqueue: hci0 hci_power_on
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
+ qca_uart_setup (drivers/bluetooth/btqca.c:948)
+ qca_setup (drivers/bluetooth/hci_qca.c:2029)
+ hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
+ hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
+ hci_power_on (net/bluetooth/hci_core.c:920)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btqca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
+index dda76365726f0b..fff1dd64383a3d 100644
+--- a/drivers/bluetooth/btqca.c
++++ b/drivers/bluetooth/btqca.c
+@@ -413,7 +413,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
+
+ idx = 0;
+ data = tlv->data;
+- while (idx < length - sizeof(struct tlv_type_nvm)) {
++ while (idx + sizeof(struct tlv_type_nvm) <= length) {
+ tlv_nvm = (struct tlv_type_nvm *)(data + idx);
+
+ tag_id = le16_to_cpu(tlv_nvm->tag_id);
+--
+2.53.0
+
--- /dev/null
+From 6737670f6595c40b67b6122dc8ccfe4076c1c0b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jul 2026 00:37:16 +0800
+Subject: bnxt_en: Handle partially initialized auxiliary devices
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 1cb8553c02e93e5a150cebd42f9ee3db0ece4707 ]
+
+bnxt_aux_devices_init() calls auxiliary_device_init() before all fields
+used by bnxt_aux_dev_release() are initialized. After
+auxiliary_device_init() succeeds, later errors must unwind with
+auxiliary_device_uninit(), which invokes the release callback.
+
+The release callback assumes that aux_priv->id, aux_priv->edev,
+edev->net and edev->ulp_tbl are all populated. If allocation fails
+after auxiliary_device_init(), the release path can otherwise dereference
+or clear partially initialized state.
+
+Allocate and attach the bnxt_en_dev and ULP table before calling
+auxiliary_device_init(), so the release callback only sees a fully
+initialized auxiliary private object. If auxiliary_device_init() itself
+fails, free those allocations directly because device_initialize() has not
+run and the release callback will not be invoked.
+
+This issue was found by a static analysis checker and confirmed by manual
+source review.
+
+Fixes: 194fad5b2781 ("bnxt_en: Refactor bnxt_rdma_aux_device_init/uninit functions")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Link: https://patch.msgid.link/20260711163716.3996929-1-ruoyuw560@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 39 ++++++++++---------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
+index 5c751933da6a9d..a515c368bac015 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
+@@ -566,6 +566,18 @@ void bnxt_aux_devices_init(struct bnxt *bp)
+ if (!aux_priv)
+ goto next_auxdev;
+
++ edev = kzalloc_obj(*edev);
++ if (!edev)
++ goto aux_priv_free;
++ aux_priv->edev = edev;
++ bnxt_set_edev_info(edev, bp);
++
++ ulp = kzalloc_obj(*ulp);
++ if (!ulp)
++ goto edev_free;
++ edev->ulp_tbl = ulp;
++ aux_priv->id = idx;
++
+ aux_dev = &aux_priv->aux_dev;
+ aux_dev->id = bp->auxdev_id;
+ aux_dev->name = bnxt_aux_devices[idx].name;
+@@ -573,37 +585,26 @@ void bnxt_aux_devices_init(struct bnxt *bp)
+ aux_dev->dev.release = bnxt_aux_dev_release;
+
+ rc = auxiliary_device_init(aux_dev);
+- if (rc) {
+- kfree(aux_priv);
+- goto next_auxdev;
+- }
++ if (rc)
++ goto ulp_free;
+ bp->aux_priv[idx] = aux_priv;
+
+ /* From this point, all cleanup will happen via the .release
+ * callback & any error unwinding will need to include a call
+ * to auxiliary_device_uninit.
+ */
+- edev = kzalloc_obj(*edev);
+- if (!edev)
+- goto aux_dev_uninit;
+-
+- aux_priv->edev = edev;
+- bnxt_set_edev_info(edev, bp);
+-
+- ulp = kzalloc_obj(*ulp);
+- if (!ulp)
+- goto aux_dev_uninit;
+-
+- edev->ulp_tbl = ulp;
+ bp->edev[idx] = edev;
+ if (idx == BNXT_AUXDEV_RDMA)
+ bp->ulp_num_msix_want = bnxt_set_dflt_ulp_msix(bp);
+- aux_priv->id = idx;
+ bnxt_auxdev_set_state(bp, idx, BNXT_ADEV_STATE_INIT);
+
+ continue;
+-aux_dev_uninit:
+- auxiliary_device_uninit(aux_dev);
++ulp_free:
++ kfree(ulp);
++edev_free:
++ kfree(edev);
++aux_priv_free:
++ kfree(aux_priv);
+ next_auxdev:
+ if (idx == BNXT_AUXDEV_RDMA)
+ bp->flags &= ~BNXT_FLAG_ROCE_CAP;
+--
+2.53.0
+
--- /dev/null
+From 5b06edca601daed6f9ff96f64beb6903f36a5488 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 02:53:16 +0000
+Subject: bpf: Fix UAF in sock clone early bailouts
+
+From: Matt Bobrowski <mattbobrowski@google.com>
+
+[ Upstream commit 7cbd0c4cebe4c9f678d15e6b9ba975e1155a107f ]
+
+Similar to recent commit 9b51a6155d14 ("bpf,fork: wipe ->bpf_storage
+before bailouts that access it"), sk_clone() performs an initial
+shallow copy of the socket field ->sk_bpf_storage via sock_copy()
+for the cloned socket newsk.
+
+If sk_clone() bails out early (e.g. if sk_filter_charge() fails) prior
+to calling bpf_sk_storage_clone(), newsk->sk_bpf_storage still points
+to the parent socket's BPF local storage. When newsk is subsequently
+freed via sk_free(), the deallocation path (__sk_destruct() ->
+bpf_sk_storage_free()) destroys the parent socket's BPF local storage,
+leading to a use-after-free (UAF) on the parent socket.
+
+Fix this by resetting newsk->sk_bpf_storage to NULL immediately after
+sock_copy() in sk_clone(), and remove the now redundant initialization
+from bpf_sk_storage_clone().
+
+Fixes: 6ac99e8f23d4 ("bpf: Introduce bpf sk local storage")
+Fixes: f12dd75959b0 ("bpf: net: Set sk_bpf_storage back to NULL for cloned sk")
+Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20260709025316.999913-1-mattbobrowski@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/bpf_sk_storage.c | 2 --
+ net/core/sock.c | 3 +++
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
+index ecd659f79fd4a0..1d295a8769fad5 100644
+--- a/net/core/bpf_sk_storage.c
++++ b/net/core/bpf_sk_storage.c
+@@ -158,8 +158,6 @@ int bpf_sk_storage_clone(const struct sock *sk, struct sock *newsk)
+ struct bpf_local_storage_elem *selem;
+ int ret = 0;
+
+- RCU_INIT_POINTER(newsk->sk_bpf_storage, NULL);
+-
+ rcu_read_lock_dont_migrate();
+ sk_storage = rcu_dereference(sk->sk_bpf_storage);
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index cab041b57d2865..1c73b6841d0ae9 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2492,6 +2492,9 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority,
+ sock_copy(newsk, sk);
+
+ newsk->sk_prot_creator = prot;
++#ifdef CONFIG_BPF_SYSCALL
++ RCU_INIT_POINTER(newsk->sk_bpf_storage, NULL);
++#endif
+
+ /* SANITY */
+ if (likely(newsk->sk_net_refcnt)) {
+--
+2.53.0
+
--- /dev/null
+From 07f1ac46874e0aea6b608029e041ab8614950da5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 06:23:57 +0200
+Subject: bpf, sockmap: Reject unhashed UDP sockets on sockmap update
+
+From: Michal Luczaj <mhal@rbox.co>
+
+[ Upstream commit 66efd3368ae10d05e08fbe6425b50fdec7186ac7 ]
+
+UDP sockets get SOCK_RCU_FREE set when (auto-)bound. This means
+sk_is_refcounted(unbound) = true, while sk_is_refcounted(bound) = false.
+
+Because sockmap accepts unbound UDP sockets, a BPF program can increment a
+socket's refcount via lookup. If the socket is subsequently bound, the
+transition from unbound to bound causes bpf_sk_release() to skip the
+decrement of the refcount, causing a memory leak.
+
+unreferenced object 0xffff88810bc2eb40 (size 1984):
+ comm "test_progs", pid 2451, jiffies 4295320596
+ hex dump (first 32 bytes):
+ 7f 00 00 01 7f 00 00 01 d2 04 1b b7 04 d2 00 00 ................
+ 02 00 01 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace (crc bdee079d):
+ kmem_cache_alloc_noprof+0x557/0x660
+ sk_prot_alloc+0x69/0x240
+ sk_alloc+0x30/0x460
+ inet_create+0x2ce/0xf80
+ __sock_create+0x25b/0x5c0
+ __sys_socket+0x119/0x1d0
+ __x64_sys_socket+0x72/0xd0
+ do_syscall_64+0xa1/0x5f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Instead of special-casing for refcounted sockets, reject unhashed UDP
+sockets during sockmap updates, as there is no benefit to supporting those.
+This effectively reverts the commit under Fixes, with two exceptions:
+
+1. sock_map_sk_state_allowed() maintains a fall-through `return true`.
+2. In the spirit of commit b8b8315e39ff ("bpf, sockmap: Remove unhash
+ handler for BPF sockmap usage"), the proto::unhash BPF handler is not
+ reintroduced.
+
+Historical note: this issue is related to commit 67312adc96b5 ("bpf: reject
+unhashed sockets in bpf_sk_assign").
+
+Fixes: 0c48eefae712 ("sock_map: Lift socket state restriction for datagram sockets")
+Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Michal Luczaj <mhal@rbox.co>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20260707-sockmap-lookup-udp-leak-v4-2-f878346f27ab@rbox.co
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 99e3789492a09e..9ece7bafe27c91 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -542,6 +542,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk)
+ {
+ if (sk_is_tcp(sk))
+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN);
++ if (sk_is_udp(sk))
++ return sk_hashed(sk);
+ if (sk_is_stream_unix(sk))
+ return (1 << READ_ONCE(sk->sk_state)) & TCPF_ESTABLISHED;
+ if (sk_is_vsock(sk) &&
+--
+2.53.0
+
--- /dev/null
+From 10a4a4142c15f34a374f6659397c27a7da0eba45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 14:40:17 -0700
+Subject: btrfs: fallback to transaction csum tree on a commit root csum miss
+
+From: Boris Burkov <boris@bur.io>
+
+[ Upstream commit 3dcd50730814e5220072d2b26d0587af6bfb6dbe ]
+
+We have been running with commit root csums enabled for some time and
+have noticed a slight uptick in zero csum errors. Investigating those
+revealed that they were same transaction reads of extents that were just
+relocated, but the extent map generation was long ago.
+
+It turns out that relocation intentionally does not update the extent
+generation (replace_file_extents()), but must write a new csum since the
+data has moved, so we must account for this with commit root csum reading.
+
+Luckily this is a short lived condition: after the relocation transaction
+the commit root will once again have the csum. So we can add a generic
+fallback to the lookup to try again with the transaction csum root.
+
+Fixes: f07b855c56b1 ("btrfs: try to search for data csums in commit root")
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Boris Burkov <boris@bur.io>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/file-item.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
+index d72249390030f4..e50b10b30c717b 100644
+--- a/fs/btrfs/file-item.c
++++ b/fs/btrfs/file-item.c
+@@ -356,6 +356,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;
+ int ret = 0;
+ u32 bio_offset = 0;
++ bool using_commit_root = false;
+
+ if ((inode->flags & BTRFS_INODE_NODATASUM) ||
+ test_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state))
+@@ -429,6 +430,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * from across transactions.
+ */
+ if (bbio->csum_search_commit_root) {
++ using_commit_root = true;
+ path->search_commit_root = true;
+ path->skip_locking = true;
+ down_read(&fs_info->commit_root_sem);
+@@ -461,6 +463,28 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ * assume this is the case.
+ */
+ if (count == 0) {
++ /*
++ * If an extent is relocated in the current transaction
++ * then relocation writes a new csum without updating
++ * the extent map generation. Until the next commit, we
++ * will see a hole in that case, so we need to fallback
++ * to searching the transaction csum root.
++ *
++ * Note that a commit root lookup of a referenced extent can
++ * only miss, not return a stale csum. A freed extent's csum
++ * is deleted in the same transaction and its bytenr is not
++ * reusable until that transaction has committed and the
++ * extent is unpinned.
++ */
++ if (using_commit_root) {
++ up_read(&fs_info->commit_root_sem);
++ using_commit_root = false;
++ path->search_commit_root = false;
++ path->skip_locking = false;
++ btrfs_release_path(path);
++ continue;
++ }
++
+ memset(csum_dst, 0, csum_size);
+ count = 1;
+
+@@ -479,7 +503,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
+ bio_offset += count * sectorsize;
+ }
+
+- if (bbio->csum_search_commit_root)
++ if (using_commit_root)
+ up_read(&fs_info->commit_root_sem);
+ return ret;
+ }
+--
+2.53.0
+
--- /dev/null
+From 83e3ad031342a5352c01d5f61f397dc8a05d7339 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:16:21 +0100
+Subject: btrfs: fix root leak if its reloc root is unexpected in
+ merge_reloc_roots()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
+
+If we have an unexpected reloc_root for our root, we jump to the out label
+but never drop the reference we obtained for root, resulting in a leak.
+Add a missing btrfs_put_root() call.
+
+Fixes: 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 3ebaf5880125fa..6c826be4174934 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1850,6 +1850,7 @@ void merge_reloc_roots(struct reloc_control *rc)
+ * corruption, e.g. bad reloc tree key offset.
+ */
+ ret = -EINVAL;
++ btrfs_put_root(root);
+ goto out;
+ }
+ ret = merge_reloc_root(rc, root);
+--
+2.53.0
+
--- /dev/null
+From 221b95fcedd21f939091b9b1d6f5ba0697af46eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 10:29:26 -0700
+Subject: btrfs: reject free space cache with more entries than pages
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
+
+When loading a v1 free space cache, __load_free_space_cache() takes
+num_entries and num_bitmaps straight from the on-disk
+btrfs_free_space_header. That header is stored in the tree_root under a key
+with type 0, which the tree-checker has no case for, so neither count is
+validated before the load trusts it.
+
+The load loops num_entries times and maps the next page whenever the current
+one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
+does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
+io_ctl_init() from the cache inode's i_size, not from num_entries:
+
+ num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
+ io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
+
+So if num_entries claims more records than the pages can hold, io_ctl->index
+runs off the end of pages[]. The write side never hits this because
+io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
+io_ctl->index >= io_ctl->num_pages; the read side just never had the same
+check.
+
+To trigger it, take a clean cache (num_entries = <N> here), set num_entries
+in the header to 0x10000, and fix up the leaf checksum so it still passes
+the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
+pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
+65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
+array:
+
+ BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
+ io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
+ __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
+ load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
+ caching_thread (fs/btrfs/block-group.c:880)
+ btrfs_work_helper (fs/btrfs/async-thread.c:312)
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
+at line 565, which is why that is the frame KASAN names. The out-of-bounds
+slot is then treated as a struct page and handed to crc32c(), so the bad
+read turns into a GP fault.
+
+Add the missing check to io_ctl_check_crc(), which is where both the entry
+loop and the bitmap loop end up. When num_entries is too large the load now
+fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
+the free space from the extent tree, so a valid cache is never rejected.
+
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Fixes: 5b0e95bf607d ("Btrfs: inline checksums into the disk free space cache")
+Link: https://lore.kernel.org/linux-btrfs/CAPpSM+RMPByMCKXvM5QFKToxsyNccfuFLWMdD0mfd0wh2Ja62w@mail.gmail.com/
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/free-space-cache.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index ab22e4f9ffdde0..bbc4db7fe74bbd 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -555,6 +555,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
+ u32 crc = ~(u32)0;
+ unsigned offset = 0;
+
++ if (index >= io_ctl->num_pages)
++ return -EIO;
++
+ if (index == 0)
+ offset = sizeof(u32) * io_ctl->num_pages;
+
+--
+2.53.0
+
--- /dev/null
+From f3ff92f092cdf9b7237226e29f773b1582aec8db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:26 +0200
+Subject: can: j1939: fix lockless local-destination check
+
+From: Shuhao Fu <sfual@cse.ust.hk>
+
+[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
+
+j1939_priv.ents[].nusers is documented as protected by priv->lock, and
+its updates already happen under that lock. j1939_can_recv() also reads
+it under read_lock_bh(). However, j1939_session_skb_queue() and
+j1939_tp_send() still read priv->ents[da].nusers without taking the
+lock.
+
+Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so
+they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while
+userspace is binding or releasing sockets concurrently with TP traffic.
+This can misclassify TP/ETP sessions as local or remote and take the wrong
+transport path.
+
+Fix both transport paths by routing the destination-locality check through
+a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20260419140614.GA4041240@chcpu16
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index df93d57907da7e..8a31cb23bc76d0 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -351,6 +351,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ }
+ }
+
++static bool j1939_address_is_local(struct j1939_priv *priv, u8 addr)
++{
++ bool local = false;
++
++ read_lock_bh(&priv->lock);
++ if (j1939_address_is_unicast(addr) && priv->ents[addr].nusers)
++ local = true;
++ read_unlock_bh(&priv->lock);
++
++ return local;
++}
++
+ void j1939_session_skb_queue(struct j1939_session *session,
+ struct sk_buff *skb)
+ {
+@@ -359,8 +371,7 @@ void j1939_session_skb_queue(struct j1939_session *session,
+
+ j1939_ac_fixup(priv, skb);
+
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ skcb->flags |= J1939_ECU_LOCAL_SRC;
+@@ -2038,8 +2049,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+ return ERR_PTR(ret);
+
+ /* fix DST flags, it may be used there soon */
+- if (j1939_address_is_unicast(skcb->addr.da) &&
+- priv->ents[skcb->addr.da].nusers)
++ if (j1939_address_is_local(priv, skcb->addr.da))
+ skcb->flags |= J1939_ECU_LOCAL_DST;
+
+ /* src is always local, I'm sending ... */
+--
+2.53.0
+
--- /dev/null
+From a19b39cf85ee94560a0eb3c2d049dd3d6301c131 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:22:23 +0200
+Subject: can: raw: add locking for raw flags bitfield
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 1e5185c090589f4146d728ab36417d8a5419f127 ]
+
+With commit 890e5198a6e5 ("can: raw: use bitfields to store flags in
+struct raw_sock") the formerly separate integer values have been integrated
+into a single bitfield. This led to a read-modify-write operation when
+changing a flag in raw_setsockopt() which now needs a locking to prevent
+concurrent access.
+
+Instead of adding a lock/unlock hell in each of the flag manipulations this
+patch introduces a wrapper for a new raw_setsockopt_locked() function
+analogue to the isotp_setsockopt[_locked]() approach in net/can/isotp.c
+
+Fixes: 890e5198a6e5 ("can: raw: use bitfields to store flags in struct raw_sock")
+Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
+Closes: https://lore.kernel.org/linux-can/20260503112200.22727-1-eulgyukim@snu.ac.kr/
+Tested-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
+Tested-by: Vincent Mailhol <mailhol@kernel.org>
+Link: https://patch.msgid.link/20260504111928.41856-1-socketcan@hartkopp.net
+[mkl: use Closes tag instead of Link]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 66 +++++++++++++++++++++++----------------------------
+ 1 file changed, 30 insertions(+), 36 deletions(-)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index a26942e78e6887..82d9c0499c95fa 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -562,8 +562,8 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
+ return RAW_MIN_NAMELEN;
+ }
+
+-static int raw_setsockopt(struct socket *sock, int level, int optname,
+- sockptr_t optval, unsigned int optlen)
++static int raw_setsockopt_locked(struct socket *sock, int optname,
++ sockptr_t optval, unsigned int optlen)
+ {
+ struct sock *sk = sock->sk;
+ struct raw_sock *ro = raw_sk(sk);
+@@ -575,9 +575,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ int flag;
+ int err = 0;
+
+- if (level != SOL_CAN_RAW)
+- return -EINVAL;
+-
+ switch (optname) {
+ case CAN_RAW_FILTER:
+ if (optlen % sizeof(struct can_filter) != 0)
+@@ -598,17 +595,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ return -EFAULT;
+ }
+
+- rtnl_lock();
+- lock_sock(sk);
+-
+ dev = ro->dev;
+- if (ro->bound && dev) {
+- if (dev->reg_state != NETREG_REGISTERED) {
+- if (count > 1)
+- kfree(filter);
+- err = -ENODEV;
+- goto out_fil;
+- }
++ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED) {
++ if (count > 1)
++ kfree(filter);
++ return -ENODEV;
+ }
+
+ if (ro->bound) {
+@@ -622,7 +613,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ if (err) {
+ if (count > 1)
+ kfree(filter);
+- goto out_fil;
++ return err;
+ }
+
+ /* remove old filter registrations */
+@@ -642,11 +633,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ }
+ ro->filter = filter;
+ ro->count = count;
+-
+- out_fil:
+- release_sock(sk);
+- rtnl_unlock();
+-
+ break;
+
+ case CAN_RAW_ERR_FILTER:
+@@ -658,16 +644,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+
+ err_mask &= CAN_ERR_MASK;
+
+- rtnl_lock();
+- lock_sock(sk);
+-
+ dev = ro->dev;
+- if (ro->bound && dev) {
+- if (dev->reg_state != NETREG_REGISTERED) {
+- err = -ENODEV;
+- goto out_err;
+- }
+- }
++ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED)
++ return -ENODEV;
+
+ /* remove current error mask */
+ if (ro->bound) {
+@@ -676,7 +655,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ err_mask);
+
+ if (err)
+- goto out_err;
++ return err;
+
+ /* remove old err_mask registration */
+ raw_disable_errfilter(sock_net(sk), dev, sk,
+@@ -685,11 +664,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+
+ /* link new err_mask to the socket */
+ ro->err_mask = err_mask;
+-
+- out_err:
+- release_sock(sk);
+- rtnl_unlock();
+-
+ break;
+
+ case CAN_RAW_LOOPBACK:
+@@ -769,6 +743,26 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ return err;
+ }
+
++static int raw_setsockopt(struct socket *sock, int level, int optname,
++ sockptr_t optval, unsigned int optlen)
++{
++ struct sock *sk = sock->sk;
++ int err;
++
++ if (level != SOL_CAN_RAW)
++ return -EINVAL;
++
++ rtnl_lock();
++ lock_sock(sk);
++
++ err = raw_setsockopt_locked(sock, optname, optval, optlen);
++
++ release_sock(sk);
++ rtnl_unlock();
++
++ return err;
++}
++
+ static int raw_getsockopt(struct socket *sock, int level, int optname,
+ sockopt_t *opt)
+ {
+--
+2.53.0
+
--- /dev/null
+From b7fdce13dcc180f4eccbe55f009025b3d8bdd50d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 19:25:39 +0200
+Subject: cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit d2d5c129d07ea8eb91cd8a8633b5774116c4d171 ]
+
+If arch_scale_freq_ref() is not defined for a given arch (like x86, for
+example), cpufreq_update_pressure() will always set cpufreq_pressure to
+zero for all CPUs in the system, which is generally problematic on
+systems with asymmetric capacity [1].
+
+However, in the absence of arch_scale_freq_ref(), it is reasonable
+to assume that cpuinfo.max_freq is the maximum sustainable frequency
+for the given cpufreq policy. Moreover, there are cases in which
+arch_scale_freq_ref() would need to be defined to return essentially
+the cpuinfo.max_freq value anyway (for example, intel_pstate on
+hybrid platforms).
+
+For the above reasons, update cpufreq_update_pressure() to fall back to
+using cpuinfo.max_freq as the reference frequency if zero is returned by
+arch_scale_freq_ref().
+
+Fixes: 75d659317bb1 ("cpufreq: Add a cpufreq pressure feedback for the scheduler")
+Link: https://lore.kernel.org/lkml/CAKfTPtBuRLfYNnR4w--cFZYZy-R8gaPEgVwCcaMmbCcJ2H-muQ@mail.gmail.com/ [1]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
+Tested-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> # cluster scheduling
+Acked-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://patch.msgid.link/5086499.GXAFRqVoOG@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index d41067cd1f1b25..2debe39fc477be 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -2583,6 +2583,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
+
+ cpu = cpumask_first(policy->related_cpus);
+ max_freq = arch_scale_freq_ref(cpu);
++ if (!max_freq)
++ max_freq = policy->cpuinfo.max_freq;
++
+ capped_freq = policy->max;
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 9f60f93aba6b635d57ef1b3a87f2ca42922bcb06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:27:51 +0000
+Subject: Docs/admin-guide/cgroup-v2: fix memory.stat doc details
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Doehyun Baek <doehyunbaek@gmail.com>
+
+[ Upstream commit 46d65096ce8d278abf4528e254878c14ddd0b459 ]
+
+Fix minor cgroup v2 memory.stat documentation issues. Correct the
+vmalloc per-node marker now that vmalloc uses the native NR_VMALLOC node
+stat, and document zswap_incomp as a byte-valued memory amount instead
+of as a page counter.
+
+Fixes: c466412c73c3 ("mm: memcontrol: switch to native NR_VMALLOC vmstat counter")
+Fixes: 5ad41a38c364 ("mm: zswap: add per-memcg stat for incompressible pages")
+Signed-off-by: Doehyun Baek <doehyunbaek@gmail.com>
+Reviewed-by: Nhat Pham <nphamcs@gmail.com>
+Acked-by: Michal Koutný <mkoutny@suse.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/cgroup-v2.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
+index 6efd0095ed995b..5cc33d87c3dffe 100644
+--- a/Documentation/admin-guide/cgroup-v2.rst
++++ b/Documentation/admin-guide/cgroup-v2.rst
+@@ -1570,7 +1570,7 @@ The following nested keys are defined.
+ sock (npn)
+ Amount of memory used in network transmission buffers
+
+- vmalloc (npn)
++ vmalloc
+ Amount of memory used for vmap backed memory.
+
+ shmem
+@@ -1735,7 +1735,7 @@ The following nested keys are defined.
+ Number of pages written from zswap to swap.
+
+ zswap_incomp
+- Number of incompressible pages currently stored in zswap
++ Amount of memory used by incompressible pages currently stored in zswap
+ without compression. These pages could not be compressed to
+ a size smaller than PAGE_SIZE, so they are stored as-is.
+
+--
+2.53.0
+
--- /dev/null
+From 165fcdd2305162a2176e29984c9c75e0dc6ce452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 21:36:25 +0200
+Subject: dpll: fix NULL pointer dereference in dpll_msg_add_pin_ref_sync()
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit d2e914a4a0d0f753dbae830264850d044026167c ]
+
+When a dpll_pin is shared across multiple dpll_device instances and
+those devices are being unregistered (e.g. during driver module removal),
+a NULL pointer dereference can occur in dpll_msg_add_pin_ref_sync().
+
+This happens under the following conditions:
+ - A pin is registered with two or more dpll devices (dpll_A, dpll_B)
+ - The pin has ref_sync pairs with other pins
+ - During unregistration of dpll_A's pins, a ref_sync partner pin is
+ unregistered first, removing it from dpll_A->pin_refs
+ - But since the partner pin is still registered with dpll_B, its
+ dpll_refs is not empty, so dpll_pin_ref_sync_pair_del() does NOT
+ run and the partner stays in the pin's ref_sync_pins xarray
+ - When the pin itself is then unregistered from dpll_A, the delete
+ notification calls dpll_msg_add_pin_ref_sync() which finds the
+ partner in ref_sync_pins, passes dpll_pin_available() (partner is
+ still registered with dpll_B), but dpll_pin_on_dpll_priv(dpll_A,
+ partner) returns NULL because partner was already removed from
+ dpll_A->pin_refs
+ - The NULL priv pointer is passed to the driver's ref_sync_get
+ callback, which dereferences it
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000034
+ Oops: Oops: 0000 [#1] SMP NOPTI
+ RIP: 0010:zl3073x_dpll_input_pin_ref_sync_get+0x73/0x80 [zl3073x]
+ Call Trace:
+ dpll_msg_add_pin_ref_sync+0xb8/0x200
+ dpll_cmd_pin_get_one+0x3b6/0x4b0
+ dpll_pin_event_send+0x72/0x140
+ __dpll_pin_unregister+0x5a/0x2b0
+ dpll_pin_unregister+0x49/0x70
+
+Fix this by skipping ref_sync pins whose priv pointer cannot be resolved
+for the current dpll device.
+
+Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20260710193625.1378822-1-ivecera@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/dpll_netlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
+index 75e3ae0c16d077..8163521188c06c 100644
+--- a/drivers/dpll/dpll_netlink.c
++++ b/drivers/dpll/dpll_netlink.c
+@@ -557,6 +557,9 @@ dpll_msg_add_pin_ref_sync(struct sk_buff *msg, struct dpll_pin *pin,
+ if (!dpll_pin_available(ref_sync_pin))
+ continue;
+ ref_sync_pin_priv = dpll_pin_on_dpll_priv(dpll, ref_sync_pin);
++ /* Pin may have been unregistered from this dpll already */
++ if (!ref_sync_pin_priv)
++ continue;
+ if (WARN_ON(!ops->ref_sync_get))
+ return -EOPNOTSUPP;
+ ret = ops->ref_sync_get(pin, pin_priv, ref_sync_pin,
+--
+2.53.0
+
--- /dev/null
+From 6cc50909b76c522a0ede033d895ce4c788c2dbd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 16:02:25 +0800
+Subject: drm/i915/gt: use correct selftest config symbol
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
+
+intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running
+the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST,
+without the trailing "S", and the rest of i915 uses
+CONFIG_DRM_I915_SELFTEST.
+
+Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol,
+the IS_ENABLED() test is always false. Use the existing selftest symbol
+so the debug/selftest guarded path can be reached when selftests are
+enabled.
+
+This is a source-level fix. It does not claim dynamic hardware
+reproduction; the evidence is the Kconfig definition and the inconsistent
+guard in intel_engine_user.c.
+
+Fixes: 750e76b4f9f6 ("drm/i915/gt: Move the [class][inst] lookup for engines onto the GT")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260705080225.436-1-pengpeng@iscas.ac.cn
+(cherry picked from commit 14a2012a490258f3f93857bc4f1b203405964be7)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+index be4bbff1a57c9c..d5190e11b27062 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
+@@ -259,7 +259,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
+ p = &prev->rb_right;
+ }
+
+- if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
++ if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) &&
+ IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+ struct intel_engine_cs *engine;
+ unsigned int isolation;
+--
+2.53.0
+
--- /dev/null
+From cb351d8683f64bf468f32873cf8235c4ec0901af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jul 2026 01:04:30 +0300
+Subject: drm/i915/selftests: Fix GT PM sort comparators
+
+From: Emre Cecanpunar <emreleno@gmail.com>
+
+[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
+
+Compare the sampled clock values instead of their addresses. Comparing
+addresses leaves the samples unsorted, preventing the code from discarding
+the minimum and maximum samples.
+
+Fixes: 1a5392479207 ("drm/i915/selftests: Measure CS_TIMESTAMP")
+Signed-off-by: Emre Cecanpunar <emreleno@gmail.com>
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Link: https://lore.kernel.org/r/20260714220430.238433-1-emreleno@gmail.com
+(cherry picked from commit 682ea2d28d18bb06f9fc663cb5ab7e80dc0e606a)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+index 33351deeea4f0b..07eaf71955c447 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
++++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+@@ -16,9 +16,9 @@ static int cmp_u64(const void *A, const void *B)
+ {
+ const u64 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+@@ -28,9 +28,9 @@ static int cmp_u32(const void *A, const void *B)
+ {
+ const u32 *a = A, *b = B;
+
+- if (a < b)
++ if (*a < *b)
+ return -1;
+- else if (a > b)
++ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From a091269771446f65f39d81b31a2d7e4bf4cc01b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 23:33:49 +0300
+Subject: drm/i915/wm: clear the plane ddb_y entries on plane disable
+
+From: Vinod Govindapillai <vinod.govindapillai@intel.com>
+
+[ Upstream commit e89978c1cff54e265345c66e1177d19ea5a8bc00 ]
+
+The UV/Y plane DDB entriess are never cleared on
+sk_wm_plane_disable_noatomic() and can leave stale DDB state
+for NV12 planes on pre-Gen11 devices
+
+Fixes: d34b59d5ba41 ("drm/i915: Add skl_wm_plane_disable_noatomic()")
+Assisted-by: Copilot:claude-sonnet-4.6
+Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
+Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
+Link: https://patch.msgid.link/20260615203355.218578-2-vinod.govindapillai@intel.com
+(cherry picked from commit 60f68a6ba298fd1e971a2d91576304bee89a16fc)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/skl_watermark.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
+index e0ac4e2ce4dcb6..29b7661f88141d 100644
+--- a/drivers/gpu/drm/i915/display/skl_watermark.c
++++ b/drivers/gpu/drm/i915/display/skl_watermark.c
+@@ -3908,7 +3908,7 @@ void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc,
+ return;
+
+ skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
+- skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0);
++ skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb_y[plane->id], 0, 0);
+
+ crtc_state->wm.skl.plane_min_ddb[plane->id] = 0;
+ crtc_state->wm.skl.plane_interim_ddb[plane->id] = 0;
+--
+2.53.0
+
--- /dev/null
+From ce3228a495604907c03b59645390ff52b2cefb98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 16:29:12 +0800
+Subject: drm/panthor: Check debugfs GEM lock initialization
+
+From: Linmao Li <lilinmao@kylinos.cn>
+
+[ Upstream commit 022e901333c3054656a640794e842bab7af5a75c ]
+
+drmm_mutex_init() can fail while registering the managed cleanup action.
+When that happens, drmm_add_action_or_reset() destroys the mutex before
+returning the error. Continuing initialization would therefore leave the
+debugfs GEM object list with an unusable lock.
+
+Propagate the error as is already done for the other managed mutexes in
+panthor_device_init().
+
+Fixes: a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS")
+Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://patch.msgid.link/20260713082912.321021-1-lilinmao@kylinos.cn
+Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_device.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
+index 4f522a912d8968..48bb33bac36631 100644
+--- a/drivers/gpu/drm/panthor/panthor_device.c
++++ b/drivers/gpu/drm/panthor/panthor_device.c
+@@ -207,7 +207,10 @@ int panthor_device_init(struct panthor_device *ptdev)
+ return ret;
+
+ #ifdef CONFIG_DEBUG_FS
+- drmm_mutex_init(&ptdev->base, &ptdev->gems.lock);
++ ret = drmm_mutex_init(&ptdev->base, &ptdev->gems.lock);
++ if (ret)
++ return ret;
++
+ INIT_LIST_HEAD(&ptdev->gems.node);
+ #endif
+
+--
+2.53.0
+
--- /dev/null
+From e8c09786377951b5fb7d430544dc18dd793b2665 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 11:34:18 +0100
+Subject: drm/xe: Assign queue name in time for drm_sched_init
+
+From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+
+[ Upstream commit 24f60b8e9f44b10614b43dbc4ba4b029f8ede3b6 ]
+
+Currently the queue name is only assigned after the drm scheduler instance
+has been created. This loses information with all logging or debug
+workqueue facilities so lets re-order things a bit so the name gets
+assigned in time.
+
+To be able to assign a GuC ID early we split the allocation into
+reservation and publish phases.
+
+First, with the submission state lock held, we reserve the ID in the GuC
+ID manager, which serves as an authoritative source of truth. Then we can
+drop the lock and reserve entries in the exec queue lookup XArray. This
+can be lockless since the NULL entries are invisible both to the kernel
+and userspace. Only after the queue has been fully created we replace the
+reserved entries with the queue pointer, which can be done locklessly for
+single width queues.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://patch.msgid.link/20260523103418.61832-1-tvrtko.ursulin@igalia.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Stable-dep-of: 299bc6d50b1b ("drm/xe/guc: Keep scheduler timeline name alive")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_submit.c | 72 +++++++++++++++++-------------
+ 1 file changed, 40 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
+index 42110e01b7d096..1752039d333f39 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -397,46 +397,43 @@ void xe_guc_submit_disable(struct xe_guc *guc)
+ guc->submission_state.enabled = false;
+ }
+
+-static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa_count)
++static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q,
++ int count)
+ {
+ int i;
+
+- lockdep_assert_held(&guc->submission_state.lock);
++ mutex_lock(&guc->submission_state.lock);
+
+- for (i = 0; i < xa_count; ++i)
+- xa_erase(&guc->submission_state.exec_queue_lookup, q->guc->id + i);
++ for (i = 0; i < count; ++i)
++ xa_erase(&guc->submission_state.exec_queue_lookup,
++ q->guc->id + i);
+
+ xe_guc_id_mgr_release_locked(&guc->submission_state.idm,
+ q->guc->id, q->width);
+
+ if (xa_empty(&guc->submission_state.exec_queue_lookup))
+ wake_up(&guc->submission_state.fini_wq);
++
++ mutex_unlock(&guc->submission_state.lock);
+ }
+
+ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
+ {
+- int ret;
+- int i;
+-
+- /*
+- * Must use GFP_NOWAIT as this lock is in the dma fence signalling path,
+- * worse case user gets -ENOMEM on engine create and has to try again.
+- *
+- * FIXME: Have caller pre-alloc or post-alloc /w GFP_KERNEL to prevent
+- * failure.
+- */
+- lockdep_assert_held(&guc->submission_state.lock);
++ int ret, i;
+
++ mutex_lock(&guc->submission_state.lock);
+ ret = xe_guc_id_mgr_reserve_locked(&guc->submission_state.idm,
+ q->width);
++ mutex_unlock(&guc->submission_state.lock);
+ if (ret < 0)
+ return ret;
+
+ q->guc->id = ret;
+
++ /* Reserve empty slots. */
+ for (i = 0; i < q->width; ++i) {
+- ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup,
+- q->guc->id + i, q, GFP_NOWAIT));
++ ret = xa_insert(&guc->submission_state.exec_queue_lookup,
++ q->guc->id + i, NULL, GFP_KERNEL);
+ if (ret)
+ goto err_release;
+ }
+@@ -449,11 +446,24 @@ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
+ return ret;
+ }
+
++static void publish_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
++{
++ int i;
++
++ lockdep_assert_held(&guc->submission_state.lock);
++
++ for (i = 0; i < q->width; ++i) {
++ void *old;
++
++ old = xa_store(&guc->submission_state.exec_queue_lookup,
++ q->guc->id + i, q, GFP_NOWAIT);
++ XE_WARN_ON(old || xa_is_err(old));
++ }
++}
++
+ static void release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
+ {
+- mutex_lock(&guc->submission_state.lock);
+ __release_guc_id(guc, q, q->width);
+- mutex_unlock(&guc->submission_state.lock);
+ }
+
+ struct exec_queue_policy {
+@@ -1957,6 +1967,12 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT :
+ msecs_to_jiffies(q->sched_props.job_timeout_ms);
+
++ err = alloc_guc_id(guc, q);
++ if (err)
++ goto err_free;
++
++ xe_exec_queue_assign_name(q, q->guc->id);
++
+ /*
+ * Use primary queue's submit_wq for all secondary queues of a
+ * multi queue group. This serialization avoids any locking around
+@@ -1973,28 +1989,21 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ timeout, guc_to_gt(guc)->ordered_wq, NULL,
+ q->name, gt_to_xe(q->gt)->drm.dev);
+ if (err)
+- goto err_free;
++ goto err_release_id;
+
+ sched = &ge->sched;
+ err = xe_sched_entity_init(&ge->entity, sched);
+ if (err)
+ goto err_sched;
+
+- mutex_lock(&guc->submission_state.lock);
+-
+- err = alloc_guc_id(guc, q);
+- if (err)
+- goto err_entity;
+-
+ q->entity = &ge->entity;
+
++ mutex_lock(&guc->submission_state.lock);
+ if (xe_guc_read_stopped(guc) || vf_recovery(guc))
+ xe_sched_stop(sched);
+-
++ publish_guc_id(guc, q);
+ mutex_unlock(&guc->submission_state.lock);
+
+- xe_exec_queue_assign_name(q, q->guc->id);
+-
+ /*
+ * Maintain secondary queues of the multi queue group in a list
+ * for handling dependencies across the queues in the group.
+@@ -2017,11 +2026,10 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+
+ return 0;
+
+-err_entity:
+- mutex_unlock(&guc->submission_state.lock);
+- xe_sched_entity_fini(&ge->entity);
+ err_sched:
+ xe_sched_fini(&ge->sched);
++err_release_id:
++ release_guc_id(guc, q);
+ err_free:
+ kfree(ge);
+
+--
+2.53.0
+
--- /dev/null
+From 1b9160852d1ed247c508f5fae306c72c1d249b85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jul 2026 11:56:24 +0530
+Subject: drm/xe/guc: Hold device ref until queue teardown completes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arvind Yadav <arvind.yadav@intel.com>
+
+[ Upstream commit 9b7e60184f4b22e893d4ae95234d5f26261a430c ]
+
+GuC exec queue destruction can run asynchronously. If the final device
+put happens from a destroy worker, drmm cleanup can end up draining
+the same workqueue and deadlock.
+
+Hold a drm_device reference for the queue lifetime and drop it after
+queue teardown completes. This keeps drmm cleanup from running while
+async destroy work is still pending.
+
+Move GuC destroy work to a module-lifetime Xe workqueue and flush it
+on PCI remove so hot-unbind/rebind still waits for pending destroy work.
+
+With queue-held device refs, guc_submit_sw_fini() cannot run with live
+GuC IDs. Replace the fini wait with an assertion and remove the unused
+fini_wq.
+
+v2:
+ - Rebase
+
+v3:
+ - Switch to queue-lifetime drm_dev_get()/drm_dev_put() model. (Matt)
+ - Queue async teardown on system_dfl_wq instead of xe->destroy_wq. (Matt)
+ - Drop separate deferred drm_dev_put worker.
+ - Remove stale drain_workqueue(xe->destroy_wq) from guc_submit_sw_fini().
+
+v4:
+ - Replace the guc_submit_sw_fini() wait with an assertion and remove
+ the now-unused fini_wq. (sashiko)
+
+v5:
+ - Move destroy work to a module-lifetime Xe workqueue instead of
+ system_dfl_wq. (Matt)
+ - Flush the module-lifetime destroy workqueue during PCI remove to
+ preserve the old device-remove wait semantics.
+
+v6:
+ - Keep SVM pagemap destroy work on the per-device destroy_wq to avoid
+ letting it outlive the xe_device/drm_device. (Sashiko)
+ - Use WQ_MEM_RECLAIM for xe->destroy_wq because SVM pagemap destroy work
+ can be queued from the reclaim path.
+
+v7:
+ - Drop the per-device xe->destroy_wq and use the module-level destroy WQ
+ for SVM pagemap destroy as well. (Matt)
+ - Rename xe_exec_queue_destroy_wq_*() helpers to xe_destroy_wq_*()
+ helpers because the WQ is no longer exec-queue specific. (Matt)
+
+v8:
+ - Rebase.
+
+v9:
+ - Keep SVM pagemap destroy work on the per-device WQ_MEM_RECLAIM
+ destroy_wq because it can be queued from reclaim and embeds
+ the dev_pagemap used by devres teardown. (Sashiko)
+ - Keep the module-level destroy WQ GuC-only and drop WQ_MEM_RECLAIM
+ from it.
+ - Update the module-WQ kdoc to document the GuC/SVM split.
+
+v10:
+ - Keep xe->destroy_wq per-cpu while adding WQ_MEM_RECLAIM to fix the
+ workqueue allocation warning.
+
+v11:
+ - Drop the SVM pagemap destroy comment as it was revision-specific.
+ (Thomas)
+
+v12:
+ - Rebase.
+
+Fixes: 2d2be279f1ca ("drm/xe: fix UAF around queue destruction")
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Cc: Tejas Upadhyay <tejas.upadhyay@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
+Link: https://patch.msgid.link/20260716062624.211396-1-arvind.yadav@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit da1124abac689cc2b1d8995e5f0a816f8a122edb)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device.c | 2 +-
+ drivers/gpu/drm/xe/xe_device_types.h | 2 +-
+ drivers/gpu/drm/xe/xe_guc_submit.c | 66 ++++++++++++++++------------
+ drivers/gpu/drm/xe/xe_guc_types.h | 2 -
+ drivers/gpu/drm/xe/xe_module.c | 49 +++++++++++++++++++++
+ drivers/gpu/drm/xe/xe_module.h | 5 +++
+ drivers/gpu/drm/xe/xe_pci.c | 6 +++
+ 7 files changed, 100 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
+index ffea4a453c01ca..991b0ea9218bb2 100644
+--- a/drivers/gpu/drm/xe/xe_device.c
++++ b/drivers/gpu/drm/xe/xe_device.c
+@@ -509,7 +509,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
+ WQ_MEM_RECLAIM);
+ xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
+ xe->unordered_wq = alloc_workqueue("xe-unordered-wq", WQ_PERCPU, 0);
+- xe->destroy_wq = alloc_workqueue("xe-destroy-wq", WQ_PERCPU, 0);
++ xe->destroy_wq = alloc_workqueue("xe-destroy-wq", WQ_PERCPU | WQ_MEM_RECLAIM, 0);
+ if (!xe->ordered_wq || !xe->unordered_wq ||
+ !xe->preempt_fence_wq || !xe->destroy_wq) {
+ /*
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index 615218d775b14e..7e0901ac95c91d 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -351,7 +351,7 @@ struct xe_device {
+ /** @unordered_wq: used to serialize unordered work */
+ struct workqueue_struct *unordered_wq;
+
+- /** @destroy_wq: used to serialize user destroy work, like queue */
++ /** @destroy_wq: used to serialize SVM pagemap destroy work */
+ struct workqueue_struct *destroy_wq;
+
+ /** @tiles: device tiles */
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
+index 54606367eea3b3..b8465553aed2dc 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -10,6 +10,7 @@
+ #include <linux/circ_buf.h>
+ #include <linux/dma-fence-array.h>
+
++#include <drm/drm_drv.h>
+ #include <drm/drm_managed.h>
+
+ #include "abi/guc_actions_abi.h"
+@@ -37,6 +38,7 @@
+ #include "xe_macros.h"
+ #include "xe_map.h"
+ #include "xe_mocs.h"
++#include "xe_module.h"
+ #include "xe_pm.h"
+ #include "xe_ring_ops_types.h"
+ #include "xe_sched_job.h"
+@@ -232,17 +234,9 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
+ static void guc_submit_sw_fini(struct drm_device *drm, void *arg)
+ {
+ struct xe_guc *guc = arg;
+- struct xe_device *xe = guc_to_xe(guc);
+ struct xe_gt *gt = guc_to_gt(guc);
+- int ret;
+-
+- ret = wait_event_timeout(guc->submission_state.fini_wq,
+- xa_empty(&guc->submission_state.exec_queue_lookup),
+- HZ * 5);
+
+- drain_workqueue(xe->destroy_wq);
+-
+- xe_gt_assert(gt, ret);
++ xe_gt_assert(gt, xa_empty(&guc->submission_state.exec_queue_lookup));
+
+ xa_destroy(&guc->submission_state.exec_queue_lookup);
+ }
+@@ -319,8 +313,6 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids)
+
+ xa_init(&guc->submission_state.exec_queue_lookup);
+
+- init_waitqueue_head(&guc->submission_state.fini_wq);
+-
+ primelockdep(guc);
+
+ guc->submission_state.initialized = true;
+@@ -411,9 +403,6 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q,
+ xe_guc_id_mgr_release_locked(&guc->submission_state.idm,
+ q->guc->id, q->width);
+
+- if (xa_empty(&guc->submission_state.exec_queue_lookup))
+- wake_up(&guc->submission_state.fini_wq);
+-
+ mutex_unlock(&guc->submission_state.lock);
+ }
+
+@@ -1690,6 +1679,7 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
+ {
+ struct xe_guc_exec_queue *ge = q->guc;
+ struct xe_guc *guc = exec_queue_to_guc(q);
++ struct drm_device *drm = &guc_to_xe(guc)->drm;
+
+ if (xe_exec_queue_is_multi_queue_secondary(q)) {
+ struct xe_exec_queue_group *group = q->multi_queue.group;
+@@ -1708,36 +1698,52 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
+ * (timeline name).
+ */
+ kfree_rcu(ge, rcu);
++
++ drm_dev_put(drm);
+ }
+
+-static void __guc_exec_queue_destroy_async(struct work_struct *w)
++static void guc_exec_queue_do_destroy(struct xe_exec_queue *q)
+ {
+- struct xe_guc_exec_queue *ge =
+- container_of(w, struct xe_guc_exec_queue, destroy_async);
+- struct xe_exec_queue *q = ge->q;
++ struct xe_guc_exec_queue *ge = q->guc;
+ struct xe_guc *guc = exec_queue_to_guc(q);
++ struct xe_device *xe = guc_to_xe(guc);
++ struct drm_device *drm = &xe->drm;
+
+- guard(xe_pm_runtime)(guc_to_xe(guc));
+- trace_xe_exec_queue_destroy(q);
++ /*
++ * guc_exec_queue_fini() drops the queue's drm_device ref.
++ * Keep the device alive until the PM-runtime guard unwinds.
++ */
++ drm_dev_get(drm);
+
+- /* Confirm no work left behind accessing device structures */
+- cancel_delayed_work_sync(&ge->sched.base.work_tdr);
++ scoped_guard(xe_pm_runtime, xe) {
++ trace_xe_exec_queue_destroy(q);
+
+- xe_exec_queue_fini(q);
++ /* Confirm no work left behind accessing device structures */
++ cancel_delayed_work_sync(&ge->sched.base.work_tdr);
++
++ xe_exec_queue_fini(q);
++ }
++
++ drm_dev_put(drm);
+ }
+
+-static void guc_exec_queue_destroy_async(struct xe_exec_queue *q)
++static void __guc_exec_queue_destroy_async(struct work_struct *w)
+ {
+- struct xe_guc *guc = exec_queue_to_guc(q);
+- struct xe_device *xe = guc_to_xe(guc);
++ struct xe_guc_exec_queue *ge =
++ container_of(w, struct xe_guc_exec_queue, destroy_async);
++
++ guc_exec_queue_do_destroy(ge->q);
++}
+
++static void guc_exec_queue_destroy_async(struct xe_exec_queue *q)
++{
+ INIT_WORK(&q->guc->destroy_async, __guc_exec_queue_destroy_async);
+
+ /* We must block on kernel engines so slabs are empty on driver unload */
+ if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q))
+- __guc_exec_queue_destroy_async(&q->guc->destroy_async);
++ guc_exec_queue_do_destroy(q);
+ else
+- queue_work(xe->destroy_wq, &q->guc->destroy_async);
++ xe_destroy_wq_queue(&q->guc->destroy_async);
+ }
+
+ static void __guc_exec_queue_destroy(struct xe_guc *guc, struct xe_exec_queue *q)
+@@ -1945,6 +1951,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ {
+ struct xe_gpu_scheduler *sched;
+ struct xe_guc *guc = exec_queue_to_guc(q);
++ struct drm_device *drm = &guc_to_xe(guc)->drm;
+ struct workqueue_struct *submit_wq = NULL;
+ struct xe_guc_exec_queue *ge;
+ long timeout;
+@@ -1956,6 +1963,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ if (!ge)
+ return -ENOMEM;
+
++ drm_dev_get(drm);
++
+ q->guc = ge;
+ ge->q = q;
+ init_rcu_head(&ge->rcu);
+@@ -2034,6 +2043,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ release_guc_id(guc, q);
+ err_free:
+ kfree(ge);
++ drm_dev_put(drm);
+
+ return err;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_guc_types.h b/drivers/gpu/drm/xe/xe_guc_types.h
+index c7b9642b41ba74..31a2acb63ac34d 100644
+--- a/drivers/gpu/drm/xe/xe_guc_types.h
++++ b/drivers/gpu/drm/xe/xe_guc_types.h
+@@ -100,8 +100,6 @@ struct xe_guc {
+ * even initialized - before that not even the lock is valid
+ */
+ bool initialized;
+- /** @submission_state.fini_wq: submit fini wait queue */
+- wait_queue_head_t fini_wq;
+ } submission_state;
+
+ /** @hwconfig: Hardware config state */
+diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
+index 4cb57818291229..99347f216ec893 100644
+--- a/drivers/gpu/drm/xe/xe_module.c
++++ b/drivers/gpu/drm/xe/xe_module.c
+@@ -7,6 +7,7 @@
+
+ #include <linux/init.h>
+ #include <linux/module.h>
++#include <linux/workqueue.h>
+
+ #include <drm/drm_module.h>
+
+@@ -91,6 +92,50 @@ static int xe_check_nomodeset(void)
+ return 0;
+ }
+
++static struct workqueue_struct *xe_destroy_wq;
++
++static int __init xe_destroy_wq_module_init(void)
++{
++ xe_destroy_wq = alloc_workqueue("xe-guc-destroy-wq", WQ_UNBOUND, 0);
++ if (!xe_destroy_wq)
++ return -ENOMEM;
++ return 0;
++}
++
++static void xe_destroy_wq_module_exit(void)
++{
++ if (xe_destroy_wq)
++ destroy_workqueue(xe_destroy_wq);
++ xe_destroy_wq = NULL;
++}
++
++/**
++ * xe_destroy_wq_queue() - Queue work on the destroy workqueue
++ * @work: work item to queue
++ *
++ * The destroy workqueue has module lifetime and is used for GuC exec queue
++ * teardown that can outlive a single xe_device. SVM pagemap destroy uses the
++ * per-device xe->destroy_wq instead.
++ *
++ * Return: %true if @work was queued, %false if it was already pending.
++ */
++bool xe_destroy_wq_queue(struct work_struct *work)
++{
++ return queue_work(xe_destroy_wq, work);
++}
++
++/**
++ * xe_destroy_wq_flush() - Flush the destroy workqueue
++ *
++ * Drains all pending destroy work. Called from PCI remove to ensure
++ * teardown ordering before the device is destroyed.
++ */
++void xe_destroy_wq_flush(void)
++{
++ if (xe_destroy_wq)
++ flush_workqueue(xe_destroy_wq);
++}
++
+ struct init_funcs {
+ int (*init)(void);
+ void (*exit)(void);
+@@ -112,6 +157,10 @@ static const struct init_funcs init_funcs[] = {
+ .init = xe_sched_job_module_init,
+ .exit = xe_sched_job_module_exit,
+ },
++ {
++ .init = xe_destroy_wq_module_init,
++ .exit = xe_destroy_wq_module_exit,
++ },
+ {
+ .init = xe_register_pci_driver,
+ .exit = xe_unregister_pci_driver,
+diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
+index 79cb9639c0f3df..e8e54f701cf3ee 100644
+--- a/drivers/gpu/drm/xe/xe_module.h
++++ b/drivers/gpu/drm/xe/xe_module.h
+@@ -8,6 +8,8 @@
+
+ #include <linux/types.h>
+
++struct work_struct;
++
+ /* Module modprobe variables */
+ struct xe_modparam {
+ bool force_execlist;
+@@ -27,5 +29,8 @@ struct xe_modparam {
+
+ extern struct xe_modparam xe_modparam;
+
++bool xe_destroy_wq_queue(struct work_struct *work);
++void xe_destroy_wq_flush(void);
++
+ #endif
+
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index c2ecd27ec770a2..ad4955fe5ade7e 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -1029,6 +1029,12 @@ static void xe_pci_remove(struct pci_dev *pdev)
+ return;
+
+ xe_device_remove(xe);
++
++ /*
++ * Preserve remove-time flush after moving destroy work to module
++ * lifetime.
++ */
++ xe_destroy_wq_flush();
+ xe_pm_fini(xe);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 887a612e8395e2eaf20faf3e67bfa22152967843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jul 2026 12:14:02 +0530
+Subject: drm/xe/guc: Keep scheduler timeline name alive
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arvind Yadav <arvind.yadav@intel.com>
+
+[ Upstream commit 299bc6d50b1bed7d1f408391736712f01a0855e2 ]
+
+The scheduler keeps a pointer to the timeline name, but q->name
+is freed with the exec queue while scheduler fences can still
+reference it.
+
+Store the name in struct xe_guc_exec_queue so it shares
+the scheduler's RCU-deferred lifetime.
+
+Fixes: 6bd90e700b42 ("drm/xe: Make dma-fences compliant with the safe access rules")
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Acked-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20260714064402.2457257-1-arvind.yadav@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit 41075f0eb5dcbd3b065d15f15ef7bbe9315188e8)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_exec_queue_types.h | 5 +++++
+ drivers/gpu/drm/xe/xe_guc_submit.c | 4 +++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
+index e5e53b421f29fb..cda14d954e572f 100644
+--- a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
++++ b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
+@@ -10,6 +10,7 @@
+ #include <linux/workqueue.h>
+
+ #include "xe_gpu_scheduler_types.h"
++#include "xe_hw_fence_types.h"
+
+ struct dma_fence;
+ struct xe_exec_queue;
+@@ -24,6 +25,10 @@ struct xe_guc_exec_queue {
+ struct rcu_head rcu;
+ /** @sched: GPU scheduler for this xe_exec_queue */
+ struct xe_gpu_scheduler sched;
++ /**
++ * @name: Scheduler timeline name, kept with @sched until RCU free.
++ */
++ char name[MAX_FENCE_NAME_LEN];
+ /** @entity: Scheduler entity for this xe_exec_queue */
+ struct xe_sched_entity entity;
+ /**
+diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
+index 1752039d333f39..54606367eea3b3 100644
+--- a/drivers/gpu/drm/xe/xe_guc_submit.c
++++ b/drivers/gpu/drm/xe/xe_guc_submit.c
+@@ -1973,6 +1973,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+
+ xe_exec_queue_assign_name(q, q->guc->id);
+
++ strscpy(ge->name, q->name, sizeof(ge->name));
++
+ /*
+ * Use primary queue's submit_wq for all secondary queues of a
+ * multi queue group. This serialization avoids any locking around
+@@ -1987,7 +1989,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
+ err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops,
+ submit_wq, xe_lrc_ring_size() / MAX_JOB_SIZE_BYTES, 64,
+ timeout, guc_to_gt(guc)->ordered_wq, NULL,
+- q->name, gt_to_xe(q->gt)->drm.dev);
++ ge->name, gt_to_xe(q->gt)->drm.dev);
+ if (err)
+ goto err_release_id;
+
+--
+2.53.0
+
--- /dev/null
+From 9cd76176faeb20c7478933f90e38ebd5492b48f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 23:24:40 -0700
+Subject: drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 56441f9e08ad68697295b8835266d2bc48ab59b5 ]
+
+xe_bo_move() attaches VF CCS read/write batch buffers (BBs) to a BO
+after it transitions NULL/SYSTEM -> TT, and detaches them after it
+transitions TT -> SYSTEM. Both operations were done synchronously on
+the CPU immediately after building the move's copy/clear fence,
+without waiting for that fence to signal. This creates two races with
+VF migration:
+
+- Attach happens too late relative to the copy job it is meant to
+ protect. If the copy job is submitted before the CCS BBs are
+ attached, a VF migration event that pauses execution mid-copy can
+ observe partially copied CCS metadata without the attach state
+ needed to correctly save/restore it.
+
+- Detach happens too early relative to the copy job that moves data
+ out of TT. The CCS BBs are torn down right after the copy fence is
+ obtained, while the actual blit may still be in flight. A VF
+ migration event that pauses execution mid-copy can then race the
+ save/restore path against the still-running blit, and the CCS BBs
+ it would need to make sense of the paused state have already been
+ removed.
+
+Fix both races:
+
+- Move the attach call to before the copy/clear job is submitted, so
+ the CCS BBs are already registered by the time the copy runs. On
+ attach failure, unwind and bail out of the move. xe_migrate_ccs_rw_copy()
+ now takes the destination resource explicitly, since bo->ttm.resource
+ is not updated to the new resource until after the move commits.
+
+- Detach only after explicitly waiting for the copy fence to signal,
+ instead of tearing down the CCS BBs immediately after obtaining it.
+
+While here, also fix xe_sriov_vf_ccs_attach_bo() to properly unwind and
+propagate errors: the per-context loop previously never broke out on
+error, silently discarding earlier failures. Unwind by clearing each
+attached context directly via xe_migrate_ccs_rw_copy_clear() instead of
+reusing xe_sriov_vf_ccs_detach_bo(), which requires both contexts to be
+attached before it will clean up either one.
+
+Fixes: 864690cf4dd6 ("drm/xe/vf: Attach and detach CCS copy commands with BO")
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Cc: Michał Winiarski <michal.winiarski@intel.com>
+Cc: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Assisted-by: GitHub_Copilot:claude-sonnet-5
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Acked-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
+Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+Link: https://patch.msgid.link/20260714062440.3421225-1-matthew.brost@intel.com
+(cherry picked from commit d45ad0aa7a1eb5d7288b5ed948b05695611dc39e)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 34 +++++++++++++++++++---------
+ drivers/gpu/drm/xe/xe_migrate.c | 5 +++-
+ drivers/gpu/drm/xe/xe_migrate.h | 1 +
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 20 ++++++++++++++--
+ drivers/gpu/drm/xe/xe_sriov_vf_ccs.h | 3 ++-
+ 5 files changed, 48 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 6b518858538f57..261c38c9fa985a 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -1109,6 +1109,21 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ xe_pm_runtime_get_noresume(xe);
+ }
+
++ /*
++ * Attach CCS BBs before submitting the copy job below so a VF
++ * migration racing the copy sees valid, up to date attach state.
++ */
++ if (IS_VF_CCS_READY(xe) &&
++ ((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
++ (old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
++ handle_system_ccs) {
++ ret = xe_sriov_vf_ccs_attach_bo(bo, new_mem);
++ if (ret) {
++ xe_pm_runtime_put(xe);
++ goto out;
++ }
++ }
++
+ if (move_lacks_source) {
+ u32 flags = 0;
+
+@@ -1146,22 +1161,19 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ ttm_bo_move_null(ttm_bo, new_mem);
+ }
+
+- dma_fence_put(fence);
+- xe_pm_runtime_put(xe);
+-
+ /*
+- * CCS meta data is migrated from TT -> SMEM. So, let us detach the
+- * BBs from BO as it is no longer needed.
++ * Detach must wait for the copy above to complete: a VF migration
++ * racing an in-flight copy must still see valid CCS BBs, so don't
++ * tear them down until the copy fence has signaled.
+ */
+ if (IS_VF_CCS_READY(xe) && old_mem_type == XE_PL_TT &&
+- new_mem->mem_type == XE_PL_SYSTEM)
++ new_mem->mem_type == XE_PL_SYSTEM) {
++ dma_fence_wait(fence, false);
+ xe_sriov_vf_ccs_detach_bo(bo);
++ }
+
+- if (IS_VF_CCS_READY(xe) &&
+- ((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
+- (old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
+- handle_system_ccs)
+- ret = xe_sriov_vf_ccs_attach_bo(bo);
++ dma_fence_put(fence);
++ xe_pm_runtime_put(xe);
+
+ out:
+ if ((!ttm_bo->resource || ttm_bo->resource->mem_type == XE_PL_SYSTEM) &&
+diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
+index a22413f892a096..f4160e844b4c33 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.c
++++ b/drivers/gpu/drm/xe/xe_migrate.c
+@@ -1145,6 +1145,8 @@ static int emit_flush_invalidate(u32 *dw, int i, u32 flags)
+ * @tile: Tile whose migration context to be used.
+ * @q : Execution to be used along with migration context.
+ * @src_bo: The buffer object @src is currently bound to.
++ * @new_mem: The (not yet committed) destination resource @src_bo is being
++ * moved into; src_bo->ttm.resource is still the old resource.
+ * @read_write : Creates BB commands for CCS read/write.
+ *
+ * Creates batch buffer instructions to copy CCS metadata from CCS pool to
+@@ -1156,12 +1158,13 @@ static int emit_flush_invalidate(u32 *dw, int i, u32 flags)
+ */
+ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ struct xe_bo *src_bo,
++ struct ttm_resource *new_mem,
+ enum xe_sriov_vf_ccs_rw_ctxs read_write)
+
+ {
+ bool src_is_pltt = read_write == XE_SRIOV_VF_CCS_READ_CTX;
+ bool dst_is_pltt = read_write == XE_SRIOV_VF_CCS_WRITE_CTX;
+- struct ttm_resource *src = src_bo->ttm.resource;
++ struct ttm_resource *src = new_mem;
+ struct xe_migrate *m = tile->migrate;
+ struct xe_gt *gt = tile->primary_gt;
+ u32 batch_size, batch_size_allocated;
+diff --git a/drivers/gpu/drm/xe/xe_migrate.h b/drivers/gpu/drm/xe/xe_migrate.h
+index 169279d9d8c247..7761c02b4d86d6 100644
+--- a/drivers/gpu/drm/xe/xe_migrate.h
++++ b/drivers/gpu/drm/xe/xe_migrate.h
+@@ -138,6 +138,7 @@ struct dma_fence *xe_migrate_resolve(struct xe_migrate *m,
+
+ int xe_migrate_ccs_rw_copy(struct xe_tile *tile, struct xe_exec_queue *q,
+ struct xe_bo *src_bo,
++ struct ttm_resource *new_mem,
+ enum xe_sriov_vf_ccs_rw_ctxs read_write);
+
+ void xe_migrate_ccs_rw_copy_clear(struct xe_bo *src_bo,
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+index 09b99fb2608bce..6787564629c65f 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
+@@ -404,6 +404,8 @@ void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx)
+ /**
+ * xe_sriov_vf_ccs_attach_bo - Insert CCS read write commands in the BO.
+ * @bo: the &buffer object to which batch buffer commands will be added.
++ * @new_mem: the (not yet committed) destination resource @bo is being moved
++ * into; bo->ttm.resource is still the old resource at this point.
+ *
+ * This function shall be called only by VF. It inserts the PTEs and copy
+ * command instructions in the BO by calling xe_migrate_ccs_rw_copy()
+@@ -411,7 +413,7 @@ void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx)
+ *
+ * Returns: 0 if successful, negative error code on failure.
+ */
+-int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo)
++int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo, struct ttm_resource *new_mem)
+ {
+ struct xe_device *xe = xe_bo_device(bo);
+ enum xe_sriov_vf_ccs_rw_ctxs ctx_id;
+@@ -430,7 +432,21 @@ int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo)
+ xe_assert(xe, !bb);
+
+ ctx = &xe->sriov.vf.ccs.contexts[ctx_id];
+- err = xe_migrate_ccs_rw_copy(tile, ctx->mig_q, bo, ctx_id);
++ err = xe_migrate_ccs_rw_copy(tile, ctx->mig_q, bo, new_mem, ctx_id);
++ if (err)
++ goto err_unwind;
++ }
++ return 0;
++
++err_unwind:
++ /*
++ * Clean up any contexts already attached. Can't reuse
++ * xe_sriov_vf_ccs_detach_bo() here as it requires both contexts
++ * attached before cleaning up either one.
++ */
++ for_each_ccs_rw_ctx(ctx_id) {
++ if (bo->bb_ccs[ctx_id])
++ xe_migrate_ccs_rw_copy_clear(bo, ctx_id);
+ }
+ return err;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+index 00e58b36c510ac..e1034d85210406 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
++++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.h
+@@ -11,11 +11,12 @@
+ #include "xe_sriov_vf_ccs_types.h"
+
+ struct drm_printer;
++struct ttm_resource;
+ struct xe_device;
+ struct xe_bo;
+
+ int xe_sriov_vf_ccs_init(struct xe_device *xe);
+-int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo);
++int xe_sriov_vf_ccs_attach_bo(struct xe_bo *bo, struct ttm_resource *new_mem);
+ int xe_sriov_vf_ccs_detach_bo(struct xe_bo *bo);
+ int xe_sriov_vf_ccs_register_context(struct xe_device *xe);
+ void xe_sriov_vf_ccs_rebase(struct xe_device *xe);
+--
+2.53.0
+
--- /dev/null
+From 108e5ed9c2fccd519c31f2631750ccc33e155a74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 15:17:59 -0700
+Subject: drm/xe/wopcm: fix WOPCM size for LNL+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit ad87e2476b3b246580f407afc8ffa91d621bc849 ]
+
+Starting on LNL the WOPCM size is 8MB instead of 4, so we need to avoid
+using the [0, 8MB) range of the GGTT as that can be unaccessible from
+the microcontrollers.
+
+Note that the proper long-term fix here is to read the WOPCM size from
+the HW, but that is a more serious rework that would be difficult to
+backport, so we can do that as a follow-up.
+
+Fixes: 9c57bc08652a ("drm/xe/lnl: Drop force_probe requirement")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Shuicheng Lin <shuicheng.lin@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260713221758.3285744-2-daniele.ceraolospurio@intel.com
+(cherry picked from commit 3033b0b24ed0e2f5e56bdd4d9c183417c365a45b)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wopcm.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c
+index 900daf1d1b1bb5..fe65ed246775d9 100644
+--- a/drivers/gpu/drm/xe/xe_wopcm.c
++++ b/drivers/gpu/drm/xe/xe_wopcm.c
+@@ -49,9 +49,9 @@
+ */
+
+ /* Default WOPCM size is 2MB from Gen11, 1MB on previous platforms */
+-/* FIXME: Larger size require for 2 tile PVC, do a proper probe sooner or later */
++/* FIXME: Larger size require for some platforms, do a proper probe sooner or later */
+ #define DGFX_WOPCM_SIZE SZ_4M
+-/* FIXME: Larger size require for MTL, do a proper probe sooner or later */
++#define LNL_WOPCM_SIZE SZ_8M
+ #define MTL_WOPCM_SIZE SZ_4M
+ #define WOPCM_SIZE SZ_2M
+
+@@ -179,9 +179,14 @@ static int __wopcm_init_regs(struct xe_device *xe, struct xe_gt *gt,
+
+ u32 xe_wopcm_size(struct xe_device *xe)
+ {
+- return IS_DGFX(xe) ? DGFX_WOPCM_SIZE :
+- xe->info.platform == XE_METEORLAKE ? MTL_WOPCM_SIZE :
+- WOPCM_SIZE;
++ if (xe->info.platform >= XE_LUNARLAKE)
++ return LNL_WOPCM_SIZE;
++ else if (IS_DGFX(xe))
++ return DGFX_WOPCM_SIZE;
++ else if (xe->info.platform == XE_METEORLAKE)
++ return MTL_WOPCM_SIZE;
++ else
++ return WOPCM_SIZE;
+ }
+
+ static u32 max_wopcm_size(struct xe_device *xe)
+--
+2.53.0
+
--- /dev/null
+From cf2f0c2e3957fc9f3f7d749475f1700e601a57f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 11:18:45 +0800
+Subject: erofs: relax sanity check for tail pclusters due to ztailpacking
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit d3386e17393bec1341cfeedb9d08d6846ccd6fb2 ]
+
+If the tail data can be inlined into the inode meta block, it should
+be converted into a regular tail pcluster.
+
+In principle, it should be converted into an uncompressed pcluster if
+there is not enough gain to use compression (map->m_llen < map->m_plen);
+but since there are various shipped images, relax the condition for
+ztailpacking tail pcluster fallback instead of reporting corruption
+incorrectly.
+
+Reported-and-tested-by: Yifan Zhao <zhaoyifan28@huawei.com>
+Reported-by: Alberto Salvia Novella <es20490446e@gmail.com>
+Closes: https://github.com/erofs/erofs-utils/issues/51
+Fixes: a5242d37c83a ("erofs: error out obviously illegal extents in advance")
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/zmap.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index e1a02a2c8406bf..53e8a9f2fb9109 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -721,7 +721,8 @@ static int z_erofs_map_sanity_check(struct inode *inode,
+ map->m_algorithmformat, EROFS_I(inode)->nid);
+ return -EFSCORRUPTED;
+ }
+- if (EROFS_MAP_FULL(map->m_flags) && map->m_llen < map->m_plen) {
++ if (EROFS_MAP_FULL(map->m_flags) && map->m_llen < map->m_plen &&
++ map->m_la + map->m_llen < inode->i_size) {
+ erofs_err(inode->i_sb, "too much compressed data @ la %llu of nid %llu",
+ map->m_la, EROFS_I(inode)->nid);
+ return -EFSCORRUPTED;
+--
+2.53.0
+
--- /dev/null
+From 42880e05ffd19ac3e703d7e495ddd2583190956f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 10:38:39 +0000
+Subject: firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset
+ calculation
+
+From: Sebastian Ene <sebastianene@google.com>
+
+[ Upstream commit b4d961351aa84fdf0148783fb1f3a1391b8a0adb ]
+
+Use the descriptor's `ep_mem_offset` to calculate the start of the endpoint
+memory access array and to comply with the FF-A spec instead of defaulting
+to `sizeof(struct ffa_mem_region)`.
+This requires moving `ffa_mem_region_additional_setup()` earlier in the setup
+flow.
+Also, add sanity checks to ensure the calculated descriptor offsets do not
+exceed `max_fragsize`.
+
+Fixes: 113580530ee7 ("firmware: arm_ffa: Update memory descriptor to support v1.1 format")
+Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Sebastian Ene <sebastianene@google.com>
+Link: https://patch.msgid.link/20260702103848.1647249-3-sebastianene@google.com
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 20 +++++++++++++++-----
+ include/linux/arm_ffa.h | 2 +-
+ 2 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index c9e3d0f246913c..4cbf7537e6242d 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -711,19 +711,30 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ struct ffa_composite_mem_region *composite;
+ struct ffa_mem_region_addr_range *constituents;
+ struct ffa_mem_region_attributes *ep_mem_access;
+- u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg);
++ u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg), ep_offset;
++ u32 emad_end, emad_size = ffa_emad_size_get(drv_info->version);
+
+ mem_region->tag = args->tag;
+ mem_region->flags = args->flags;
+ mem_region->sender_id = drv_info->vm_id;
+ mem_region->attributes = ffa_memory_attributes_get(func_id);
++
++ ffa_mem_region_additional_setup(drv_info->version, mem_region);
+ composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
+ drv_info->version);
++ if (composite_offset + sizeof(*composite) > max_fragsize)
++ return -ENXIO;
+
+ for (idx = 0; idx < args->nattrs; idx++) {
+- ep_mem_access = buffer +
+- ffa_mem_desc_offset(buffer, idx, drv_info->version);
+- memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
++ ep_offset = ffa_mem_desc_offset(buffer, idx, drv_info->version);
++ if (check_add_overflow(ep_offset, emad_size, &emad_end))
++ return -ENXIO;
++
++ if (emad_end > max_fragsize)
++ return -ENXIO;
++
++ ep_mem_access = buffer + ep_offset;
++ memset(ep_mem_access, 0, emad_size);
+ ep_mem_access->receiver = args->attrs[idx].receiver;
+ ep_mem_access->attrs = args->attrs[idx].attrs;
+ ep_mem_access->composite_off = composite_offset;
+@@ -733,7 +744,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ }
+ mem_region->handle = 0;
+ mem_region->ep_count = args->nattrs;
+- ffa_mem_region_additional_setup(drv_info->version, mem_region);
+
+ composite = buffer + composite_offset;
+ composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
+diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
+index 81e603839c4a51..62d67dae8b7033 100644
+--- a/include/linux/arm_ffa.h
++++ b/include/linux/arm_ffa.h
+@@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
+ if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
+ offset += offsetof(struct ffa_mem_region, ep_mem_offset);
+ else
+- offset += sizeof(struct ffa_mem_region);
++ offset += buf->ep_mem_offset;
+
+ return offset;
+ }
+--
+2.53.0
+
--- /dev/null
+From 601e3e4c18b72da8525a194463a679c34fce91ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:35:00 -0700
+Subject: firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
+
+From: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+
+[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
+
+ffa_partition_info_get() passes uuid_str directly to uuid_parse()
+without a NULL check. When a caller passes NULL, uuid_parse() ->
+__uuid_parse() -> uuid_is_valid() dereferences the pointer, causing
+a kernel panic:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address
+ | 0000000000000040
+ | pc : uuid_parse+0x40/0xac
+ | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
+
+Add a NULL guard before uuid_parse() so a NULL argument returns
+-ENODEV instead of crashing. Callers are expected to always supply
+a valid partition UUID, so NULL is not a supported input.
+
+Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions")
+Signed-off-by: Unnathi Chalicheemala <unnathi.chalicheemala@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260617-ffa_partition_nullptr_fix-v2-1-bc801b4ce34c@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index e2438ca09da24b..ea0671180a16d9 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1137,7 +1137,7 @@ static int ffa_partition_info_get(const char *uuid_str,
+ uuid_t uuid;
+ struct ffa_partition_info *pbuf;
+
+- if (uuid_parse(uuid_str, &uuid)) {
++ if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
+ pr_err("invalid uuid (%s)\n", uuid_str);
+ return -ENODEV;
+ }
+--
+2.53.0
+
--- /dev/null
+From 48dfc2f64ca877f73a5067e2c72ee4597615c037 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 10:38:38 +0000
+Subject: firmware: arm_ffa: Fix out-of-bound writes in
+ ffa_setup_and_transmit()
+
+From: Mostafa Saleh <smostafa@google.com>
+
+[ Upstream commit 3383ffb7ef937317361713ffcc21921a7848511a ]
+
+Sashiko (locally) reports multiple out-of-bound issues in
+ffa_setup_and_transmit:
+1) Writing ep_mem_access->reserved can write out of bounds for FFA
+ versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case
+ while reserved has an offset of 24.
+ Instead of zeroing fields, memset the struct to zero first based on
+ the FFA version.
+
+2) Make sure there is enough size to write constituents.
+
+While at it, convert the only sizeof() in the driver that uses a
+type instead of variable.
+
+Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
+Fixes: 111a833dc5cb ("firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors")
+Signed-off-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Sebastian Ene <sebastianene@google.com>
+Link: https://patch.msgid.link/20260702103848.1647249-2-sebastianene@google.com
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index ea0671180a16d9..c9e3d0f246913c 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -723,11 +723,10 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ for (idx = 0; idx < args->nattrs; idx++) {
+ ep_mem_access = buffer +
+ ffa_mem_desc_offset(buffer, idx, drv_info->version);
++ memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
+ ep_mem_access->receiver = args->attrs[idx].receiver;
+ ep_mem_access->attrs = args->attrs[idx].attrs;
+ ep_mem_access->composite_off = composite_offset;
+- ep_mem_access->flag = 0;
+- ep_mem_access->reserved = 0;
+ ffa_emad_impdef_value_init(drv_info->version,
+ ep_mem_access->impdef_val,
+ args->attrs[idx].impdef_val);
+@@ -767,7 +766,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ constituents = buffer;
+ }
+
+- if ((void *)constituents - buffer > max_fragsize) {
++ if ((void *)constituents + sizeof(*constituents) - buffer > max_fragsize) {
+ pr_err("Memory Region Fragment > Tx Buffer size\n");
+ return -EFAULT;
+ }
+@@ -776,7 +775,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
+ constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE;
+ constituents->reserved = 0;
+ constituents++;
+- frag_len += sizeof(struct ffa_mem_region_addr_range);
++ frag_len += sizeof(*constituents);
+ } while ((args->sg = sg_next(args->sg)));
+
+ return ffa_transmit_fragment(func_id, addr, buf_sz, frag_len,
+--
+2.53.0
+
--- /dev/null
+From 7a4d9262663a59e4cf9272051d39ce7bee7ffe3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 21:54:06 +0000
+Subject: firmware: arm_ffa: Respect firmware advertised RX/TX buffer size
+ limits
+
+From: Seth Forshee <sforshee@nvidia.com>
+
+[ Upstream commit 53716a4d745f1dac7aff33f3d1494b701eb2f888 ]
+
+FFA_FEATURES reports the minimum size and alignment boundary required
+for RXTX_MAP. In FF-A v1.2 and later it can also report a maximum buffer
+size, with zero meaning that no maximum is enforced.
+
+The driver only used the minimum value and then rounded it up to PAGE_SIZE
+before invoking RXTX_MAP after commit 83210251fd70 ("firmware: arm_ffa:
+Use the correct buffer size during RXTX_MAP"). On systems where PAGE_SIZE
+is larger than the advertised minimum, this can exceed a non-zero maximum
+reported by firmware. Older implementations do not advertise a maximum and
+may also reject the rounded-up size.
+
+Decode the maximum size and clamp the page-aligned minimum to it when it
+is present. If no maximum is advertised and RXTX_MAP rejects the rounded
+size with INVALID_PARAMETERS, retry with the advertised minimum size.
+Record drv_info->rxtx_bufsz only after RXTX_MAP succeeds so it reflects
+the size registered with firmware.
+
+While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
+consistency.
+
+Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
+Suggested-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Seth Forshee <sforshee@nvidia.com>
+Link: https://patch.msgid.link/20260602-b4-ffa-rxtx-map-fixes-v2-1-7cb06508da84@nvidia.com
+(sudeep.holla: Minor rewording subject and commit message)
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index cab32cfdac4236..e2438ca09da24b 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -32,6 +32,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
++#include <linux/minmax.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/mutex.h>
+@@ -55,7 +56,9 @@
+ (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
+
+ #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
+-#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
++#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
++#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
++#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
+
+ #define FFA_MAX_NOTIFICATIONS 64
+
+@@ -2095,7 +2098,7 @@ static int __init ffa_init(void)
+ {
+ int ret;
+ u32 buf_sz;
+- size_t rxtx_bufsz = SZ_4K;
++ size_t rxtx_min_bufsz = SZ_4K, rxtx_max_bufsz = 0, rxtx_bufsz;
+
+ ret = ffa_transport_init(&invoke_ffa_fn);
+ if (ret)
+@@ -2118,15 +2121,18 @@ static int __init ffa_init(void)
+ ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
+ if (!ret) {
+ if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
+- rxtx_bufsz = SZ_64K;
++ rxtx_min_bufsz = SZ_64K;
+ else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
+- rxtx_bufsz = SZ_16K;
++ rxtx_min_bufsz = SZ_16K;
+ else
+- rxtx_bufsz = SZ_4K;
++ rxtx_min_bufsz = SZ_4K;
++
++ rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
++ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
++ rxtx_max_bufsz = rxtx_min_bufsz;
+ }
+
+- rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
+- drv_info->rxtx_bufsz = rxtx_bufsz;
++ rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
+ drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
+ if (!drv_info->rx_buffer) {
+ ret = -ENOMEM;
+@@ -2142,10 +2148,17 @@ static int __init ffa_init(void)
+ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+ virt_to_phys(drv_info->rx_buffer),
+ rxtx_bufsz / FFA_PAGE_SIZE);
++ if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
++ rxtx_bufsz = rxtx_min_bufsz;
++ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
++ virt_to_phys(drv_info->rx_buffer),
++ rxtx_bufsz / FFA_PAGE_SIZE);
++ }
+ if (ret) {
+ pr_err("failed to register FFA RxTx buffers\n");
+ goto free_pages;
+ }
++ drv_info->rxtx_bufsz = rxtx_bufsz;
+
+ mutex_init(&drv_info->rx_lock);
+ mutex_init(&drv_info->tx_lock);
+--
+2.53.0
+
--- /dev/null
+From 825bf576b206300c39fc7d59893baad62ed03b3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:53:39 +0530
+Subject: firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
+
+From: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+
+[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
+
+The scmi_notify() function is called from interrupt context to queue
+received notification events onto a per-protocol kfifo. When the kfifo
+is full, it logs a warning via dev_warn() for every dropped event.
+
+Under conditions where the platform sends a burst of SCMI notifications
+faster than the deferred worker can drain the queue, this results in a
+flood of dev_warn() calls from IRQ context. Each call acquires the
+console lock and may execute blocking console writes, causing the CPU
+to be held in interrupt context for an extended period and leading to
+observable system stalls.
+
+Fix this by switching to dev_warn_ratelimited() to limit the frequency
+of log messages when the notification queue is full. This reduces
+console overhead in interrupt context and prevents CPU stalls caused by
+excessive logging, while still preserving diagnostic visibility.
+
+Fixes: bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
+Signed-off-by: Pushpendra Singh <pushpendra.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260708072339.3021140-1-pushpendra.singh@oss.qualcomm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/notify.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
+index 40ec184eedaecc..0a192cf2deab62 100644
+--- a/drivers/firmware/arm_scmi/notify.c
++++ b/drivers/firmware/arm_scmi/notify.c
+@@ -600,9 +600,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
+ return -EINVAL;
+ }
+ if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
+- dev_warn(handle->dev,
+- "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
+- proto_id, evt_id, ktime_to_ns(ts));
++ dev_warn_ratelimited(handle->dev,
++ "queue full, dropping proto_id:%d evt_id:%d ts:%lld\n",
++ proto_id, evt_id, ktime_to_ns(ts));
+ return -ENOMEM;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 7e8784dcda18217f0ff477deb27ee98ab28c86e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 16:01:55 -0400
+Subject: IB/mad: Drop unmatched RMPP responses before reassembly
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
+
+Kernel-handled RMPP receive processing starts reassembly for active
+DATA responses before the response is matched to an outstanding send.
+The normal match happens later, after ib_process_rmpp_recv_wc() has
+either assembled a complete message or consumed the segment.
+
+That ordering lets an unsolicited response that routes to a kernel
+RMPP agent by the high TID bits allocate or extend RMPP receive state
+before the full TID and source address are checked against a real
+request. A reordered burst can therefore reach the receive-side
+insertion path even though the response would not match any send.
+
+For kernel-handled RMPP DATA responses, require the existing
+ib_find_send_mad() match before entering RMPP reassembly. The matcher
+already checks the full TID, management class and source address/GID
+against the agent wait, backlog and in-flight send lists. If there is
+no match, drop the response without creating RMPP state.
+
+This leaves the RMPP window behavior unchanged and only rejects
+responses that have no corresponding request.
+
+Fixes: fa619a77046b ("[PATCH] IB: Add RMPP implementation")
+Assisted-by: Codex:gpt-5-5-xhigh
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/3170ff3bc389a930bb1641f2caa394a0b2241579.1780774907.git.michael.bommarito@gmail.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 8d19613179e3ee..e0b3b36b8b1496 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -2031,6 +2031,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+ change_mad_state(mad_send_wr, IB_MAD_STATE_EARLY_RESP);
+ }
+
++static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
++ struct ib_mad_recv_wc *mad_recv_wc)
++{
++ const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
++ struct ib_rmpp_mad *rmpp_mad;
++
++ if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
++ !ib_response_mad(mad_hdr) ||
++ !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
++ return false;
++
++ rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
++
++ return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
++ IB_MGMT_RMPP_FLAG_ACTIVE) &&
++ rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
++}
++
+ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+ {
+@@ -2050,6 +2068,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
+ }
+
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
++ if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
++ spin_lock_irqsave(&mad_agent_priv->lock, flags);
++ mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
++ spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
++
++ if (!mad_send_wr) {
++ ib_free_recv_mad(mad_recv_wc);
++ deref_mad_agent(mad_agent_priv);
++ return;
++ }
++ }
++
+ if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
+ mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+ mad_recv_wc);
+--
+2.53.0
+
--- /dev/null
+From 0edc2d979a81e7e5884dc405d2dea63c6b0c962b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 10:14:21 -0700
+Subject: ipv4: fib: free fib_alias with kfree_rcu() on insert error path
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
+
+fib_table_insert() publishes new_fa into the leaf's fa_list with
+fib_insert_alias() before calling the fib entry notifiers. When a
+notifier fails, the error path removes new_fa with fib_remove_alias()
+(hlist_del_rcu) and frees it right away with kmem_cache_free().
+
+fib_table_lookup() walks that list under rcu_read_lock() only, so a
+concurrent lookup that already reached new_fa keeps reading it after the
+free:
+
+ BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ Read of size 1 at addr ffff88810676d4eb by task exploit/297
+ Call Trace:
+ fib_table_lookup (net/ipv4/fib_trie.c:1601)
+ ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
+ ip_route_output_key_hash (net/ipv4/route.c:2705)
+ __ip4_datagram_connect (net/ipv4/datagram.c:49)
+ udp_connect (net/ipv4/udp.c:2144)
+ __sys_connect (net/socket.c:2167)
+ __x64_sys_connect (net/socket.c:2173)
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+ which belongs to the cache ip_fib_alias of size 56
+
+Triggering the error path needs CAP_NET_ADMIN and a registered fib
+notifier that can reject a route; a netdevsim device whose IPv4 FIB
+resource is exhausted is enough.
+
+Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already
+does for a fib_alias removed from the trie.
+
+Fixes: a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260704171421.1786806-1-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_trie.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index dac543c1d6867a..9bf5550e2fb734 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1385,7 +1385,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ out_remove_new_fa:
+ fib_remove_alias(t, tp, l, new_fa);
+ out_free_new_fa:
+- kmem_cache_free(fn_alias_kmem, new_fa);
++ alias_free_mem_rcu(new_fa);
+ out:
+ fib_release_info(fi);
+ err:
+--
+2.53.0
+
--- /dev/null
+From 7eb5f1e5c6d9266e5164d21737ab5701b920e91d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 22:49:55 +0800
+Subject: ksmbd: pin conn during async oplock break notification
+
+From: Qihang <q.h.hack.winter@gmail.com>
+
+[ Upstream commit aa5d8f3f96aa11a4a54ce993c11ce8af11c546f9 ]
+
+smb2_oplock_break_noti() and smb2_lease_break_noti() store a ksmbd_conn
+pointer in an async ksmbd_work and then queue that work on ksmbd-io. The
+work only increments conn->r_count, which prevents teardown from passing
+the pending-request wait after the increment, but it does not pin the
+struct ksmbd_conn object.
+
+If connection teardown races with an oplock break notification, the last
+conn reference can be dropped before the queued worker finishes. The
+worker then uses the freed conn in ksmbd_conn_write() and
+ksmbd_conn_r_count_dec().
+
+Take a real conn reference when publishing the conn pointer to the async
+work item, and drop it after the notification work has decremented
+r_count. Apply the same lifetime rule to lease break notification, which
+uses the same work->conn pattern.
+
+Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification")
+Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index 60e7e821c2455d..3f28dc3b7fc415 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -705,6 +705,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -740,7 +741,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
+ br_info->open_trunc = opinfo->open_trunc;
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+@@ -814,6 +815,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
+ out:
+ ksmbd_free_work_struct(work);
+ ksmbd_conn_r_count_dec(conn);
++ ksmbd_conn_put(conn);
+ }
+
+ /**
+@@ -853,7 +855,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
+ memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
+
+ work->request_buf = (char *)br_info;
+- work->conn = conn;
++ work->conn = ksmbd_conn_get(conn);
+ work->sess = opinfo->sess;
+
+ ksmbd_conn_r_count_inc(conn);
+--
+2.53.0
+
--- /dev/null
+From 5e9a224853fbf0b1c5f9b6128e243c38ad762d73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 21:55:10 +0000
+Subject: ksmbd: validate compound request size before reading StructureSize2
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 15b38176fd1530372905c602fde51fe89ec8c877 ]
+
+When ksmbd validates a compound (chained) SMB2 request,
+ksmbd_smb2_check_message() reads pdu->StructureSize2 without first
+checking that the compound element is large enough to contain it.
+StructureSize2 is a 2-byte field at offset 64
+(__SMB2_HEADER_STRUCTURE_SIZE) from the start of each element.
+
+The compound-walking logic only guarantees that a full 64-byte SMB2
+header is present for the trailing element: when NextCommand is 0, len is
+reduced to the number of bytes remaining after next_smb2_rcv_hdr_off. A
+remote client can craft a compound request whose last element has exactly
+64 bytes, so the 2-byte StructureSize2 read at offset 64 extends one byte
+past the receive buffer, producing a slab-out-of-bounds read.
+
+ BUG: KASAN: slab-out-of-bounds in ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ Read of size 2 at addr ffff888012ae31ac by task kworker/0:1/14
+ The buggy address is located 172 bytes inside of allocated 173-byte region
+ Workqueue: ksmbd-io handle_ksmbd_work
+ Call Trace:
+ ...
+ kasan_report (mm/kasan/report.c:595)
+ ksmbd_smb2_check_message (fs/smb/server/smb2misc.c:402)
+ handle_ksmbd_work (fs/smb/server/server.c:119)
+ process_one_work (kernel/workqueue.c:3314)
+ worker_thread (kernel/workqueue.c:3397)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+Reject any compound element that is too small to hold StructureSize2
+before dereferencing it.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2misc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c
+index a1ddca21c47bf9..29f33ece30a94e 100644
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -399,6 +399,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
+ return 1;
+ }
+
++ if (len < __SMB2_HEADER_STRUCTURE_SIZE + sizeof(__le16)) {
++ ksmbd_debug(SMB, "Message is too small for StructureSize2\n");
++ return 1;
++ }
++
+ if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
+ if (!(command == SMB2_OPLOCK_BREAK_HE &&
+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 ||
+--
+2.53.0
+
--- /dev/null
+From f49a098fc019e13a696497b27c914a6207d98690 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 04:50:00 -0700
+Subject: mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
+
+On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed
+attribute table itself instead of calling ip_valid_fib_dump_req(). The
+RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is
+present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no
+RTA_OIF hits a NULL dereference.
+
+RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without
+CAP_NET_ADMIN, so an unprivileged user can trigger it.
+
+ Oops: general protection fault, probably for non-canonical address
+ 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
+ KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+ RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
+ Call Trace:
+ mpls_dump_routes (net/mpls/af_mpls.c:2236)
+ netlink_dump (net/netlink/af_netlink.c:2331)
+ __netlink_dump_start (net/netlink/af_netlink.c:2446)
+ rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
+ netlink_rcv_skb (net/netlink/af_netlink.c:2556)
+ netlink_unicast (net/netlink/af_netlink.c:1345)
+ netlink_sendmsg (net/netlink/af_netlink.c:1900)
+ __sock_sendmsg (net/socket.c:790)
+ ____sys_sendmsg (net/socket.c:2684)
+ ___sys_sendmsg (net/socket.c:2738)
+ __sys_sendmsg (net/socket.c:2770)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Skip unset attributes, as ip_valid_fib_dump_req() does.
+
+Fixes: 196cfebf8972 ("net/mpls: Handle kernel side filtering of route dumps")
+Assisted-by: Claude:claude-opus-4-8
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20260711114958.1009619-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mpls/af_mpls.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index 26340a7306b591..b64a8b1bac0961 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -2186,6 +2186,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+ int ifindex;
+
+ if (i == RTA_OIF) {
++ if (!tb[i])
++ continue;
++
+ ifindex = nla_get_u32(tb[i]);
+ filter->dev = dev_get_by_index_rcu(net, ifindex);
+ if (!filter->dev)
+--
+2.53.0
+
--- /dev/null
+From ba9c23cc262803ae82e8a122de13dfdffa5535e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 20:10:42 +0800
+Subject: mtd: fix double free and WARN_ON in add_mtd_device() error paths
+
+From: Xue Lei <Xue.Lei@windriver.com>
+
+[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]
+
+When device_register() or mtd_nvmem_add() fails inside
+add_mtd_device() for a partition, the error handling triggers
+mtd_release() via put_device() or device_unregister(). mtd_release()
+calls release_mtd_partition() which frees the mtd_info structure.
+However, callers such as mtd_add_partition() and add_mtd_partitions()
+also call free_partition() in their error paths, resulting in a double
+free.
+
+Additionally, release_mtd_partition() hits WARN_ON(!list_empty(
+&mtd->part.node)) because the partition node is still linked in the
+parent's partitions list when the release callback fires from the
+add_mtd_device() error path.
+
+Fix this by overriding dev->type and dev->release before put_device()
+in the error paths, so that device_release() invokes a no-op function
+instead of mtd_release(). For the mtd_nvmem_add() failure case,
+device_unregister() is replaced with device_del() to separate the
+device removal from the final kobject reference drop, allowing the
+override to take effect before put_device() is called.
+
+The callers' error paths (list_del + free_partition) remain the sole
+owners of mtd_info lifetime on add_mtd_device() failure, which is the
+expected contract.
+
+The normal partition teardown path is not affected: del_mtd_device()
+goes through kref_put() -> mtd_device_release() -> device_unregister()
+with dev->type still set to &mtd_devtype, so mtd_release() ->
+release_mtd_partition() continues to work correctly for the regular
+removal case.
+
+Reported-by: syzbot+e9c76b56dc05023b8117@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e9c76b56dc05023b8117
+Fixes: 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
+Signed-off-by: Xue Lei <Xue.Lei@windriver.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 57653777462887..16629382a787bd 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -105,6 +105,15 @@ static void mtd_release(struct device *dev)
+ device_destroy(&mtd_class, index + 1);
+ }
+
++/*
++ * No-op device release used in add_mtd_device() error paths.
++ * Prevents mtd_release() from being called via device_release(),
++ * which would free the mtd_info that the caller still manages.
++ */
++static void mtd_dev_release_nop(struct device *dev)
++{
++}
++
+ static void mtd_device_release(struct kref *kref)
+ {
+ struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
+@@ -799,10 +808,8 @@ int add_mtd_device(struct mtd_info *mtd)
+ mtd_check_of_node(mtd);
+ of_node_get(mtd_get_of_node(mtd));
+ error = device_register(&mtd->dev);
+- if (error) {
+- put_device(&mtd->dev);
++ if (error)
+ goto fail_added;
+- }
+
+ /* Add the nvmem provider */
+ error = mtd_nvmem_add(mtd);
+@@ -840,8 +847,16 @@ int add_mtd_device(struct mtd_info *mtd)
+ return 0;
+
+ fail_nvmem_add:
+- device_unregister(&mtd->dev);
++ device_del(&mtd->dev);
+ fail_added:
++ /*
++ * Clear type and set nop release to prevent mtd_release() ->
++ * release_mtd_partition() -> free_partition() from freeing mtd.
++ * The caller handles cleanup on failure.
++ */
++ mtd->dev.type = NULL;
++ mtd->dev.release = mtd_dev_release_nop;
++ put_device(&mtd->dev);
+ of_node_put(mtd_get_of_node(mtd));
+ fail_devname:
+ idr_remove(&mtd_idr, i);
+--
+2.53.0
+
--- /dev/null
+From fb3072abac909521520645fe9402932e8498680f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 09:53:17 +0800
+Subject: mtd: mtdswap: remove debugfs stats file on teardown
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
+
+mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the
+per-MTD debugfs directory, but mtdswap_remove_dev() never removes it
+before freeing the mtdswap_dev.
+
+Store the returned dentry and remove it during device teardown before the
+driver-private state is freed.
+
+Fixes: a32159024620 ("mtd: Add mtdswap block driver")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtdswap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
+index 866933fc84265d..f33f753f0a9fda 100644
+--- a/drivers/mtd/mtdswap.c
++++ b/drivers/mtd/mtdswap.c
+@@ -125,6 +125,7 @@ struct mtdswap_dev {
+
+ char *page_buf;
+ char *oob_buf;
++ struct dentry *debugfs_stats;
+ };
+
+ struct mtdswap_oobdata {
+@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
+ if (IS_ERR_OR_NULL(root))
+ return -1;
+
+- debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
++ d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
++ d, &mtdswap_fops);
+
+ return 0;
+ }
+@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
+ {
+ struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
+
++ debugfs_remove(d->debugfs_stats);
+ del_mtd_blktrans_dev(dev);
+ mtdswap_cleanup(d);
+ kfree(d);
+--
+2.53.0
+
--- /dev/null
+From e68acff71a768916ec6e4af8adf17e056e484b9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jun 2026 21:57:29 +0800
+Subject: mtd: nand: mtk-ecc: stop on ECC idle timeouts
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
+
+mtk_ecc_wait_idle() logs when the encoder or decoder does not become
+idle, but returns void. Callers can therefore configure a non-idle ECC
+engine or read parity bytes after an unconfirmed encoder idle state.
+
+Return the idle poll result and propagate it from the enable and encode
+paths that require the engine to be idle before continuing.
+
+Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/ecc-mtk.c b/drivers/mtd/nand/ecc-mtk.c
+index c75bb8b80cc1e1..96703f0a418ea2 100644
+--- a/drivers/mtd/nand/ecc-mtk.c
++++ b/drivers/mtd/nand/ecc-mtk.c
+@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = {
+ [ECC_DECIRQ_STA] = 0x144,
+ };
+
+-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+- enum mtk_ecc_operation op)
++static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
++ enum mtk_ecc_operation op)
+ {
+ struct device *dev = ecc->dev;
+ u32 val;
+@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ if (ret)
+ dev_warn(dev, "%s NOT idle\n",
+ op == ECC_ENCODE ? "encoder" : "decoder");
++
++ return ret;
+ }
+
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ return ret;
+ }
+
+- mtk_ecc_wait_idle(ecc, op);
++ ret = mtk_ecc_wait_idle(ecc, op);
++ if (ret) {
++ mutex_unlock(&ecc->lock);
++ return ret;
++ }
+
+ ret = mtk_ecc_config(ecc, config);
+ if (ret) {
+@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ if (ret)
+ goto timeout;
+
+- mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
++ if (ret)
++ goto timeout;
+
+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+ len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+--
+2.53.0
+
--- /dev/null
+From 387b03e12e51c7c44bda9b9a5e3e451731e8b93a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Jun 2026 01:10:52 -0700
+Subject: mtd: virt_concat: fix use-after-free in
+ mtd_virt_concat_destroy_joins()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 75c0c09541b49daa08fddbc2c18c2232f4eab7d8 ]
+
+mtd_concat_destroy() frees item->concat so calling
+mtd_virt_concat_put_mtd_devices(item->concat) leads to a use after free.
+
+Fix this by moving mtd_virt_concat_put_mtd_devices() before
+mtd_concat_destroy()
+
+Fixes: 43db6366fc2d ("mtd: Add driver for concatenating devices")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtd_virt_concat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtd_virt_concat.c b/drivers/mtd/mtd_virt_concat.c
+index 5db6e648927e29..5761816e7f4dca 100644
+--- a/drivers/mtd/mtd_virt_concat.c
++++ b/drivers/mtd/mtd_virt_concat.c
+@@ -75,8 +75,8 @@ void mtd_virt_concat_destroy_joins(void)
+ if (item->concat) {
+ mtd_device_unregister(mtd);
+ kfree(mtd->name);
+- mtd_concat_destroy(mtd);
+ mtd_virt_concat_put_mtd_devices(item->concat);
++ mtd_concat_destroy(mtd);
+ }
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 871e2b0f1c27a0a18bc99d8ed324767e10f83917 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jun 2026 03:14:39 -0700
+Subject: mtd: virt_concat: fix use-after-free in mtd_virt_concat_destroy()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 4b45d7836b9526b8776af5f29219615be9417230 ]
+
+mtd_concat_destroy() frees item->concat so calling
+mtd_virt_concat_put_mtd_devices(item->concat) after that leads to a
+use-after-free.
+
+Fix it by moving mtd_virt_concat_put_mtd_devices() before
+mtd_concat_destroy().
+
+Fixes: 43db6366fc2d ("mtd: Add driver for concatenating devices")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/mtd_virt_concat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/mtd_virt_concat.c b/drivers/mtd/mtd_virt_concat.c
+index 5761816e7f4dca..da4277ced4d63b 100644
+--- a/drivers/mtd/mtd_virt_concat.c
++++ b/drivers/mtd/mtd_virt_concat.c
+@@ -126,8 +126,8 @@ int mtd_virt_concat_destroy(struct mtd_info *mtd)
+ if (concat->mtd.name) {
+ del_mtd_device(&concat->mtd);
+ kfree(concat->mtd.name);
+- mtd_concat_destroy(&concat->mtd);
+ mtd_virt_concat_put_mtd_devices(item->concat);
++ mtd_concat_destroy(&concat->mtd);
+ }
+
+ for (idx = 0; idx < item->count; idx++)
+--
+2.53.0
+
--- /dev/null
+From 52a74c1890cfdd0bf5d494ced86c2ad515949edb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jul 2026 22:24:36 -0500
+Subject: net/iucv: take a reference on the socket found in afiucv_hs_rcv()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]
+
+afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
+drops the lock, and then passes the socket to the afiucv_hs_callback_*()
+handlers without holding a reference. AF_IUCV sockets are not
+RCU-protected and are freed synchronously by iucv_sock_kill() ->
+sock_put(), so a concurrent close can free the socket in the window
+between read_unlock() and the handler, which then dereferences freed
+memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
+
+Take a reference with sock_hold() while the socket is still on the list
+and release it with sock_put() once the handler has run.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index c2dc3338670e83..126b58bbc2a5f4 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2091,6 +2091,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+ }
++ if (sk)
++ sock_hold(sk);
+ read_unlock(&iucv_sk_list.lock);
+ if (!iucv)
+ sk = NULL;
+@@ -2140,6 +2142,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+ kfree_skb(skb);
+ }
+
++ if (sk)
++ sock_put(sk);
+ return err;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 0988d2c6cd0987a7891006fa3a3a472c9834ad44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jul 2026 11:05:37 -0400
+Subject: net/sched: act_tunnel_key: Defer dst_release to RCU callback
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
+
+Fix a race-condition use-after-free in tunnel_key_release_params().
+
+The function releases the metadata_dst of the old params synchronously
+via dst_release() while deferring the params struct free with
+kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may
+still hold the old params pointer (under rcu_read_lock_bh) and proceed
+to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's
+dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
+
+zdi-disclosures@trendmicro.com produced a poc which i (and Victor) verified
+that KASAN reports:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112
+BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109
+BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173
+BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168
+Write of size 4 at addr ffff88806158de40 by task poc/9388
+
+CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy)
+Tainted: [W]=WARN
+Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378
+ print_report+0x139/0x4ad mm/kasan/report.c:482
+ kasan_report+0xe4/0x1d0 mm/kasan/report.c:595
+ check_region_inline mm/kasan/generic.c:186
+ kasan_check_range+0x125/0x200 mm/kasan/generic.c:200
+ instrument_atomic_read_write include/linux/instrumented.h:112
+ atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326
+ __rcuref_put include/linux/rcuref.h:109
+ rcuref_put include/linux/rcuref.h:173
+ dst_release+0x5b/0x370 net/core/dst.c:168
+ refdst_drop include/net/dst.h:272
+ skb_dst_drop include/net/dst.h:284
+ skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163
+ skb_release_all net/core/skbuff.c:1187
+[..]
+Allocated by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398
+ __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263
+ __do_kmalloc_node mm/slub.c:5296
+ __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ kzalloc_noprof include/linux/slab.h:1188
+ offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35
+ tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+Freed by task 9391:
+ kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
+ kasan_save_track+0x14/0x30 mm/kasan/common.c:78
+ kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
+ poison_slab_object mm/kasan/common.c:253
+ __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285
+ kasan_slab_free include/linux/kasan.h:235
+ slab_free_hook mm/slub.c:2689
+ slab_free mm/slub.c:6251
+ kfree+0x21f/0x6b0 mm/slub.c:6566
+ tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284
+ tcf_action_offload_add net/sched/act_api.c:293
+ tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+
+The buggy address belongs to the object at ffff88806158de00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 64 bytes inside of
+ freed 256-byte region [ffff88806158de00, ffff88806158df00)
+
+The buggy address belongs to the physical page:
+page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c
+head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff)
+page_type: f5(slab)
+raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
+head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
+head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
+head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0
+ set_page_owner include/linux/page_owner.h:32
+ post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853
+ prep_new_page mm/page_alloc.c:1861
+ get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941
+ __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221
+ alloc_slab_page mm/slub.c:3278
+ allocate_slab mm/slub.c:3467
+ new_slab+0xa6/0x690 mm/slub.c:3525
+ refill_objects+0x271/0x420 mm/slub.c:7272
+ refill_sheaf mm/slub.c:2816
+ __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652
+ alloc_from_pcs mm/slub.c:4750
+ slab_alloc_node mm/slub.c:4884
+ __do_kmalloc_node mm/slub.c:5295
+ __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308
+ kmalloc_noprof include/linux/slab.h:954
+ metadata_dst_alloc+0x26/0x90 net/core/dst.c:298
+ tun_rx_dst include/net/dst_metadata.h:144
+ __ip_tun_set_dst include/net/dst_metadata.h:208
+ tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451
+ tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428
+ tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503
+ tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
+[..]
+==================================================================
+
+Fix by moving dst_release() into a custom RCU callback that runs
+after the grace period, matching the lifetime of the containing
+params struct. Readers in the datapath therefore always find a live
+rcuref when calling dst_clone().
+
+Fixes: 9174c3df1cd18 ("net/sched: act_tunnel_key: fix memory leak in case of action replace")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20260711150537.7946-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_tunnel_key.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 876b30c5709e1f..b14807761d829e 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -342,14 +342,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ };
+
+-static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++static void tunnel_key_release_params_rcu(struct rcu_head *head)
+ {
+- if (!p)
+- return;
++ struct tcf_tunnel_key_params *p = container_of(head, typeof(*p), rcu);
++
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
++ kfree(p);
++}
+
+- kfree_rcu(p, rcu);
++static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
++{
++ if (!p)
++ return;
++ call_rcu(&p->rcu, tunnel_key_release_params_rcu);
+ }
+
+ static int tunnel_key_init(struct net *net, struct nlattr *nla,
+--
+2.53.0
+
--- /dev/null
+From 76a5afd98dcb44bba10700b7ed3b01e3c100ab2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 21:33:09 -0700
+Subject: powerpc/85xx: Add fsl,ifc to common device ids
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit 25957f7c3dac3265332d766b71233e3622f17e14 ]
+
+Add fsl,ifc to mpc85xx_common_ids so that of_platform_bus_probe
+creates a platform device for the IFC node even without 'simple-bus'
+in its compatible property. On P1010 and similar platforms the IFC
+node is a direct child of the root, so it must be explicitly matched
+to be populated.
+
+Fixes: 0bf51cc9e9e5 ("powerpc: dts: mpc85xx: remove "simple-bus" compatible from ifc node")
+Assisted-by: opencode:big-pickle
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260604043309.91280-1-rosenp@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/85xx/common.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
+index 757811155587db..c11deb2f50ed45 100644
+--- a/arch/powerpc/platforms/85xx/common.c
++++ b/arch/powerpc/platforms/85xx/common.c
+@@ -42,6 +42,8 @@ static const struct of_device_id mpc85xx_common_ids[] __initconst = {
+ { .compatible = "fsl,qoriq-pcie-v2.3", },
+ { .compatible = "fsl,qoriq-pcie-v2.2", },
+ { .compatible = "fsl,fman", },
++ /* IFC NAND and NOR controllers */
++ { .compatible = "fsl,ifc", },
+ {},
+ };
+
+--
+2.53.0
+
--- /dev/null
+From 326cb1f90501ee24c19ffa93fe2833296cc9959a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 May 2026 15:16:37 +0200
+Subject: powerpc/time: Prepare to stop elapsing in dynticks-idle
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit c8ba971cf8567d49eb5f43ee90c4e50424331c18 ]
+
+Currently the tick subsystem stores the idle cputime accounting in
+private fields, allowing cohabitation with architecture idle vtime
+accounting. The former is fetched on online CPUs, the latter on offline
+CPUs.
+
+For consolidation purpose, architecture vtime accounting will continue
+to account the cputime but will make a break when the idle tick is
+stopped. The dyntick cputime accounting will then be relayed by the tick
+subsystem so that the idle cputime is still seen advancing coherently
+even when the tick isn't there to flush the idle vtime.
+
+Prepare for that and introduce three new APIs which will be used in
+subsequent patches:
+
+ - vtime_dynticks_start() is deemed to be called when idle enters in
+ dyntick mode. The idle cputime that elapsed so far is accumulated.
+
+ - vtime_dynticks_stop() is deemed to be called when idle exits from
+ dyntick mode. The vtime entry clocks are fast-forward to current time
+ so that idle accounting restarts elapsing from now.
+
+ - vtime_reset() is deemed to be called from dynticks idle IRQ entry to
+ fast-forward the clock to current time so that the IRQ time is still
+ accounted by vtime while nohz cputime is paused.
+
+Also accumulated vtime won't be flushed from dyntick-idle ticks to avoid
+accounting twice the idle cputime, along with nohz accounting.
+
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Link: https://patch.msgid.link/20260508131647.43868-6-frederic@kernel.org
+Stable-dep-of: c1c1ffa490fc ("powerpc/vtime: Initialize starttime at boot for native accounting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 41 ++++++++++++++++++++++++++++++++++++++
+ include/linux/vtime.h | 6 ++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index b4472288e0d434..3460d1a5a97c2a 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
+ acct->starttime = acct0->starttime;
+ }
+ }
++
++#ifdef CONFIG_NO_HZ_COMMON
++/**
++ * vtime_reset - Fast forward vtime entry clocks
++ *
++ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
++ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
++ */
++void vtime_reset(void)
++{
++ struct cpu_accounting_data *acct = get_accounting(current);
++
++ acct->starttime = mftb();
++#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
++ acct->startspurr = read_spurr(acct->starttime);
++#endif
++}
++
++/**
++ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
++ *
++ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
++ * is accumulated and the tick subsystem takes over the idle cputime accounting.
++ */
++void vtime_dyntick_start(void)
++{
++ vtime_account_idle(current);
++}
++
++/**
++ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
++ *
++ * Called when idle exits from dyntick mode. The vtime entry clocks are
++ * fast-forward to current time so that idle accounting restarts elapsing from
++ * now.
++ */
++void vtime_dyntick_stop(void)
++{
++ vtime_reset();
++}
++#endif /* CONFIG_NO_HZ_COMMON */
+ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+ void __no_kcsan __delay(unsigned long loops)
+diff --git a/include/linux/vtime.h b/include/linux/vtime.h
+index 29dd5b91dd7d66..3fc04b849e4e30 100644
+--- a/include/linux/vtime.h
++++ b/include/linux/vtime.h
+@@ -32,11 +32,17 @@ extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);
+ extern void vtime_account_softirq(struct task_struct *tsk);
+ extern void vtime_account_hardirq(struct task_struct *tsk);
+ extern void vtime_flush(struct task_struct *tsk);
++extern void vtime_reset(void);
++extern void vtime_dyntick_start(void);
++extern void vtime_dyntick_stop(void);
+ #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+ static inline void vtime_account_irq(struct task_struct *tsk, unsigned int offset) { }
+ static inline void vtime_account_softirq(struct task_struct *tsk) { }
+ static inline void vtime_account_hardirq(struct task_struct *tsk) { }
+ static inline void vtime_flush(struct task_struct *tsk) { }
++static inline void vtime_reset(void) { }
++static inline void vtime_dyntick_start(void) { }
++static inline void vtime_dyntick_stop(void) { }
+ #endif
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 549994e3e6a9e20c7768b8030d66fdf08cee20d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:13:29 +0530
+Subject: powerpc/vtime: Initialize starttime at boot for native accounting
+
+From: Shrikanth Hegde <sshegde@linux.ibm.com>
+
+[ Upstream commit c1c1ffa490fc33591e90852ed0d38804dd20bc36 ]
+
+It was observed that /proc/stat had very large value for one ore more
+CPUs. It was more visible after recent code simplifications around
+cpustats.
+
+System has 240 CPUs.
+
+cat /proc/uptime;
+194.18 46500.55
+cat /proc/stat
+cpu 5966 39 837032887 4650070 164 185 100 0 0 0
+cpu0 108 0 837030890 19109 24 4 23 0 0 0
+
+Since uptime is 194s, system time of each CPU can't be more than 19400.
+Sum of system time of all CPUs can't be more than 19400*240 4656000.
+In fact huge value is close to mftb(). Note mftb doesn't reset on powerVM
+when the LPAR restart. It only resets when whole system resets. The same
+issue exists for kexec too.
+
+This happens since starttime is not setup at init time. Once it is set
+then subsequent vtime_delta will return the right delta.
+
+Fix it by initializing the starttime during CPU initialization. This
+fixes the large times seen.
+
+cat /proc/uptime; cat /proc/stat
+15.78 3694.63
+cpu 6035 35 1347 369479 23 144 49 0 0 0
+cpu0 19 0 38 1508 0 1 14 0 0 0
+
+Now, system time is reported as expected.
+
+Fixes: cf9efce0ce31 ("powerpc: Account time using timebase rather than PURR")
+Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Suggested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
+Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260605124329.377533-1-sshegde@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 3460d1a5a97c2a..11145c40183dd1 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -377,7 +377,6 @@ void vtime_task_switch(struct task_struct *prev)
+ }
+ }
+
+-#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_reset - Fast forward vtime entry clocks
+ *
+@@ -394,6 +393,7 @@ void vtime_reset(void)
+ #endif
+ }
+
++#ifdef CONFIG_NO_HZ_COMMON
+ /**
+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
+ *
+@@ -933,6 +933,7 @@ static void __init set_decrementer_max(void)
+ static void __init init_decrementer_clockevent(void)
+ {
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ void secondary_cpu_time_init(void)
+@@ -948,6 +949,7 @@ void secondary_cpu_time_init(void)
+ /* FIME: Should make unrelated change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
++ vtime_reset();
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From 76e4e6adc75b897bca5e1e852a70bb9b42c5cc22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 11:01:59 +0200
+Subject: ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
+
+From: Norbert Szetei <norbert@doyensec.com>
+
+[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
+
+pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
+
+ l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
+ -> ppp_input(&po->chan)
+
+It runs under rcu_read_lock() holding only an l2tp_session reference and
+takes NO reference on the internal PPP channel (struct channel,
+chan->ppp) that ppp_input() dereferences.
+
+The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel
+are RCU-safe. But the internal struct channel is a separate allocation
+that ppp_release_channel() frees with a plain kfree():
+
+ close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
+ -> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
+
+For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit
+(no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips
+both ppp_disconnect_channel()'s synchronize_net() and
+ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace
+period. rcu_read_lock() in pppol2tp_recv() does not protect against a
+plain kfree(), so an in-flight ppp_input() on one CPU can dereference
+the channel just freed by close() on another CPU.
+
+The bug is reachable by an unprivileged user.
+
+Defer the channel free to an RCU callback via call_rcu() so the grace
+period fences any in-flight ppp_input(). The disconnect and unbridge
+teardown paths already fence with synchronize_net()/synchronize_rcu();
+call_rcu() does the same here without stalling the close() path.
+
+Fixes: ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Norbert Szetei <norbert@doyensec.com>
+Reviewed-by: Qingfang Deng <qingfang.deng@linux.dev>
+Link: https://patch.msgid.link/E793FCF2-58DE-4387-A983-C7B4BC3158BD@doyensec.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 57c68efa5ff81d..717c1d3aa95380 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -184,6 +184,7 @@ struct channel {
+ struct list_head clist; /* link in list of channels per unit */
+ spinlock_t upl; /* protects `ppp' and 'bridge' */
+ struct channel __rcu *bridge; /* "bridged" ppp channel */
++ struct rcu_head rcu; /* for RCU-deferred free of the channel */
+ #ifdef CONFIG_PPP_MULTILINK
+ u8 avail; /* flag used in multilink stuff */
+ u8 had_frag; /* >= 1 fragments have been sent */
+@@ -3562,6 +3563,18 @@ ppp_disconnect_channel(struct channel *pch)
+ return err;
+ }
+
++/* Purge after the grace period: a late ppp_input() may still queue an
++ * skb on pch->file.rq before the last RCU reader drains.
++ */
++static void ppp_release_channel_free(struct rcu_head *rcu)
++{
++ struct channel *pch = container_of(rcu, struct channel, rcu);
++
++ skb_queue_purge(&pch->file.xq);
++ skb_queue_purge(&pch->file.rq);
++ kfree(pch);
++}
++
+ /*
+ * Drop a reference to a ppp channel and free its memory if the refcount reaches
+ * zero.
+@@ -3581,9 +3594,7 @@ static void ppp_release_channel(struct channel *pch)
+ pr_err("ppp: destroying undead channel %p !\n", pch);
+ return;
+ }
+- skb_queue_purge(&pch->file.xq);
+- skb_queue_purge(&pch->file.rq);
+- kfree(pch);
++ call_rcu(&pch->rcu, ppp_release_channel_free);
+ }
+
+ static void __exit ppp_cleanup(void)
+@@ -3596,6 +3607,7 @@ static void __exit ppp_cleanup(void)
+ device_destroy(&ppp_class, MKDEV(PPP_MAJOR, 0));
+ class_unregister(&ppp_class);
+ unregister_pernet_device(&ppp_net_ops);
++ rcu_barrier(); /* wait for RCU callbacks before module unload */
+ }
+
+ /*
+--
+2.53.0
+
--- /dev/null
+From d645cd636b6bcd8f91d49e1609954a0b6cab8493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:21:05 +0300
+Subject: RDMA/cma: Fix hardware address comparison length in netevent callback
+
+From: Or Gerlitz <ogerlitz@ddn.com>
+
+[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
+
+The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
+
+This breaks IPoIB, which uses 20-byte addresses. By truncating the
+memcmp, the CMA may incorrectly assume the target address is
+unchanged and fails to abort the stalled connection.
+
+Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len
+to correctly evaluate the full address regardless of the link layer.
+
+Fixes: 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
+Signed-off-by: Or Gerlitz <ogerlitz@ddn.com>
+Link: https://patch.msgid.link/20260617-fix-cma-ipoib-v1-1-03f869344304@ddn.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 9480d1a51c116e..e88d3efb967b3b 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5270,7 +5270,7 @@ static int cma_netevent_callback(struct notifier_block *self,
+
+ list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
+ if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
+- neigh->ha, ETH_ALEN))
++ neigh->ha, neigh->dev->addr_len))
+ continue;
+ cma_id_get(current_id);
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
+--
+2.53.0
+
--- /dev/null
+From ee0b2558f1b1e76d34ce4ff285e0806b268fae17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jun 2026 10:01:48 +0800
+Subject: RDMA/core: Fix memory leak in __ib_create_cq() on invalid cqe
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit e939334ea7dd219f100f963dbb1cb43df520c20a ]
+
+Move the zero CQE validation before rdma_zalloc_drv_obj() to avoid
+leaking the CQ object when returning -EINVAL.
+
+Fixes: a2917582887a ("RDMA/core: Reject zero CQE count")
+Link: https://patch.msgid.link/r/20260625020148.224537-1-zhaochenguang@kylinos.cn
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/verbs.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index bac87de9cc6735..2f3237e6086b9b 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -2199,13 +2199,13 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
+ struct ib_cq *cq;
+ int ret;
+
++ if (WARN_ON_ONCE(!cq_attr->cqe))
++ return ERR_PTR(-EINVAL);
++
+ cq = rdma_zalloc_drv_obj(device, ib_cq);
+ if (!cq)
+ return ERR_PTR(-ENOMEM);
+
+- if (WARN_ON_ONCE(!cq_attr->cqe))
+- return ERR_PTR(-EINVAL);
+-
+ cq->device = device;
+ cq->comp_handler = comp_handler;
+ cq->event_handler = event_handler;
+--
+2.53.0
+
--- /dev/null
+From 29c11b10c4417645f9f3e03c996a0e24651c586b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:51 +0800
+Subject: RDMA/erdma: initialize ret for empty receive WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
+
+erdma_post_recv() returns ret after walking the receive work request list.
+If the caller passes an empty list, the loop is skipped and ret is not
+assigned.
+
+Initialize ret to 0 so an empty receive work request list returns success
+instead of stack data.
+
+Fixes: 155055771704 ("RDMA/erdma: Add verbs implementation")
+Link: https://patch.msgid.link/r/20260618041752.481193-1-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_qp.c b/drivers/infiniband/hw/erdma/erdma_qp.c
+index 25f6c49aec7798..e002343832f74d 100644
+--- a/drivers/infiniband/hw/erdma/erdma_qp.c
++++ b/drivers/infiniband/hw/erdma/erdma_qp.c
+@@ -734,7 +734,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
+ const struct ib_recv_wr *wr = recv_wr;
+ struct erdma_qp *qp = to_eqp(ibqp);
+ unsigned long flags;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&qp->lock, flags);
+
+--
+2.53.0
+
--- /dev/null
+From 35d0a2581e62a2889978f587729d711215c7c379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 09:59:51 +0000
+Subject: RDMA/hns: Fix potential integer overflow in mhop hem cleanup
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
+
+In hns_roce_cleanup_mhop_hem_table(), the expression:
+
+ obj = i * buf_chunk_size / table->obj_size;
+
+is evaluated using 32-bit unsigned arithmetic because
+'buf_chunk_size' is u32 and the usual arithmetic conversions convert
+'i' to unsigned int. The result is assigned to a u64 variable, but the
+multiplication may overflow before the assignment.
+
+For sufficiently large HEM tables, this produces an incorrect object
+index passed to hns_roce_table_mhop_put().
+
+Cast 'i' to u64 before the multiplication so that the intermediate
+calculation is performed with 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
+Link: https://patch.msgid.link/r/20260627095951.51378-1-listdansp@mail.ru
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Reviewed-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index ccb40f8a48b726..a38bfd9a0fe243 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -836,7 +836,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
+ mhop.bt_chunk_size;
+
+ for (i = 0; i < table->num_hem; ++i) {
+- obj = i * buf_chunk_size / table->obj_size;
++ obj = (u64)i * buf_chunk_size / table->obj_size;
+ if (table->hem[i])
+ hns_roce_table_mhop_put(hr_dev, table, obj, 0);
+ }
+--
+2.53.0
+
--- /dev/null
+From 47707891cb6d5d8b78b0a98b7ed0a80ca41ee122 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 17:48:46 +0300
+Subject: RDMA/irdma: Prevent overflows in memory contiguity checks
+
+From: Aleksandrova Alyona <aga@itb.spb.ru>
+
+[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
+
+irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that
+PBL entries describe physically contiguous memory ranges.
+
+Both functions calculate byte offsets using 32-bit operands. For example,
+with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when
+pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so
+i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
+
+These values are reachable in the driver. For MRs, palloc->total_cnt
+comes from iwmr->page_cnt, which is calculated by
+ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE,
+so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE
+resources do not exclude this value either: for gen3, the limit is based
+on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs
+are enough for 1048576 PBLEs.
+
+Cast one operand to u64 before the multiplications so that the offset
+calculations are performed in 64-bit arithmetic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Aleksandrova Alyona <aga@itb.spb.ru>
+Link: https://patch.msgid.link/20260624144846.61242-1-aga@itb.spb.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index e7f6ebd9c9557d..a886029411b81f 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -2815,7 +2815,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
+ u32 pg_idx;
+
+ for (pg_idx = 0; pg_idx < npages; pg_idx++) {
+- if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
++ if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
+ return false;
+ }
+
+@@ -2848,7 +2848,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+
+ for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
+ arr = leaf->addr;
+- if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
++ if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
+ return false;
+ ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
+ if (!ret)
+--
+2.53.0
+
--- /dev/null
+From ff24e9ad8c433500ee63795a896a16a4bf78a6a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 14:19:36 +0000
+Subject: RDMA/irdma: Prevent rereg_mr for non-mem regions
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]
+
+When a QP/CQ/SRQ is created, a two step process is used
+where the buffer is allocated in userspace and explicitly
+registered with the normal reg_mr mechanism prior to creating
+the actual QP/CQ/SRQ object.
+
+These special registrations are indicated via an ABI field
+so the driver knows that they do not have a valid mkey and
+to skip the actual CQP command submission.
+
+Since these are real MR objects from the core's perspective,
+it is possible for a user application to invoke rereg_mr on them
+and cause a real CQP op to be emitted with the zero-initialized
+mkey value of 0.
+
+Fix this by preventing rereg_mr on these special regions.
+
+Fixes: 5ac388db27c4 ("RDMA/irdma: Add support to re-register a memory region")
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 7da7a7e8b30ca2..a33bd3c8571247 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -3810,6 +3810,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
+ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
+ return ERR_PTR(-EOPNOTSUPP);
+
++ if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
++ return ERR_PTR(-EINVAL);
++
+ ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
+ if (ret)
+ return ERR_PTR(ret);
+--
+2.53.0
+
--- /dev/null
+From 3f368eb68d82be278d32f668d21f387beecc8b1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2026 16:40:13 +0000
+Subject: RDMA/irdma: Prevent user-triggered null deref on QP create
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit b9b0889071569d43623c260074e159cd8f26adb1 ]
+
+Previously, the user QP creation path would only attempt to
+populate iwqp->iwpbl if the user-provided req.user_wqe_bufs
+field was non-zero. The problem is that iwqp->iwpbl is
+unconditionally dereferenced later on in irdma_setup_virt_qp.
+
+While there was a check for iwqp->iwpbl != NULL, this check
+would only occur if req.user_wqe_bufs was non-zero. The end
+result is that a user could send a zero user_wqe_bufs value
+and trigger a null ptr deref.
+
+Fix this by unconditionally calling irdma_get_pbl and bailing
+if it fails, similar to the CQ and SRQ paths.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Link: https://patch.msgid.link/r/20260617164013.280790-1-jmoroni@google.com
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Reviewed-by: David Hu <xuehaohu@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 7ab08f324eb9a2..e7f6ebd9c9557d 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -633,17 +633,16 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
+
+ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
+ iwqp->user_mode = 1;
+- if (req.user_wqe_bufs) {
+- spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+- iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+- &ucontext->qp_reg_mem_list);
+- spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
+
+- if (!iwqp->iwpbl) {
+- ret = -ENODATA;
+- ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
+- return ret;
+- }
++ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
++ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
++ &ucontext->qp_reg_mem_list);
++ spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
++
++ if (!iwqp->iwpbl) {
++ ret = -ENODATA;
++ ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
++ return ret;
+ }
+
+ if (!ucontext->use_raw_attrs) {
+--
+2.53.0
+
--- /dev/null
+From 9f33fc6df425095e54961fb9d061cd345b5f23ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 21:44:22 +0000
+Subject: RDMA/irdma: Remove redundant legacy_mode checks
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit ed8621be482bf18dcd217aa024e95758bf9d28f2 ]
+
+The driver has the following invariants:
+
+1. legacy_mode is only allowed on GEN_1 hardware (enforced
+ in irdma_alloc_ucontext).
+
+2. GEN_1 hardware does not set IRDMA_FEATURE_CQ_RESIZE or
+ IRDMA_FEATURE_RTS_AE. These feature flags are only set
+ for GEN_2 and GEN_3 hardware.
+
+Therefore, legacy_mode is always false if IRDMA_FEATURE_CQ_RESIZE
+or IRDMA_FEATURE_RTS_AE is set, so remove the redundant checks.
+
+Link: https://patch.msgid.link/r/20260602214423.1315105-1-jmoroni@google.com
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: b9b088907156 ("RDMA/irdma: Prevent user-triggered null deref on QP create")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/uk.c | 9 +++------
+ drivers/infiniband/hw/irdma/user.h | 1 -
+ drivers/infiniband/hw/irdma/verbs.c | 7 +------
+ 3 files changed, 4 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index 4718acf6c6fd00..a34883fe998368 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -1568,15 +1568,12 @@ static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {
+ * irdma_setup_connection_wqes - setup WQEs necessary to complete
+ * connection.
+ * @qp: hw qp (user and kernel)
+- * @info: qp initialization info
+ */
+-static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
+- struct irdma_qp_uk_init_info *info)
++static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp)
+ {
+ u16 move_cnt = 1;
+
+- if (!info->legacy_mode &&
+- (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE))
++ if (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE)
+ move_cnt = 3;
+
+ qp->conn_wqes = move_cnt;
+@@ -1727,7 +1724,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
+ sq_ring_size = qp->sq_size << info->sq_shift;
+ IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
+ if (info->first_sq_wq) {
+- irdma_setup_connection_wqes(qp, info);
++ irdma_setup_connection_wqes(qp);
+ qp->swqe_polarity = 1;
+ qp->first_sq_wq = true;
+ } else {
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index 008af1acc92884..4dd3776a4cddb6 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -563,7 +563,6 @@ struct irdma_qp_uk_init_info {
+ u8 sq_shift;
+ u8 rq_shift;
+ int abi_ver;
+- bool legacy_mode;
+ struct irdma_srq_uk *srq_uk;
+ };
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index a33bd3c8571247..7ab08f324eb9a2 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -634,7 +634,6 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
+ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
+ iwqp->user_mode = 1;
+ if (req.user_wqe_bufs) {
+- info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode;
+ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+ &ucontext->qp_reg_mem_list);
+@@ -2074,10 +2073,6 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
+ rdma_udata_to_drv_context(udata, struct irdma_ucontext,
+ ibucontext);
+
+- /* CQ resize not supported with legacy GEN_1 libi40iw */
+- if (ucontext->legacy_mode)
+- return -EOPNOTSUPP;
+-
+ if (ib_copy_from_udata(&req, udata,
+ min(sizeof(req), udata->inlen)))
+ return -EINVAL;
+@@ -2559,7 +2554,7 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ cqmr = &iwpbl->cq_mr;
+
+ if (rf->sc_dev.hw_attrs.uk_attrs.feature_flags &
+- IRDMA_FEATURE_CQ_RESIZE && !ucontext->legacy_mode) {
++ IRDMA_FEATURE_CQ_RESIZE) {
+ spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
+ iwpbl_shadow = irdma_get_pbl(
+ (unsigned long)req.user_shadow_area,
+--
+2.53.0
+
--- /dev/null
+From 0f10d4ac619a720c8b3e214bd41ee6cca3c5dc97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2026 12:17:52 +0800
+Subject: RDMA/mana_ib: initialize err for empty send WR lists
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 155fd5ce2382b0ffbec0d7ee7b3a6818a27a5aed ]
+
+mana_ib_post_send() returns err after walking the send work request list.
+If the caller passes an empty list, the loop is skipped and err is not
+assigned.
+
+Initialize err to 0 so an empty send work request list returns success
+instead of stack data.
+
+Fixes: c8017f5b4856 ("RDMA/mana_ib: UD/GSI work requests")
+Link: https://patch.msgid.link/r/20260618041752.481193-2-ruoyuw560@gmail.com
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mana/wr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mana/wr.c b/drivers/infiniband/hw/mana/wr.c
+index 1813567d3b16c9..36a1d506f08f65 100644
+--- a/drivers/infiniband/hw/mana/wr.c
++++ b/drivers/infiniband/hw/mana/wr.c
+@@ -144,7 +144,7 @@ static int mana_ib_post_send_ud(struct mana_ib_qp *qp, const struct ib_ud_wr *wr
+ int mana_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+ {
+- int err;
++ int err = 0;
+ struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
+
+ for (; wr; wr = wr->next) {
+--
+2.53.0
+
--- /dev/null
+From 4befd8f93b4b7d8c7387e143d07e06f29b582f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jun 2026 14:00:40 +0800
+Subject: RDMA/siw: publish QP after initialization
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
+
+siw_create_qp() currently calls siw_qp_add() before the queues, CQ
+pointers, state, completion, and device list entry are ready. A QPN
+lookup can therefore reach a QP that is still being constructed.
+
+Move siw_qp_add() to the end of siw_create_qp(), after QP
+initialization and before adding the QP to the siw device list.
+
+Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
+Link: https://patch.msgid.link/r/20260630060040.966461-1-ruoyuw560@gmail.com
+Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 1e1d262a4ae2db..a513ca96259fd2 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -316,6 +316,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ struct siw_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct siw_ucontext,
+ base_ucontext);
++ struct siw_uresp_create_qp uresp = {};
+ unsigned long flags;
+ int num_sqe, num_rqe, rv = 0;
+ size_t length;
+@@ -369,11 +370,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+- rv = siw_qp_add(sdev, qp);
+- if (rv)
+- goto err_atomic;
+-
+-
+ /* All queue indices are derived from modulo operations
+ * on a free running 'get' (consumer) and 'put' (producer)
+ * unsigned counter. Having queue sizes at power of two
+@@ -391,14 +387,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->sendq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
+ if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
+ qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
+ else {
+ rv = -EINVAL;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+ qp->pd = pd;
+@@ -424,7 +420,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+
+ if (qp->recvq == NULL) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ qp->attrs.rq_size = num_rqe;
+ }
+@@ -439,11 +435,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+- struct siw_uresp_create_qp uresp = {};
+-
+ uresp.num_sqe = num_sqe;
+ uresp.num_rqe = num_rqe;
+- uresp.qp_id = qp_id(qp);
+
+ if (qp->sendq) {
+ length = num_sqe * sizeof(struct siw_sqe);
+@@ -452,7 +445,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ length, &uresp.sq_key);
+ if (!qp->sq_entry) {
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
+
+@@ -464,9 +457,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (!qp->rq_entry) {
+ uresp.sq_key = SIW_INVAL_UOBJ_KEY;
+ rv = -ENOMEM;
+- goto err_out_xa;
++ goto err_out;
+ }
+ }
++ }
++ qp->tx_cpu = siw_get_tx_cpu(sdev);
++ if (qp->tx_cpu < 0) {
++ rv = -EINVAL;
++ goto err_out;
++ }
++ init_completion(&qp->qp_free);
++
++ rv = siw_qp_add(sdev, qp);
++ if (rv)
++ goto err_out_tx;
++
++ if (udata) {
++ uresp.qp_id = qp_id(qp);
+
+ if (udata->outlen < sizeof(uresp)) {
+ rv = -EINVAL;
+@@ -476,22 +483,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ if (rv)
+ goto err_out_xa;
+ }
+- qp->tx_cpu = siw_get_tx_cpu(sdev);
+- if (qp->tx_cpu < 0) {
+- rv = -EINVAL;
+- goto err_out_xa;
+- }
++
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_add_tail(&qp->devq, &sdev->qp_list);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+- init_completion(&qp->qp_free);
+-
+ return 0;
+
+ err_out_xa:
+ xa_erase(&sdev->qp_xa, qp_id(qp));
++err_out_tx:
++ siw_put_tx_cpu(qp->tx_cpu);
++err_out:
+ if (uctx) {
+ rdma_user_mmap_entry_remove(qp->sq_entry);
+ rdma_user_mmap_entry_remove(qp->rq_entry);
+--
+2.53.0
+
--- /dev/null
+From 797a4676ed8f5e91b33f9f756e4dcbd0e5cd2cbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 02:58:37 +0000
+Subject: reset: spacemit: k3: fix USB2 ahb reset
+
+From: Yixun Lan <dlan@kernel.org>
+
+[ Upstream commit 1ca22c6aa006b05143367268066fb74e32cfe66b ]
+
+According to SpacemiT K3's updated docs, the USB2 ahb reset and USB2 bus
+clock enable bit was wrongly swapped, the correct one should be:
+
+Register : APMU_USB_CLK_RES_CTRL
+bit[1] : usb2_port_bus_clk_en
+bit[0] : usb2_port_ahb_rstn
+
+Fixes: a0e0c2f8c5f3 ("reset: spacemit: k3: Decouple composite reset lines")
+Reported-by: Junzhong Pan <panjunzhong@linux.spacemit.com>
+Signed-off-by: Yixun Lan <dlan@kernel.org>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/spacemit/reset-spacemit-k3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/reset/spacemit/reset-spacemit-k3.c b/drivers/reset/spacemit/reset-spacemit-k3.c
+index 9841f5e057b2a0..2e87f320cf1184 100644
+--- a/drivers/reset/spacemit/reset-spacemit-k3.c
++++ b/drivers/reset/spacemit/reset-spacemit-k3.c
+@@ -112,7 +112,7 @@ static const struct ccu_reset_data k3_apmu_resets[] = {
+ [RESET_APMU_SDH0] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_APMU_SDH1] = RESET_DATA(APMU_SDH1_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_APMU_SDH2] = RESET_DATA(APMU_SDH2_CLK_RES_CTRL, 0, BIT(1)),
+- [RESET_APMU_USB2_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(1)),
++ [RESET_APMU_USB2_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_APMU_USB2_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(2)),
+ [RESET_APMU_USB2_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(3)),
+ [RESET_APMU_USB3_A_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(5)),
+--
+2.53.0
+
--- /dev/null
+From cae581b9743fc95c76c2c99da12f3737663eedf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 21:04:14 +0800
+Subject: riscv: Gate FUNCTION_ALIGNMENT_4B on DYNAMIC_FTRACE
+
+From: Rui Qi <qirui.001@bytedance.com>
+
+[ Upstream commit 3a2694bf6ac8e47b3814293e80343f58fc72937f ]
+
+The FUNCTION_ALIGNMENT_4B select forces the whole kernel to be built
+with -fmin-function-alignment=4. This alignment is only needed so the
+patchable-function-entry NOPs, which arch/riscv/Makefile emits under
+CONFIG_DYNAMIC_FTRACE, can be patched reliably on RISCV_ISA_C=y builds
+where compressed instructions otherwise allow 2-byte function
+alignment.
+
+The select is currently gated on HAVE_DYNAMIC_FTRACE, a capability bit
+that is selected whenever the toolchain supports dynamic ftrace, rather
+than on whether tracing is actually enabled. As a result every
+RISCV_ISA_C=y build gets 4-byte function alignment across the entire
+kernel even when function tracing is disabled, needlessly growing the
+kernel image and wasting instruction cache for a feature that is not
+in use.
+
+Gate the select on DYNAMIC_FTRACE instead, matching the condition under
+which arch/riscv/Makefile emits -fpatchable-function-entry, so the
+alignment is only applied when it is actually needed.
+
+Fixes: c41bf4326c7b ("riscv: ftrace: align patchable functions to 4 Byte boundary")
+Signed-off-by: Rui Qi <qirui.001@bytedance.com>
+Link: https://patch.msgid.link/20260706130415.463682-1-qirui.001@bytedance.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index c5754942cf85a4..e73f556720c1cf 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -155,7 +155,7 @@ config RISCV
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_CONTIGUOUS if MMU
+ select HAVE_DYNAMIC_FTRACE if MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
+- select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
++ select FUNCTION_ALIGNMENT_4B if DYNAMIC_FTRACE && RISCV_ISA_C
+ select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
+ select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI)
+ select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
+--
+2.53.0
+
--- /dev/null
+From dc3c4ec4c3f42ed2b8d63e703a1a710a686d3fc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 17:30:56 -0700
+Subject: riscv: hwprobe: Avoid uninitialized read in hwprobe_get_cpus()
+
+From: Mark Harris <mark.hsj@gmail.com>
+
+[ Upstream commit 5caae1deee89a6582c761d5dcd4b924b744426cc ]
+
+When cpusetsize < cpumask_size(), hwprobe_get_cpus() did not fully
+initialize its copy of the cpu mask, which could cause non-deterministic
+results from the riscv_hwprobe syscall on a system with more than 8 CPUs
+when the supplied cpu mask is empty. Address this by fully initializing
+the cpu mask.
+
+Fixes: e178bf146e4b ("RISC-V: hwprobe: Introduce which-cpus flag")
+Signed-off-by: Mark Harris <mark.hsj@gmail.com>
+Reviewed-by: Nam Cao <namcao@linutronix.de>
+Reviewed-by: Michael Ellerman <mpe@kernel.org>
+Link: https://patch.msgid.link/20260714003056.73707-1-mark.hsj@gmail.com
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/sys_hwprobe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
+index 1659d31fd288fc..caf6762427c87e 100644
+--- a/arch/riscv/kernel/sys_hwprobe.c
++++ b/arch/riscv/kernel/sys_hwprobe.c
+@@ -450,6 +450,7 @@ static int hwprobe_get_cpus(struct riscv_hwprobe __user *pairs,
+ if (cpusetsize > cpumask_size())
+ cpusetsize = cpumask_size();
+
++ cpumask_clear(&cpus);
+ ret = copy_from_user(&cpus, cpus_user, cpusetsize);
+ if (ret)
+ return -EFAULT;
+--
+2.53.0
+
--- /dev/null
+From 87c3655f8900c9bc6a2e68b7cdf559768b22a185 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 12:02:14 +0200
+Subject: s390/checksum: Fix csum_partial() without vector facility
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+[ Upstream commit 4bb06b60d982355e22647b3d12d6619419f8c1fa ]
+
+Currently csum_partial() calls csum_copy() with copy=false and dst=NULL.
+On machines without the vector facility, csum_copy() falls back to
+cksm(dst, ...), causing the checksum to be calculated from address zero
+instead of the source buffer.
+
+The VX implementation already checksums data loaded from src. Make the
+fallback do the same by passing src to cksm().
+
+Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/lib/csum-partial.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/lib/csum-partial.c b/arch/s390/lib/csum-partial.c
+index 458abd9bac7025..9d74ceff136c54 100644
+--- a/arch/s390/lib/csum-partial.c
++++ b/arch/s390/lib/csum-partial.c
+@@ -23,7 +23,7 @@ static __always_inline __wsum csum_copy(void *dst, const void *src, int len, __w
+ if (!cpu_has_vx()) {
+ if (copy)
+ memcpy(dst, src, len);
+- return cksm(dst, len, sum);
++ return cksm(src, len, sum);
+ }
+ kernel_fpu_begin(&vxstate, KERNEL_VXR_V16V23);
+ fpu_vlvgf(16, (__force u32)sum, 1);
+--
+2.53.0
+
--- /dev/null
+From 69f5da0b892c4cb9bd92ba737e63d37806124566 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 12:40:51 -1000
+Subject: sched_ext: Annotate ksyncs with __rcu in alloc/free_kick_syncs()
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit 115d1ce989747045bd7745c7ab020982660c7e42 ]
+
+scx_kick_syncs is a per-CPU __rcu pointer, so per_cpu_ptr() returns struct
+scx_kick_syncs __rcu **. alloc_kick_syncs() and free_kick_syncs() stored it
+in a plain struct scx_kick_syncs **ksyncs, which sparse flags as an __rcu
+address-space mismatch. Annotate ksyncs to match. Its accesses already go
+through rcu_*_pointer().
+
+Fixes: 987e00035c0e ("sched_ext: Rename pnt_seq to kick_sync")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202606122315.pbnDHP0n-lkp@intel.com/
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index 8429bebc21a19a..0e13139a7f27b9 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -5615,7 +5615,7 @@ static void free_kick_syncs(void)
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+- struct scx_kick_syncs **ksyncs = per_cpu_ptr(&scx_kick_syncs, cpu);
++ struct scx_kick_syncs __rcu **ksyncs = per_cpu_ptr(&scx_kick_syncs, cpu);
+ struct scx_kick_syncs *to_free;
+
+ to_free = rcu_replace_pointer(*ksyncs, NULL, true);
+@@ -6538,7 +6538,7 @@ static int alloc_kick_syncs(void)
+ * can exceed percpu allocator limits on large machines.
+ */
+ for_each_possible_cpu(cpu) {
+- struct scx_kick_syncs **ksyncs = per_cpu_ptr(&scx_kick_syncs, cpu);
++ struct scx_kick_syncs __rcu **ksyncs = per_cpu_ptr(&scx_kick_syncs, cpu);
+ struct scx_kick_syncs *new_ksyncs;
+
+ WARN_ON_ONCE(rcu_access_pointer(*ksyncs));
+--
+2.53.0
+
--- /dev/null
+From f10c175e6eb42f587ca4e64f41ca4942096aec9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jun 2026 12:55:48 -1000
+Subject: sched_ext: Don't warn on core-sched forced idle in
+ put_prev_task_scx()
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit b7d9c359e5cf867f7eb23df3bb1c6b9e58af24da ]
+
+put_prev_task_scx() warns when a runnable task drops to a lower sched_class
+without SCX_OPS_ENQ_LAST, on the assumption that balance_one() would have
+kept it running. Core scheduling breaks that: a forced-idle SMT sibling
+reschedules through the core_pick fast path in pick_next_task(), which skips
+pick_task_scx() and thus balance_one(), so a runnable task can drop to idle
+with ENQ_LAST unset.
+
+Gate the warning on sched_cpu_cookie_match(): a cookie mismatch means core
+scheduling forced the idle, while a match (or core scheduling off) still
+catches a genuine missing-ENQ_LAST drop.
+
+Fixes: 7c65ae81ea86 ("sched_ext: Don't call put_prev_task_scx() before picking the next task")
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index 0e13139a7f27b9..5f1accb092e30b 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -3097,9 +3097,14 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
+ * sched_class, %SCX_OPS_ENQ_LAST must be set. Tell
+ * ops.enqueue() that @p is the only one available for this cpu,
+ * which should trigger an explicit follow-up scheduling event.
++ *
++ * Core scheduling can force this CPU idle while @p stays
++ * runnable. @p's cookie then won't match the core's, so skip
++ * the warning in that case.
+ */
+ if (next && sched_class_above(&ext_sched_class, next->sched_class)) {
+- WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_LAST));
++ WARN_ON_ONCE(sched_cpu_cookie_match(rq, p) &&
++ !(sch->ops.flags & SCX_OPS_ENQ_LAST));
+ do_enqueue_task(rq, p, SCX_ENQ_LAST, -1);
+ } else {
+ do_enqueue_task(rq, p, 0, -1);
+--
+2.53.0
+
--- /dev/null
+From 3f414202e8855beec0f3f3cef546264d1a88497b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 09:46:48 +0200
+Subject: sched_ext: Enable tick for finite slices on nohz_full
+
+From: Andrea Righi <arighi@nvidia.com>
+
+[ Upstream commit 4ec10f38ff901dc10503d57cbdcf941248419ac1 ]
+
+set_next_task_scx() updates the tick dependency before __schedule()
+updates rq->curr. When switching from a non-EXT task, such as idle, to
+an EXT task with a finite slice, sched_update_tick_dependency() checks
+the outgoing task and can allow the tick to remain stopped.
+
+The dependency can also be lost without a slice-type transition. After a
+finite-slice task leaves the CPU idle, the enqueue path can clear the
+dependency against the idle rq->curr. SCX_RQ_CAN_STOP_TICK still records
+a finite slice, so another finite task skips the transition block and
+can run without the ticks needed to expire its slice.
+
+The reverse mismatch can also happen when the last finite-slice EXT task
+is dequeued: sub_nr_running() updates the dependency before rq->curr
+changes, so the outgoing task state can keep the dependency set after
+the CPU goes idle.
+
+Fix this by unconditionally enabling the scheduler tick whenever a
+finite-slice EXT task is selected on a nohz_full CPU. Moreover, when the
+last runnable EXT task leaves, ignore the outgoing EXT slice state so
+the generic scheduler can correctly re-evaluate and clear the tick
+dependency.
+
+Fixes: 22a920209ab6 ("sched_ext: Implement tickless support")
+Signed-off-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 47 ++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 35 insertions(+), 12 deletions(-)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index 5f1accb092e30b..432c4c68a2c010 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -2985,24 +2985,38 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, bool first)
+
+ /*
+ * @p is getting newly scheduled or got kicked after someone updated its
+- * slice. Refresh whether tick can be stopped. See scx_can_stop_tick().
++ * slice. Update SCX_RQ_CAN_STOP_TICK to reflect whether the tick can be
++ * stopped. See scx_can_stop_tick().
++ *
++ * Moreover, refresh the load_avgs just when transitioning in and out of
++ * nohz. In the future, we might want to add a mechanism to update
++ * load_avgs periodically on tick-stopped CPUs.
+ */
+- if ((p->scx.slice == SCX_SLICE_INF) !=
+- (bool)(rq->scx.flags & SCX_RQ_CAN_STOP_TICK)) {
+- if (p->scx.slice == SCX_SLICE_INF)
++ if (p->scx.slice == SCX_SLICE_INF) {
++ if (!(rq->scx.flags & SCX_RQ_CAN_STOP_TICK)) {
++ /*
++ * Bypass mode always assigns finite slices, so @p
++ * can't have an infinite slice while bypassing.
++ * Therefore, sched_update_tick_dependency() can safely
++ * evaluate the outgoing task.
++ */
+ rq->scx.flags |= SCX_RQ_CAN_STOP_TICK;
+- else
+- rq->scx.flags &= ~SCX_RQ_CAN_STOP_TICK;
++ sched_update_tick_dependency(rq);
+
+- sched_update_tick_dependency(rq);
++ update_other_load_avgs(rq);
++ }
++ } else {
++ if (rq->scx.flags & SCX_RQ_CAN_STOP_TICK) {
++ rq->scx.flags &= ~SCX_RQ_CAN_STOP_TICK;
++ update_other_load_avgs(rq);
++ }
+
+ /*
+- * For now, let's refresh the load_avgs just when transitioning
+- * in and out of nohz. In the future, we might want to add a
+- * mechanism which calls the following periodically on
+- * tick-stopped CPUs.
++ * @rq still references the outgoing scheduling context. A finite
++ * slice is sufficient by itself to require the tick.
+ */
+- update_other_load_avgs(rq);
++ if (tick_nohz_full_cpu(cpu_of(rq)))
++ tick_nohz_dep_set_cpu(cpu_of(rq), TICK_DEP_BIT_SCHED);
+ }
+ }
+
+@@ -4296,6 +4310,15 @@ bool scx_can_stop_tick(struct rq *rq)
+ if (p->sched_class != &ext_sched_class)
+ return true;
+
++ /*
++ * @rq->curr may still reference an outgoing EXT task after it has been
++ * dequeued. If no EXT tasks are accounted on @rq, ignore its stale
++ * slice state. If another task is dispatched from a DSQ,
++ * set_next_task_scx() will update the dependency for the incoming task.
++ */
++ if (!rq->scx.nr_running)
++ return true;
++
+ if (scx_bypassing(sch, cpu_of(rq)))
+ return false;
+
+--
+2.53.0
+
--- /dev/null
+From 00994572199d328af60b9a06acea5e225eeaf7d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2026 11:08:13 -1000
+Subject: sched_ext: Record an error on errno-only sub-enable failure
+
+From: Tejun Heo <tj@kernel.org>
+
+[ Upstream commit db4e9defd2e8620abee04cfe5809c0bcd6ecf06a ]
+
+scx_sub_enable_workfn() has several failure paths that only return an errno
+(e.g. -ENOMEM from an allocation) and jump to err_disable without calling
+scx_error(). scx_flush_disable_work() runs the disable, and thus ops.exit(),
+only when an error has been recorded, so an errno-only failure leaves the
+half-initialized sub-scheduler linked.
+
+Record an error at the err_disable sink so every errno-only failure runs the
+disable path.
+
+Fixes: ebeca1f930ea ("sched_ext: Introduce cgroup sub-sched support")
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
+index 432c4c68a2c010..46f7b33b565ba3 100644
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -7440,6 +7440,12 @@ static void scx_sub_enable_workfn(struct kthread_work *work)
+ percpu_up_write(&scx_fork_rwsem);
+ err_disable:
+ mutex_unlock(&scx_enable_mutex);
++ /*
++ * Some enable failures only return an errno (e.g. -ENOMEM from an
++ * allocation) without calling scx_error(). Record it so
++ * scx_flush_disable_work() runs the disable and ops.exit() fires.
++ */
++ scx_error(sch, "scx_sub_enable() failed (%d)", ret);
+ scx_flush_disable_work(sch);
+ cmd->ret = 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From fe244be3b03220ff6d4bace6559b6b46fffa982d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 13:46:30 -0400
+Subject: scsi: core: wake eh reliably when using scsi_schedule_eh
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit dccf3b1798b70f94e958b3d00b83010399e6fb05 ]
+
+Drivers which use the scsi_schedule_eh function to run the error handler
+currently risk the error handler thread never waking once all commands are
+timed out or inactive. There is no enforced memory order between setting
+the host into error recovery state and counting busy commands. This can
+result in a race with scsi_dec_host_busy where neither CPU sees both
+conditions of all commands inactive and the host error state to request
+waking the error handler.
+
+To fix this, run the scsi_schedule_eh's scsi_eh_wakeup from a new work item
+which will use rcu to ensure scsi_schedule_eh's call to scsi_host_busy will
+occur after the error state is globally visible and will be seen by any
+current scsi_dec_host_busy callers.
+
+Fixes: 6eb045e092ef ("scsi: core: avoid host-wide host_busy counter for scsi_mq")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Link: https://patch.msgid.link/20260615174630.11492-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hosts.c | 2 ++
+ drivers/scsi/scsi_error.c | 22 +++++++++++++++++++++-
+ drivers/scsi/scsi_priv.h | 1 +
+ include/scsi/scsi_host.h | 3 +++
+ 4 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index e047747d4ecf81..46cc8e3c79a26e 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -357,6 +357,7 @@ static void scsi_host_dev_release(struct device *dev)
+ /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
+ rcu_barrier();
+
++ cancel_work_sync(&shost->eh_work);
+ if (shost->tmf_work_q)
+ destroy_workqueue(shost->tmf_work_q);
+ if (shost->ehandler)
+@@ -422,6 +423,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
+ INIT_LIST_HEAD(&shost->starved_list);
+ init_waitqueue_head(&shost->host_wait);
+ mutex_init(&shost->scan_mutex);
++ INIT_WORK(&shost->eh_work, scsi_rcu_eh_wakeup);
+
+ index = ida_alloc(&host_index_ida, GFP_KERNEL);
+ if (index < 0) {
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 147127fb4db9cc..453a2232452dba 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -73,6 +73,26 @@ void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy)
+ }
+ }
+
++void scsi_rcu_eh_wakeup(struct work_struct *work)
++{
++ struct Scsi_Host *shost = container_of(work, struct Scsi_Host, eh_work);
++ unsigned long flags;
++ unsigned int busy;
++
++ /*
++ * Ensure any running scsi_dec_host_busy has completed its rcu section
++ * so changes to host state and host_eh_scheduled are visible to all
++ * future calls of scsi_dec_host_busy
++ */
++ synchronize_rcu();
++
++ busy = scsi_host_busy(shost);
++
++ spin_lock_irqsave(shost->host_lock, flags);
++ scsi_eh_wakeup(shost, busy);
++ spin_unlock_irqrestore(shost->host_lock, flags);
++}
++
+ /**
+ * scsi_schedule_eh - schedule EH for SCSI host
+ * @shost: SCSI host to invoke error handling on.
+@@ -88,7 +108,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
+ if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 ||
+ scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) {
+ shost->host_eh_scheduled++;
+- scsi_eh_wakeup(shost, scsi_host_busy(shost));
++ queue_work(shost->tmf_work_q, &shost->eh_work);
+ }
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
+index 7a193cc04e5b6f..304e8e79bd91a9 100644
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -91,6 +91,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req);
+ extern int scsi_error_handler(void *host);
+ extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd);
+ extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy);
++extern void scsi_rcu_eh_wakeup(struct work_struct *work);
+ extern void scsi_eh_scmd_add(struct scsi_cmnd *);
+ void scsi_eh_ready_devs(struct Scsi_Host *shost,
+ struct list_head *work_q,
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 7e2011830ba4bd..f6b286fa59f214 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -750,6 +750,9 @@ struct Scsi_Host {
+ */
+ struct device *dma_dev;
+
++ /* Used for an rcu-synchronizing eh wakeup */
++ struct work_struct eh_work;
++
+ /* Delay for runtime autosuspend */
+ int rpm_autosuspend_delay;
+
+--
+2.53.0
+
--- /dev/null
+From fc2430fcae93a99e8d62eb9923387331c6f6b78a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 14:12:35 -0400
+Subject: sctp: fix auth_hmacs array size in struct sctp_cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
+
+The auth_hmacs array in struct sctp_cookie is supposed to store a complete
+SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr
+followed by N HMAC identifiers.
+
+However, the array size was calculated using an extra 2 bytes instead of
+sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers
+are configured, the HMAC-ALGO parameter stored in the endpoint is larger
+than the auth_hmacs buffer in the cookie.
+
+As a result, sctp_association_init() copies beyond the end of auth_hmacs
+when initializing the association, corrupting the adjacent auth_chunks
+field. This can lead to an invalid HMAC identifier being accepted and later
+cause an out-of-bounds read in sctp_auth_get_hmac().
+
+Fix the array size calculation by including the full SCTP parameter header
+size.
+
+Fixes: 1f485649f529 ("[SCTP]: Implement SCTP-AUTH internals")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <dstsmallbird@foxmail.com>
+Reported-by: Zihan Xi <xizh2024@lzu.edu.cn>
+Reported-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/634a0de0d5de29532915e6d47c92a0cbc206e03f.1783707155.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index affee44bd38e31..cccc662561aac3 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -312,7 +312,8 @@ struct sctp_cookie {
+
+ __u8 auth_random[sizeof(struct sctp_paramhdr) +
+ SCTP_AUTH_RANDOM_LENGTH];
+- __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2];
++ __u8 auth_hmacs[sizeof(struct sctp_paramhdr) +
++ SCTP_AUTH_NUM_HMACS * sizeof(__u16)];
+ __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS];
+
+ /* This is a shim for my peer's INIT packet, followed by
+--
+2.53.0
+
--- /dev/null
+From 7f05b4c9d464c9baf7d83420df971518ceb3ed2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Jul 2026 16:27:36 +0530
+Subject: selftests/alsa: Fix memory leak in find_controls error path
+
+From: Malaya Kumar Rout <malayarout91@gmail.com>
+
+[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
+
+In find_controls(), card_data is allocated with malloc() but when
+snd_ctl_open_lconf() fails, the code jumps to next_card without
+freeing the allocated memory. This results in a memory leak for
+each card where snd_ctl_open_lconf() fails.
+
+Add free(card_data) before goto next_card to ensure proper cleanup
+of the allocated memory in the error path.
+
+Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
+Signed-off-by: Malaya Kumar Rout <malayarout91@gmail.com>
+Link: https://patch.msgid.link/20260704105736.94874-1-malayarout91@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/alsa/mixer-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
+index d4f845c3280456..c5ae2a026ce919 100644
+--- a/tools/testing/selftests/alsa/mixer-test.c
++++ b/tools/testing/selftests/alsa/mixer-test.c
+@@ -84,6 +84,7 @@ static void find_controls(void)
+ if (err < 0) {
+ ksft_print_msg("Failed to get hctl for card %d: %s\n",
+ card, snd_strerror(err));
++ free(card_data);
+ goto next_card;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 42a9a02906eb1a6ad5647b0c8d61c1e3af00edfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 23:19:17 +0100
+Subject: selftests: netconsole: only restore MAC when it changed on resume
+
+From: Andre Carvalho <asantostc@gmail.com>
+
+[ Upstream commit 04aeddf2dadd0eb7ad016a766dcbe9c983311f09 ]
+
+The "mac" bind mode reactivation downs the interface, restores the saved
+MAC and renames it to trigger a target resume. This assumes the recreated
+interface comes back with a different MAC, which is true under
+MACAddressPolicy=none (as on the Netdev CI) but not when MACs are
+persistent. In the persistent case netconsole resumes the target on its
+own, and the down/restore/rename flow instead drops it and fails the test.
+
+Guard the block on the MAC having actually changed so the test passes
+under both policies.
+
+Fixes: 6ecc08329bab ("selftests: netconsole: validate target resume")
+Reported-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Closes: https://lore.kernel.org/netdev/f398373e-2cb4-4649-a491-9763df94d98b@kernel.org/
+Signed-off-by: Andre Carvalho <asantostc@gmail.com>
+Tested-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260710-netcons-mac-reload-v1-1-3fb1bcc70b4a@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/drivers/net/netconsole/netcons_resume.sh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/netconsole/netcons_resume.sh b/tools/testing/selftests/drivers/net/netconsole/netcons_resume.sh
+index cb59cf436dd0a3..d9111f2102bcd1 100755
+--- a/tools/testing/selftests/drivers/net/netconsole/netcons_resume.sh
++++ b/tools/testing/selftests/drivers/net/netconsole/netcons_resume.sh
+@@ -44,7 +44,8 @@ function trigger_reactivation() {
+ # Restore MACs
+ ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" \
+ address "${SAVED_DSTMAC}"
+- if [ "${BINDMODE}" == "mac" ]; then
++ if [ "${BINDMODE}" == "mac" ] &&
++ [ "$(mac_get "${SRCIF}")" != "${SAVED_SRCMAC}" ]; then
+ ip link set dev "${SRCIF}" down
+ ip link set dev "${SRCIF}" address "${SAVED_SRCMAC}"
+ # Rename device in order to trigger target resume, as initial
+--
+2.53.0
+
gpu-host1x-fix-use-after-free-in-host1x_bo_clear_cac.patch
crypto-tegra-don-t-touch-bo-refcount-in-host1x-bo-pi.patch
xprtrdma-clear-receive-side-ownership-pointers-on-re.patch
+arm64-tegra-remove-fallback-compatible-for-gpcdma.patch
+docs-admin-guide-cgroup-v2-fix-memory.stat-doc-detai.patch
+sched_ext-annotate-ksyncs-with-__rcu-in-alloc-free_k.patch
+arm64-tegra-fix-cpu-compatible-string-to-cortex-a78a.patch
+xfrm-propagate-einprogress-from-validate_xmit_xfrm.patch
+xfrm-fix-stale-skb-prev-after-async-crypto-steals-a-.patch
+firmware-arm_ffa-respect-firmware-advertised-rx-tx-b.patch
+ib-mad-drop-unmatched-rmpp-responses-before-reassemb.patch
+mtd-virt_concat-fix-use-after-free-in-mtd_virt_conca.patch
+mtd-virt_concat-fix-use-after-free-in-mtd_virt_conca.patch-15214
+mtd-mtdswap-remove-debugfs-stats-file-on-teardown.patch
+mtd-nand-mtk-ecc-stop-on-ecc-idle-timeouts.patch
+btrfs-reject-free-space-cache-with-more-entries-than.patch
+btrfs-fix-root-leak-if-its-reloc-root-is-unexpected-.patch
+btrfs-fallback-to-transaction-csum-tree-on-a-commit-.patch
+firmware-arm_ffa-fix-null-dereference-in-ffa_partiti.patch
+sched_ext-don-t-warn-on-core-sched-forced-idle-in-pu.patch
+reset-spacemit-k3-fix-usb2-ahb-reset.patch
+xfrm-fix-sk_dst_cache-double-free-in-xfrm_user_polic.patch
+xfrm-reject-optional-iptfs-templates-in-outbound-pol.patch
+rdma-cma-fix-hardware-address-comparison-length-in-n.patch
+rdma-irdma-prevent-rereg_mr-for-non-mem-regions.patch
+rdma-irdma-remove-redundant-legacy_mode-checks.patch
+rdma-irdma-prevent-user-triggered-null-deref-on-qp-c.patch
+rdma-erdma-initialize-ret-for-empty-receive-wr-lists.patch
+rdma-mana_ib-initialize-err-for-empty-send-wr-lists.patch
+rdma-core-fix-memory-leak-in-__ib_create_cq-on-inval.patch
+rdma-hns-fix-potential-integer-overflow-in-mhop-hem-.patch
+rdma-siw-publish-qp-after-initialization.patch
+mtd-fix-double-free-and-warn_on-in-add_mtd_device-er.patch
+selftests-alsa-fix-memory-leak-in-find_controls-erro.patch
+rdma-irdma-prevent-overflows-in-memory-contiguity-ch.patch
+xfrm-clear-mode-callbacks-after-failed-mode-setup.patch
+xfrm-iptfs-propagate-skbfl_shared_frag-in-iptfs_skb_.patch
+xfrm6-clear-dst.dev-on-error-to-avoid-double-netdev_.patch
+xfrm-policy-preallocate-inexact-bins-before-xfrm_has.patch
+wifi-mac80211-allocate-backup-ieee80211_nan_sched_cf.patch
+alsa-usb-audio-fix-imbalance-per-channel-volume-of-s.patch
+wifi-cfg80211-cancel-sched-scan-results-work-on-unre.patch
+wifi-ipw2100-fix-potential-memory-leak-in-ipw2100_pc.patch
+wifi-cfg80211-fix-an-error-handling-path-in-cfg80211.patch
+wifi-mac80211_hwsim-clamp-virtio-rx-length-before-sk.patch
+wifi-mac80211-fix-unsol_bcast_probe_resp-double-free.patch
+wifi-mac80211-fix-fils_discovery-double-free-on-allo.patch
+wifi-libertas-fix-memory-leak-in-helper_firmware_cb.patch
+wifi-mac80211-defer-link-rx-stats-percpu-free-to-rcu.patch
+wifi-p54-validate-rx-frame-length-in-p54_rx_eeprom_r.patch
+wifi-cfg80211-convert-pmsr_free_wk-to-wiphy_work-to-.patch
+wifi-nl80211-free-rnr-data-on-mbssid-mismatch.patch
+wifi-cfg80211-derive-s1g-beacon-tsf-from-s1g-fields.patch
+wifi-nl80211-validate-nested-mbssid-ie-blobs.patch
+wifi-nl80211-constrain-mbssid-tx-link-id-range.patch
+wifi-cfg80211-validate-pmsr-measurement-type-data.patch
+wifi-cfg80211-validate-pmsr-ftm-preamble-range.patch
+wifi-cfg80211-reject-unsupported-pmsr-ftm-location-r.patch
+wifi-cfg80211-reject-empty-pmsr-peer-lists.patch
+wifi-mac80211-avoid-non-s1g-aid-fallback-for-s1g-ass.patch
+asoc-amd-acp-fix-linker-error-with-sdca-quirks.patch
+wifi-mac80211-free-ap_vlan-bc_buf-skbs-outside-irq-l.patch
+wifi-cfg80211-use-wiphy-work-for-socket-owner-autodi.patch
+wifi-brcmfmac-initialize-sdio-data-work-before-clean.patch
+wifi-cfg80211-bound-element-id-read-when-checking-no.patch
+firmware-arm_ffa-fix-out-of-bound-writes-in-ffa_setu.patch
+firmware-arm_ffa-fix-endpoint-memory-access-descript.patch
+asoc-meson-aiu-fifo-spdif-soft-reset-the-s-pdif-data.patch
+asoc-amd-ps-disable-msi-on-resume-in-acp-pci-driver.patch
+asoc-amd-ps-fix-wrong-acp-version-string-in-pci_requ.patch
+asoc-amd-ps-replace-bitwise-or-with-logical-or-in-ir.patch
+erofs-relax-sanity-check-for-tail-pclusters-due-to-z.patch
+asoc-cs42l43-correct-report-for-forced-microphone-ja.patch
+sched_ext-enable-tick-for-finite-slices-on-nohz_full.patch
+asoc-tas2562-fix-deprecated-shut-down-gpio-always-cl.patch
+firmware-arm_scmi-rate-limit-queue-full-warnings-in-.patch
+bpf-fix-uaf-in-sock-clone-early-bailouts.patch
+cpufreq-make-cpufreq_update_pressure-fall-back-to-cp.patch
+sched_ext-record-an-error-on-errno-only-sub-enable-f.patch
+ppp-defer-channel-free-to-an-rcu-grace-period-to-fix.patch
+ipv4-fib-free-fib_alias-with-kfree_rcu-on-insert-err.patch
+net-iucv-take-a-reference-on-the-socket-found-in-afi.patch
+udmabuf-ensure-to-perform-cache-synchronisation-in-b.patch
+scsi-core-wake-eh-reliably-when-using-scsi_schedule_.patch
+ata-sata_dwc_460ex-enable-sata-interrupts-only-after.patch
+ata-sata_dwc_460ex-use-platform_get_irq.patch
+ata-sata_dwc_460ex-fix-clear_interrupt_bit-clearing-.patch
+ata-sata_dwc_460ex-fix-infinite-loop-in-ncq-tag-comp.patch
+accel-ivpu-fix-wrong-register-read-in-lnl-failure-di.patch
+alsa-usb-audio-skip-dsd-quirk-for-musical-fidelity-m.patch
+bluetooth-qca-fix-nvm-tag-length-underflow-in-tlv-pa.patch
+bluetooth-mgmt-revalidate-load_conn_param-queued-upd.patch
+bluetooth-hci_sync-extend-conn_hash-lookup-critical-.patch
+bluetooth-mgmt-fix-locking-in-unpair_device-disconne.patch
+bluetooth-mgmt-hold-reference-for-hci_conn-in-mgmt_p.patch
+bluetooth-hci_sync-hold-hdev-lock-for-hci_conn_param.patch
+bluetooth-hci_qca-clear-memdump-state-on-invalid-dum.patch
+bluetooth-mgmt-translate-hci-reason-in-device-discon.patch
+smb-client-handle-overlapping-allocated-ranges-in-fa.patch
+riscv-gate-function_alignment_4b-on-dynamic_ftrace.patch
+drm-i915-gt-use-correct-selftest-config-symbol.patch
+can-raw-add-locking-for-raw-flags-bitfield.patch
+spi-cadence-quadspi-fix-indirect-write-timeout-when-.patch
+powerpc-85xx-add-fsl-ifc-to-common-device-ids.patch
+powerpc-time-prepare-to-stop-elapsing-in-dynticks-id.patch
+powerpc-vtime-initialize-starttime-at-boot-for-nativ.patch
+bpf-sockmap-reject-unhashed-udp-sockets-on-sockmap-u.patch
+drm-panthor-check-debugfs-gem-lock-initialization.patch
+s390-checksum-fix-csum_partial-without-vector-facili.patch
+riscv-hwprobe-avoid-uninitialized-read-in-hwprobe_ge.patch
+can-j1939-fix-lockless-local-destination-check.patch
+drm-xe-vf-fix-vf-ccs-attach-detach-race-with-in-flig.patch
+drm-xe-wopcm-fix-wopcm-size-for-lnl.patch
+drm-xe-assign-queue-name-in-time-for-drm_sched_init.patch
+drm-xe-guc-keep-scheduler-timeline-name-alive.patch
+drm-xe-guc-hold-device-ref-until-queue-teardown-comp.patch
+ksmbd-pin-conn-during-async-oplock-break-notificatio.patch
+ksmbd-validate-compound-request-size-before-reading-.patch
+drm-i915-wm-clear-the-plane-ddb_y-entries-on-plane-d.patch
+drm-i915-selftests-fix-gt-pm-sort-comparators.patch
+accel-amdxdna-fix-use-after-free-of-mm_struct-in-job.patch
+tcp-fix-time_wait-socket-reference-leak-on-psp-polic.patch
+dpll-fix-null-pointer-dereference-in-dpll_msg_add_pi.patch
+net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch
+sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch
+bnxt_en-handle-partially-initialized-auxiliary-devic.patch
+selftests-netconsole-only-restore-mac-when-it-change.patch
+mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch
--- /dev/null
+From cda1d427034c9600382bcf930e8f1a68094565af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:32:56 +0800
+Subject: smb/client: handle overlapping allocated ranges in fallocate
+
+From: Huiwen He <hehuiwen@kylinos.cn>
+
+[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
+
+smb3_simple_fallocate_range() can skip holes when an allocated range
+returned by the server starts before the current fallocate offset. The
+skipped hole is not zero-filled, but fallocate still returns success. A
+later write to that hole may therefore fail with ENOSPC.
+
+The function queries allocated ranges so that it can preserve existing
+contents and write zeroes only into holes. However, the server may return
+a range that starts before the current fallocate offset.
+
+For example, assume the fallocate request is [100, 400) and the only
+allocated range returned by the server is [0, 200):
+
+ Request: [100, 400)
+ Server range: [ 0, 200) allocated
+
+ Correct:
+ [100, 200) allocated data, skip
+ [200, 400) hole, zero-fill
+
+ Current:
+ [100, 300) skipped
+ [300, 400) zero-filled afterwards
+
+The current code adds the full server range length, 200, to the current
+offset 100 and moves to 300. As a result, the hole in [200, 300) is
+skipped without being zero-filled.
+
+Fix this by advancing only over the part of the allocated range that
+overlaps the current fallocate offset. Ignore ranges that end before the
+current offset and reject ranges whose end offset overflows.
+
+This also prevents a malformed range length from causing an out-of-bounds
+zero-buffer read.
+
+Fixes: 966a3cb7c7db ("cifs: improve fallocate emulation")
+Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2ops.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 02c2f83353e27a..6f843c8b83f3a8 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -3581,6 +3581,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
+ u32 out_data_len;
+ char *buf = NULL;
++ u64 range_start, range_len, range_end;
+ loff_t l;
+ int rc;
+
+@@ -3617,13 +3618,21 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ goto out;
+ }
+
+- if (off < le64_to_cpu(tmp_data->file_offset)) {
++ range_start = le64_to_cpu(tmp_data->file_offset);
++ range_len = le64_to_cpu(tmp_data->length);
++ if (check_add_overflow(range_start, range_len, &range_end) ||
++ range_end > S64_MAX) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < range_start) {
+ /*
+ * We are at a hole. Write until the end of the region
+ * or until the next allocated data,
+ * whichever comes next.
+ */
+- l = le64_to_cpu(tmp_data->file_offset) - off;
++ l = range_start - off;
+ if (len < l)
+ l = len;
+ rc = smb3_simple_fallocate_write_range(xid, tcon,
+@@ -3640,11 +3649,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,
+ * until the end of the data or the end of the region
+ * we are supposed to fallocate, whichever comes first.
+ */
+- l = le64_to_cpu(tmp_data->length);
+- if (len < l)
+- l = len;
+- off += l;
+- len -= l;
++ if (off < range_end) {
++ l = range_end - off;
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++ }
+
+ tmp_data = &tmp_data[1];
+ out_data_len -= sizeof(struct file_allocated_range_buffer);
+--
+2.53.0
+
--- /dev/null
+From 4e88e3535cd1bc3972789d93484f77fee45febf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2026 10:21:48 +0530
+Subject: spi: cadence-quadspi: Fix indirect write timeout when DMA read mode
+ is enabled
+
+From: Srikanth Boyapally <srikanth.boyapally@amd.com>
+
+[ Upstream commit e919ca35a6e84b5adf085da9ffa1544c01d4ce1e ]
+
+When use_dma_read is enabled, the IRQ handler unconditionally overwrites
+irq_status with the return value of get_dma_status(). For write operations,
+DMA status returns 0 since no DMA read is in progress, causing irq_status
+to become 0. The subsequent completion signal is never triggered and the
+write operation times out with -ETIMEDOUT:
+
+ cadence-qspi f1010000.spi: Indirect write timeout
+ spi-nor spi0.1: operation failed with -110
+
+Fix this by separating the DMA completion path from the write interrupt
+path. If get_dma_status() indicates DMA read completion, signal completion
+and return immediately. Otherwise, preserve the original irq_status so that
+write completion interrupts are correctly recognized and signalled.
+
+Fixes: aac733a96636 ("spi: cadence-qspi: Fix style and improve readability")
+Signed-off-by: Srikanth Boyapally <srikanth.boyapally@amd.com>
+Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Link: https://patch.msgid.link/20260708045148.2993313-1-srikanth.boyapally@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-cadence-quadspi.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index 057381e56a7fd5..38aa83375c1896 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -382,12 +382,16 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
+ /* Clear interrupt */
+ writel(irq_status, cqspi->iobase + CQSPI_REG_IRQSTATUS);
+
+- if (cqspi->use_dma_read && ddata && ddata->get_dma_status)
+- irq_status = ddata->get_dma_status(cqspi);
+- else if (cqspi->slow_sram)
++ if (cqspi->use_dma_read && ddata && ddata->get_dma_status) {
++ if (ddata->get_dma_status(cqspi)) {
++ complete(&cqspi->transfer_complete);
++ return IRQ_HANDLED;
++ }
++ } else if (cqspi->slow_sram) {
+ irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR;
+- else
++ } else {
+ irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
++ }
+
+ if (irq_status)
+ complete(&cqspi->transfer_complete);
+--
+2.53.0
+
--- /dev/null
+From ce7a35f7f03c998b78383b61f6c9dd9fa9fcf3cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2026 18:13:17 +0000
+Subject: tcp: fix TIME_WAIT socket reference leak on PSP policy failure
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2c1931a81122c3cdc4c89448fe0442c69e21c0d5 ]
+
+Release the TIME_WAIT socket reference and jump to discard_it
+upon PSP policy failure in both IPv4 and IPv6 receive paths.
+This prevents a memory leak of tcp_tw_bucket structures.
+
+Fixes: 659a2899a57d ("tcp: add datapath logic for PSP with inline key exchange")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
+Link: https://patch.msgid.link/20260710181317.4060230-1-edumazet@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_ipv4.c | 6 ++++--
+ net/ipv6/tcp_ipv6.c | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index bfdabad01fa765..d5cd238358ef04 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -2319,8 +2319,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
+ }
+
+ drop_reason = psp_twsk_rx_policy_check(inet_twsk(sk), skb);
+- if (drop_reason)
+- break;
++ if (drop_reason) {
++ inet_twsk_put(inet_twsk(sk));
++ goto discard_it;
++ }
+ }
+ /* to ACK */
+ fallthrough;
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 36d75fb50a70b7..71cca3c74423f5 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1962,8 +1962,10 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+ }
+
+ drop_reason = psp_twsk_rx_policy_check(inet_twsk(sk), skb);
+- if (drop_reason)
+- break;
++ if (drop_reason) {
++ inet_twsk_put(inet_twsk(sk));
++ goto discard_it;
++ }
+ }
+ /* to ACK */
+ fallthrough;
+--
+2.53.0
+
--- /dev/null
+From bc11f9a8c541293f50c15e29197ce62236b64e3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 12:57:25 +0200
+Subject: udmabuf: Ensure to perform cache synchronisation in
+ begin_cpu_udmabuf()
+
+From: Robert Mader <robert.mader@collabora.com>
+
+[ Upstream commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 ]
+
+The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to
+fix cacheline EEXIST warning") says:
+
+> The CPU sync at map/unmap time is also redundant for udmabuf:
+> begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit
+> cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU
+> access is requested through the dma-buf interface.
+
+This, however, does not apply to the first time begin_cpu_udmabuf() is
+called on an udmabuf, in which case the implementation previously relied on
+get_sg_table() to perform the cache synchronisation.
+
+Ensure to call dma_sync_sgtable_for_cpu() in that case as well.
+
+Fixes: 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning")
+Signed-off-by: Robert Mader <robert.mader@collabora.com>
+Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
+Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
+Link: https://patch.msgid.link/20260627105725.9083-1-robert.mader@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma-buf/udmabuf.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index 2f94be1df525aa..2e7b5d4d11f429 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -247,21 +247,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
+ {
+ struct udmabuf *ubuf = buf->priv;
+ struct device *dev = ubuf->device->this_device;
+- int ret = 0;
+
+ if (!ubuf->sg) {
+ ubuf->sg = get_sg_table(dev, buf, direction);
+ if (IS_ERR(ubuf->sg)) {
++ int ret;
++
+ ret = PTR_ERR(ubuf->sg);
+ ubuf->sg = NULL;
++ return ret;
+ } else {
+ ubuf->sg_dir = direction;
+ }
+- } else {
+- dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
+ }
+
+- return ret;
++ dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
++ return 0;
+ }
+
+ static int end_cpu_udmabuf(struct dma_buf *buf,
+--
+2.53.0
+
--- /dev/null
+From 4d2ad3756413fc9889aa75b6558a10a509a9cfa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2026 14:44:01 +0800
+Subject: wifi: brcmfmac: initialize SDIO data work before cleanup
+
+From: Runyu Xiao <runyu.xiao@seu.edu.cn>
+
+[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
+
+brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before
+allocating the ordered workqueue. If that allocation fails, the function
+jumps to fail and calls brcmf_sdio_remove().
+
+brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the
+work item before the first failure path that can reach brcmf_sdio_remove(),
+so the cleanup path always observes a valid work object.
+
+This issue was found by our static analysis tool and then confirmed by
+manual review of the probe error path and the remove-time work drain. The
+problem pattern is an early setup failure that reaches a cleanup helper
+which cancels an embedded work item before its initializer has run.
+
+A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in
+brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The
+resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports
+the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in
+the stack.
+
+Fixes: 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
+Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260619064401.1048976-1-runyu.xiao@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 8fb595733b9c36..b725c64e5b5c63 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4465,6 +4465,7 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ bus->sdiodev = sdiodev;
+ sdiodev->bus = bus;
+ skb_queue_head_init(&bus->glom);
++ INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->txbound = BRCMF_TXBOUND;
+ bus->rxbound = BRCMF_RXBOUND;
+ bus->txminmax = BRCMF_TXMINMAX;
+@@ -4479,7 +4480,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+ goto fail;
+ }
+ brcmf_sdiod_freezer_count(sdiodev);
+- INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
+ bus->brcmf_wq = wq;
+
+ /* attempt to attach to the dongle */
+--
+2.53.0
+
--- /dev/null
+From 3e1a163b3b2ea25063e7cd1bdb1398fe5487ef07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2026 18:48:28 +0900
+Subject: wifi: cfg80211: bound element ID read when checking non-inheritance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: HE WEI (ギカク) <skyexpoc@gmail.com>
+
+[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
+
+cfg80211_is_element_inherited() reads the first data octet of the
+candidate element (id = elem->data[0]) to look it up in an extension
+non-inheritance list. It does so after testing elem->id, but without
+verifying that the element actually has a data octet. A zero-length
+extension element (WLAN_EID_EXTENSION with length 0) therefore makes it
+read one octet past the end of the element.
+
+_ieee802_11_parse_elems_full() runs this check for every element of a
+frame once a non-inheritance context exists -- e.g. while parsing a
+per-STA profile of a Multi-Link element in a (re)association response,
+or a non-transmitted BSS profile -- so a crafted frame from an AP can
+trigger a one-octet slab-out-of-bounds read during element parsing:
+
+ BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
+ Read of size 1 ... in net/wireless/scan.c
+
+Return early (treat the element as inherited) when an extension element
+carries no data, mirroring the existing handling of empty ID lists.
+
+The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
+
+Fixes: f7dacfb11475 ("cfg80211: support non-inheritance element")
+Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
+Link: https://patch.msgid.link/20260707094828.16465-1-skyexpoc@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 4b7d4c576763ba..8ea6946eb0a353 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -205,7 +205,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+- if (!ext_id_len)
++ if (!ext_id_len || !elem->datalen)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+--
+2.53.0
+
--- /dev/null
+From 4352bc04c076fe4583894ec1b8fb300eecada557 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 00:25:42 +0800
+Subject: wifi: cfg80211: cancel sched scan results work on unregister
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
+
+cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a
+driver result notification while a scheduled scan request is present. The
+work callback recovers the containing cfg80211_registered_device and then
+locks the wiphy and walks the scheduled-scan request list.
+
+wiphy_unregister() already makes the wiphy unreachable and drains rdev work
+items before cfg80211_dev_free() can release the object, but it does not
+drain sched_scan_res_wk. A queued or running result work item can therefore
+cross the unregister/free boundary and access freed rdev state.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+scheduled-scan result path: unregister/free path:
+1. cfg80211_sched_scan_results() 1. interface teardown stops and
+ queues rdev->sched_scan_res_wk. removes the scheduled scan request.
+2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
+ item and recovers rdev. rdev work items.
+3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
+ and walks rdev state. frees rdev.
+
+Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev
+work items. cancel_work_sync() removes a pending result notification and
+waits for an already running callback, so cfg80211_dev_free() cannot free
+rdev while this work item is still active.
+
+Validation reproduced this kernel report:
+BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
+Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
+Read of size 8
+Call trace:
+ dump_stack_lvl+0x66/0xa0
+ print_report+0xce/0x630
+ cfg80211_sched_scan_results_wk+0x4a6/0x530
+ srso_alias_return_thunk+0x5/0xfbef5
+ __virt_addr_valid+0x224/0x430
+ kasan_report+0xac/0xe0
+ lockdep_hardirqs_on_prepare+0xea/0x1a0
+ process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
+ lock_is_held_type+0x8f/0x100
+ worker_thread+0x5ad/0xfd0
+ __kthread_parkme+0xc6/0x200
+ kthread+0x31e/0x410
+ trace_hardirqs_on+0x1a/0x170
+ ret_from_fork+0x576/0x810
+ __switch_to+0x57e/0xe20
+ __switch_to_asm+0x33/0x70
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260619162542.3878296-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 6783e0672dcb71..2743a8a50fe3e4 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1288,6 +1288,7 @@ void wiphy_unregister(struct wiphy *wiphy)
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->sched_scan_res_wk);
+ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+--
+2.53.0
+
--- /dev/null
+From 0d2dbe0f63473ca3e83c831927711aa13f3b0e23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 13:55:23 +0530
+Subject: wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock
+
+From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+
+[ Upstream commit 2b0eab425e1f658d8fe1df7590e3b9af5959505e ]
+
+When a netlink socket that owns a PMSR session is closed,
+cfg80211_release_pmsr() clears the request's nl_portid and queues
+pmsr_free_wk to call cfg80211_pmsr_process_abort() asynchronously.
+
+If the interface tears down concurrently, cfg80211_pmsr_wdev_down()
+is called under wiphy_lock and calls cancel_work_sync(&pmsr_free_wk)
+to wait for any running work. The work function acquires wiphy_lock
+via guard(wiphy) before calling process_abort.
+
+This is a deadlock: wdev_down holds wiphy_lock and blocks inside
+cancel_work_sync(); pmsr_free_wk blocks trying to acquire that same
+wiphy_lock. Neither thread can proceed.
+
+The same deadlock is reachable from cfg80211_leave_locked(), which
+calls cfg80211_pmsr_wdev_down() for all interface types under
+wiphy_lock.
+
+Fix this by converting pmsr_free_wk from a plain work_struct to a
+wiphy_work. The wiphy_work dispatcher holds wiphy_lock when running
+work items, so the explicit guard(wiphy) in the work function is no
+longer needed. wiphy_work_cancel() can be called safely while holding
+wiphy_lock - since wiphy_lock prevents the work from running
+concurrently, wiphy_work_cancel() never blocks, eliminating the
+deadlock.
+
+Remove the cancel_work_sync() for pmsr_free_wk from the
+NETDEV_GOING_DOWN handler. cfg80211_leave(), called unconditionally
+just before it, already cancels any pending work under wiphy_lock
+via wiphy_work_cancel() inside cfg80211_pmsr_wdev_down().
+
+Fixes: 6dccbc9f3e1d ("wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down")
+Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260703082523.2629324-1-peddolla.reddy@oss.qualcomm.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 2 +-
+ net/wireless/core.c | 3 +--
+ net/wireless/core.h | 2 +-
+ net/wireless/pmsr.c | 8 +++-----
+ 4 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 9d3639ff9c28e7..e7441414909cce 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -7027,7 +7027,7 @@ struct wireless_dev {
+
+ struct list_head pmsr_list;
+ spinlock_t pmsr_lock;
+- struct work_struct pmsr_free_wk;
++ struct wiphy_work pmsr_free_wk;
+
+ unsigned long unprot_beacon_reported;
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 2743a8a50fe3e4..6dd24115177112 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1561,7 +1561,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
+ INIT_LIST_HEAD(&wdev->mgmt_registrations);
+ INIT_LIST_HEAD(&wdev->pmsr_list);
+ spin_lock_init(&wdev->pmsr_lock);
+- INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
++ wiphy_work_init(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
+
+ #ifdef CONFIG_CFG80211_WEXT
+ wdev->wext.default_key = -1;
+@@ -1695,7 +1695,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ cfg80211_remove_links(wdev);
+ /* since we just did cfg80211_leave() nothing to do there */
+ cancel_work_sync(&wdev->disconnect_wk);
+- cancel_work_sync(&wdev->pmsr_free_wk);
+ break;
+ case NETDEV_DOWN:
+ wiphy_lock(&rdev->wiphy);
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index ae2d56d3ad9083..5ad38519d8a64b 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -583,7 +583,7 @@ cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len,
+
+ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
+ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
+-void cfg80211_pmsr_free_wk(struct work_struct *work);
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work);
+
+ void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
+ void cfg80211_remove_links(struct wireless_dev *wdev);
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 0ca93fd7d46f8d..1ee7a9e2cdef21 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -645,13 +645,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
+ }
+ }
+
+-void cfg80211_pmsr_free_wk(struct work_struct *work)
++void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work)
+ {
+ struct wireless_dev *wdev = container_of(work, struct wireless_dev,
+ pmsr_free_wk);
+
+- guard(wiphy)(wdev->wiphy);
+-
+ cfg80211_pmsr_process_abort(wdev);
+ }
+
+@@ -667,7 +665,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+
+- cancel_work_sync(&wdev->pmsr_free_wk);
++ wiphy_work_cancel(wdev->wiphy, &wdev->pmsr_free_wk);
+ if (found)
+ cfg80211_pmsr_process_abort(wdev);
+
+@@ -682,7 +680,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
+ list_for_each_entry(req, &wdev->pmsr_list, list) {
+ if (req->nl_portid == portid) {
+ req->nl_portid = 0;
+- schedule_work(&wdev->pmsr_free_wk);
++ wiphy_work_queue(wdev->wiphy, &wdev->pmsr_free_wk);
+ }
+ }
+ spin_unlock_bh(&wdev->pmsr_lock);
+--
+2.53.0
+
--- /dev/null
+From 779f4bc43ff8ed8edb9417c90d0d728f71b0e6ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 00:19:46 +0800
+Subject: wifi: cfg80211: derive S1G beacon TSF from S1G fields
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 4e5a4641e7b4763656336b7891d01359aaf363cd ]
+
+cfg80211_inform_bss_frame_data() parses S1G beacons with the extension
+frame layout, but still reads the TSF from the regular probe response
+layout after the S1G branch. For S1G beacons that reads bytes at the
+regular management-frame timestamp offset instead of the S1G timestamp.
+
+Use the 32-bit S1G beacon timestamp and the S1G Beacon Compatibility
+element's TSF completion field when informing an S1G BSS. Keep the
+regular management-frame timestamp read in the non-S1G branch.
+
+Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Tested-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Reviewed-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Link: https://patch.msgid.link/20260611161943.91069-6-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 654f3300912dab..4b7d4c576763ba 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3312,14 +3312,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+ bssid = ext->u.s1g_beacon.sa;
+ capability = le16_to_cpu(compat->compat_info);
+ beacon_interval = le16_to_cpu(compat->beacon_int);
++ tsf = le32_to_cpu(ext->u.s1g_beacon.timestamp);
++ tsf |= (u64)le32_to_cpu(compat->tsf_completion) << 32;
+ } else {
+ bssid = mgmt->bssid;
+ beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
+ capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
++ tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+ }
+
+- tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
+-
+ if (ieee80211_is_probe_resp(mgmt->frame_control))
+ ftype = CFG80211_BSS_FTYPE_PRESP;
+ else if (ext)
+--
+2.53.0
+
--- /dev/null
+From f75a0436c5451eda35070d81ad2ced9bb498c912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:48:56 +0200
+Subject: wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit c6659f66d4ee4841aafae5659d2ef5e4c5c63cb6 ]
+
+If the test against IEEE80211_MAX_SSID_LEN fails, then 'creq' leaks.
+Use the existing error handling path to fix it.
+
+Fixes: 2a5193119269 ("cfg80211/nl80211: scanning (and mac80211 update to use it)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://patch.msgid.link/a1be7eea4da0da18f90589af252bb76a18a61978.1781984889.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index d9f2a77e127ce8..654f3300912dab 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3613,8 +3613,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+ /* translate "Scan for SSID" request */
+ if (wreq) {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+- if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
+- return -EINVAL;
++ if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
++ err = -EINVAL;
++ goto out;
++ }
+ memcpy(creq->req.ssids[0].ssid, wreq->essid,
+ wreq->essid_len);
+ creq->req.ssids[0].ssid_len = wreq->essid_len;
+--
+2.53.0
+
--- /dev/null
+From ada7e6abb0ebaff356c9e567b7b82f4b45cafd9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:18 +0800
+Subject: wifi: cfg80211: reject empty PMSR peer lists
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 57c05ce14fea03df01288fe1250f49197e161710 ]
+
+A PMSR request with an empty peers array is not a useful request and
+weakens the cfg80211-to-driver contract by allowing start_pmsr() with
+no target peer.
+
+Reject empty peer lists before allocating the request object or calling
+into the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133717.93783-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 9246640d2eedfd..feced0f762e01d 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -332,6 +332,11 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
+ }
+ }
+
++ if (!count) {
++ NL_SET_ERR_MSG_ATTR(info->extack, peers, "No peers specified");
++ return -EINVAL;
++ }
++
+ req = kzalloc_flex(*req, peers, count);
+ if (!req)
+ return -ENOMEM;
+--
+2.53.0
+
--- /dev/null
+From 870c78b7746f29ae4d52963a277bbaac3b174dcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:11 +0800
+Subject: wifi: cfg80211: reject unsupported PMSR FTM location requests
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
+
+PMSR FTM location request flags are syntactically valid, but they must
+be rejected when the device capability does not advertise support for
+them.
+
+Return an error immediately after rejecting unsupported LCI or civic
+location request bits so the request cannot reach the driver.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133710.93544-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 4b10ce0486f4a6..9246640d2eedfd 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -109,6 +109,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
+ "FTM: LCI request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.request_civicloc =
+@@ -117,6 +118,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
+ "FTM: civic location request not supported");
++ return -EOPNOTSUPP;
+ }
+
+ out->ftm.trigger_based =
+--
+2.53.0
+
--- /dev/null
+From 71458167bd932aa56c84d82966267da3bb745b1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 23:24:18 +0800
+Subject: wifi: cfg80211: use wiphy work for socket owner autodisconnect
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 0c2ed186bbe14304415476d6707b747dddcd8583 ]
+
+nl80211_netlink_notify() walks the cfg80211 wireless device list when a
+NETLINK_GENERIC socket is released. If the socket owns a connection, the
+notifier queues the embedded wdev->disconnect_wk work item.
+
+That work is a plain work_struct today. NETDEV_GOING_DOWN cancels it, but a
+NETLINK_URELEASE notifier that already observed conn_owner_nlportid can
+queue it after that cancel returns. _cfg80211_unregister_wdev() then
+removes the wdev from the list and waits for RCU readers, but
+synchronize_net() does not drain work queued by such a reader.
+
+Make the autodisconnect work a wiphy_work instead. The callback already
+needs the wiphy mutex, and wiphy_work runs under that mutex. This lets
+teardown cancel pending autodisconnect work while holding the mutex,
+without a cancel_work_sync() vs. worker locking concern.
+
+Also cancel the wiphy work after list_del_rcu() and synchronize_net(). Any
+NETLINK_URELEASE notifier that had already reached the wdev list has then
+either queued the work and it is removed, or can no longer find the wdev.
+
+Fixes: bd2522b16884 ("cfg80211: NL80211_ATTR_SOCKET_OWNER support for CMD_CONNECT")
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706152418.779226-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg80211.h | 2 +-
+ net/wireless/core.c | 10 ++++++----
+ net/wireless/core.h | 2 +-
+ net/wireless/nl80211.c | 3 ++-
+ net/wireless/sme.c | 6 ++----
+ 5 files changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index e7441414909cce..909fb76751c508 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6990,7 +6990,7 @@ struct wireless_dev {
+ enum ieee80211_bss_type conn_bss_type;
+ u32 conn_owner_nlportid;
+
+- struct work_struct disconnect_wk;
++ struct wiphy_work disconnect_wk;
+ u8 disconnect_bssid[ETH_ALEN];
+
+ struct list_head event_list;
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 6dd24115177112..7f6a0418d83018 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1378,6 +1378,7 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
+ list_del_rcu(&wdev->list);
+ synchronize_net();
+ rdev->devlist_generation++;
++ wiphy_work_cancel(wdev->wiphy, &wdev->disconnect_wk);
+
+ cfg80211_mlme_purge_registrations(wdev);
+
+@@ -1585,7 +1586,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
+ wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
+ wdev->netdev->priv_flags |= IFF_DONT_BRIDGE;
+
+- INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
++ wiphy_work_init(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
+ }
+
+ void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
+@@ -1691,10 +1692,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+ break;
+ case NETDEV_GOING_DOWN:
+ cfg80211_leave(rdev, wdev, -1);
+- scoped_guard(wiphy, &rdev->wiphy)
++ scoped_guard(wiphy, &rdev->wiphy) {
+ cfg80211_remove_links(wdev);
+- /* since we just did cfg80211_leave() nothing to do there */
+- cancel_work_sync(&wdev->disconnect_wk);
++ /* since we just did cfg80211_leave() nothing to do there */
++ wiphy_work_cancel(wdev->wiphy, &wdev->disconnect_wk);
++ }
+ break;
+ case NETDEV_DOWN:
+ wiphy_lock(&rdev->wiphy);
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index 5ad38519d8a64b..8d40f1e6538bca 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -428,7 +428,7 @@ void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *peer_addr,
+ const u8 *td_bitmap, u8 td_bitmap_len);
+ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev);
+-void cfg80211_autodisconnect_wk(struct work_struct *work);
++void cfg80211_autodisconnect_wk(struct wiphy *wiphy, struct wiphy_work *work);
+
+ /* SME implementation */
+ void cfg80211_conn_work(struct work_struct *work);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 3476681ecd7aa8..68f9219796e199 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -22557,7 +22557,8 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
+ wdev->nl_owner_dead = true;
+ schedule_work(&rdev->destroy_work);
+ } else if (wdev->conn_owner_nlportid == notify->portid) {
+- schedule_work(&wdev->disconnect_wk);
++ wiphy_work_queue(wdev->wiphy,
++ &wdev->disconnect_wk);
+ }
+
+ cfg80211_release_pmsr(wdev, notify->portid);
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index 86e2ccaa678ce5..1ddaadbed74c82 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -1577,13 +1577,11 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+ * Used to clean up after the connection / connection attempt owner socket
+ * disconnects
+ */
+-void cfg80211_autodisconnect_wk(struct work_struct *work)
++void cfg80211_autodisconnect_wk(struct wiphy *wiphy, struct wiphy_work *work)
+ {
+ struct wireless_dev *wdev =
+ container_of(work, struct wireless_dev, disconnect_wk);
+- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+-
+- guard(wiphy)(wdev->wiphy);
++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+ if (wdev->conn_owner_nlportid) {
+ switch (wdev->iftype) {
+--
+2.53.0
+
--- /dev/null
+From cb2413b1088da94ee10aa5fca3657418d3ab95d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:37:04 +0800
+Subject: wifi: cfg80211: validate PMSR FTM preamble range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
+
+PMSR FTM request parsing accepts preamble values outside the
+enumerated nl80211 preamble range.
+
+Reject out-of-range values before using them in the parser capability
+bit test using the policy.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133703.93274-2-enderaoelyther@gmail.com
+[drop unnecessary check]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 3024fa8dd78021..3476681ecd7aa8 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -461,7 +461,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
+ static const struct nla_policy
+ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
+ [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
+- [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
++ [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
++ NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
++ NL80211_PREAMBLE_HE),
+ [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
+ NLA_POLICY_MAX(NLA_U8, 15),
+ [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
+--
+2.53.0
+
--- /dev/null
+From 6c04fd4c66a5b04450c49b74a79e8a8904b36395 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:36:57 +0800
+Subject: wifi: cfg80211: validate PMSR measurement type data
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
+
+PMSR request parsing accepts missing or duplicated measurement type
+entries in NL80211_PMSR_REQ_ATTR_DATA.
+
+Track whether one measurement type was already provided, reject a
+second one immediately, and return an error if the request data block
+contains no measurement type at all.
+
+Fixes: 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612133656.92900-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/pmsr.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
+index 1ee7a9e2cdef21..4b10ce0486f4a6 100644
+--- a/net/wireless/pmsr.c
++++ b/net/wireless/pmsr.c
+@@ -214,6 +214,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ {
+ struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
+ struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
++ bool have_measurement_type = false;
+ struct nlattr *treq;
+ int err, rem;
+
+@@ -267,6 +268,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ }
+
+ nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
++ if (have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack, treq,
++ "multiple measurement types in request data");
++ return -EINVAL;
++ }
++
++ have_measurement_type = true;
++
+ switch (nla_type(treq)) {
+ case NL80211_PMSR_TYPE_FTM:
+ err = pmsr_parse_ftm(rdev, treq, out, info);
+@@ -276,10 +285,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
+ "unsupported measurement type");
+ err = -EINVAL;
+ }
++ if (err)
++ return err;
+ }
+
+- if (err)
+- return err;
++ if (!have_measurement_type) {
++ NL_SET_ERR_MSG_ATTR(info->extack,
++ req[NL80211_PMSR_REQ_ATTR_DATA],
++ "missing measurement type in request data");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From 41cb149410a0c1b25c0b7753b458e190354b5a93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 12:22:39 +0530
+Subject: wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
+
+The memory allocated in the ipw2100_alloc_device() function is not freed
+in some of the error paths in ipw2100_pci_init_one(). Fix that by
+converting the direct return into a goto to the error path return.
+
+The error path when pci_enable_device() fails cannot jump to fail, since
+at this point priv is not set, so perform error handling inline.
+
+Fixes: 2c86c275015c ("Add ipw2100 wireless driver.")
+Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+Link: https://patch.msgid.link/20260620065242.93798-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+index c11428485dccf5..2b8a23865bfb29 100644
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6157,6 +6157,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_enable_device.\n");
++ free_libipw(dev, 0);
++ pci_iounmap(pci_dev, ioaddr);
+ return err;
+ }
+
+@@ -6169,16 +6171,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_set_dma_mask.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ err = pci_request_regions(pci_dev, DRV_NAME);
+ if (err) {
+ printk(KERN_WARNING DRV_NAME
+ "Error calling pci_request_regions.\n");
+- pci_disable_device(pci_dev);
+- return err;
++ goto fail;
+ }
+
+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+--
+2.53.0
+
--- /dev/null
+From ffe4d22c52c80de99b93c790ee690cd74b21bbcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jun 2026 16:53:43 +0800
+Subject: wifi: libertas: fix memory leak in helper_firmware_cb()
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
+
+helper_firmware_cb() neglects to free the single-stage firmware image
+after a successful async load, leading to a memory leak in the USB
+firmware-download path.
+
+Fix this memory leak by calling release_firmware() immediately after
+lbs_fw_loaded() returns.
+
+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
+the current wireless tree.
+
+An x86_64 allyesconfig build showed no new warnings. As we do not have
+compatible Libertas USB hardware for exercising this firmware-download
+path, no runtime testing was able to be performed.
+
+Fixes: 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Link: https://patch.msgid.link/20260624085343.575508-1-dawei.feng@seu.edu.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/firmware.c b/drivers/net/wireless/marvell/libertas/firmware.c
+index f124110944b7e9..9bf7d4c207b9ed 100644
+--- a/drivers/net/wireless/marvell/libertas/firmware.c
++++ b/drivers/net/wireless/marvell/libertas/firmware.c
+@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
+ } else {
+ /* No main firmware needed for this helper --> success! */
+ lbs_fw_loaded(priv, 0, firmware, NULL);
++ release_firmware(firmware);
+ }
+ }
+
+--
+2.53.0
+
--- /dev/null
+From e216efebf4bebb3f0ff0452f0d7aeeba8c18dba7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 15:00:54 +0200
+Subject: wifi: mac80211: allocate backup ieee80211_nan_sched_cfg off stack
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 44494b0d1d16e76ae805817579eacc801b10ed37 ]
+
+The ieee80211_nan_sched_cfg structure is too large to keep on the
+per thread stack:
+
+net/mac80211/nan.c:251:5: error: stack frame size (1560) exceeds limit (1536) in 'ieee80211_nan_set_local_sched' [-Werror,-Wframe-larger-than]
+ 251 | int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
+
+Allocate this dynamically using kmalloc_obj() to reduce the stack
+usage of this function to a manageable 344 bytes for the same
+configuration.
+
+Fixes: 589c06e8fdee ("wifi: mac80211: add NAN local schedule support")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://patch.msgid.link/20260611130100.3387714-1-arnd@kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/nan.c | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/net/mac80211/nan.c b/net/mac80211/nan.c
+index 4e262b624521d2..d089b18321e44c 100644
+--- a/net/mac80211/nan.c
++++ b/net/mac80211/nan.c
+@@ -253,9 +253,12 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
+ {
+ struct ieee80211_nan_channel *sched_idx_to_chan[IEEE80211_NAN_MAX_CHANNELS] = {};
+ struct ieee80211_nan_sched_cfg *sched_cfg = &sdata->vif.cfg.nan_sched;
+- struct ieee80211_nan_sched_cfg backup_sched;
++ struct ieee80211_nan_sched_cfg *backup_sched __free(kfree) = kmalloc_obj(*backup_sched);
+ int ret;
+
++ if (!backup_sched)
++ return -ENOMEM;
++
+ if (sched->n_channels > IEEE80211_NAN_MAX_CHANNELS)
+ return -EOPNOTSUPP;
+
+@@ -275,13 +278,13 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
+
+ bitmap_zero(sdata->u.nan.removed_channels, IEEE80211_NAN_MAX_CHANNELS);
+
+- memcpy(backup_sched.schedule, sched_cfg->schedule,
+- sizeof(backup_sched.schedule));
+- memcpy(backup_sched.channels, sched_cfg->channels,
+- sizeof(backup_sched.channels));
+- memcpy(backup_sched.avail_blob, sched_cfg->avail_blob,
+- sizeof(backup_sched.avail_blob));
+- backup_sched.avail_blob_len = sched_cfg->avail_blob_len;
++ memcpy(backup_sched->schedule, sched_cfg->schedule,
++ sizeof(backup_sched->schedule));
++ memcpy(backup_sched->channels, sched_cfg->channels,
++ sizeof(backup_sched->channels));
++ memcpy(backup_sched->avail_blob, sched_cfg->avail_blob,
++ sizeof(backup_sched->avail_blob));
++ backup_sched->avail_blob_len = sched_cfg->avail_blob_len;
+
+ memcpy(sched_cfg->avail_blob, sched->nan_avail_blob,
+ sched->nan_avail_blob_len);
+@@ -377,17 +380,17 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
+ if (!chan_def->chan)
+ continue;
+
+- if (!cfg80211_chandef_identical(&backup_sched.channels[i].chanreq.oper,
++ if (!cfg80211_chandef_identical(&backup_sched->channels[i].chanreq.oper,
+ chan_def))
+ ieee80211_nan_remove_channel(sdata,
+ &sched_cfg->channels[i]);
+ }
+
+ /* Re-add all backed up channels */
+- for (int i = 0; i < ARRAY_SIZE(backup_sched.channels); i++) {
++ for (int i = 0; i < ARRAY_SIZE(backup_sched->channels); i++) {
+ struct ieee80211_nan_channel *chan = &sched_cfg->channels[i];
+
+- *chan = backup_sched.channels[i];
++ *chan = backup_sched->channels[i];
+
+ /*
+ * For deferred update, no channels were removed and the channel
+@@ -418,11 +421,11 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
+ }
+ }
+
+- memcpy(sched_cfg->schedule, backup_sched.schedule,
+- sizeof(backup_sched.schedule));
+- memcpy(sched_cfg->avail_blob, backup_sched.avail_blob,
+- sizeof(backup_sched.avail_blob));
+- sched_cfg->avail_blob_len = backup_sched.avail_blob_len;
++ memcpy(sched_cfg->schedule, backup_sched->schedule,
++ sizeof(backup_sched->schedule));
++ memcpy(sched_cfg->avail_blob, backup_sched->avail_blob,
++ sizeof(backup_sched->avail_blob));
++ sched_cfg->avail_blob_len = backup_sched->avail_blob_len;
+ sched_cfg->deferred = false;
+ bitmap_zero(sdata->u.nan.removed_channels, IEEE80211_NAN_MAX_CHANNELS);
+
+--
+2.53.0
+
--- /dev/null
+From 967ea4f633fcc48c1acfd5ea026fa45b721aceef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 23:24:41 +0800
+Subject: wifi: mac80211: avoid non-S1G AID fallback for S1G assoc
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 035ed430ce6a2c35b01e211844a9f0a7643e57a4 ]
+
+When assoc_data->s1g is set and no AID Response element is present,
+falling back to mgmt->u.assoc_resp.aid reads the non-S1G
+association-response layout.
+
+Keep the fallback for non-S1G only. If a successful S1G association
+response omits the AID Response element, abandon the association
+instead of proceeding with AID 0. Initialize aid to 0 for other S1G
+responses so the later mask and logging flow keeps a defined value
+without reading the non-S1G layout.
+
+Fixes: 2a8a6b7c4cb0 ("wifi: mac80211: handle station association response with S1G")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612152440.25955-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/mlme.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index b98ddfa3003e16..ddd3479f0b4034 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -6659,7 +6659,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ {
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
+- u16 capab_info, status_code, aid;
++ u16 capab_info, status_code, aid = 0;
+ struct ieee80211_elems_parse_params parse_params = {
+ .bss = NULL,
+ .link_id = -1,
+@@ -6737,8 +6737,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+
+ if (elems->aid_resp)
+ aid = le16_to_cpu(elems->aid_resp->aid);
+- else
++ else if (!assoc_data->s1g)
+ aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
++ else if (status_code == WLAN_STATUS_SUCCESS)
++ goto abandon_assoc;
+
+ /*
+ * The 5 MSB of the AID field are reserved for a non-S1G STA. For
+--
+2.53.0
+
--- /dev/null
+From a5e76621b3a13d2401766e6d51a1a56193888202 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 16:30:28 +0800
+Subject: wifi: mac80211: defer link RX stats percpu free to RCU
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+[ Upstream commit aa2eb62525188269cdd402a583b9a8ed94657ff0 ]
+
+sta_remove_link() frees a removed MLO link's RX stats percpu buffer right
+away, but defers only the link container to RCU:
+
+ sta_info_free_link(&alloc->info);
+ kfree_rcu(alloc, rcu_head);
+
+The RX fast path reads link_sta under rcu_read_lock and writes the percpu
+stats. A reader that resolved link_sta before the removal keeps the
+pointer. The container stays alive from the kfree_rcu, so the read still
+works. But the percpu block it points to is already freed. This needs
+uses_rss. That is when pcpu_rx_stats exists.
+
+The full STA teardown frees the deflink stats only after
+synchronize_net(). The link removal path had no such barrier. The race is
+hard to win in practice, but the free should still wait for RCU.
+
+Free the link together with its data from a single RCU callback, so the
+percpu block is reclaimed only after readers drain.
+
+Fixes: c71420db653a ("wifi: mac80211: RCU-ify link STA pointers")
+Link: https://lore.kernel.org/r/20260626080158.3589711-1-maoyixie.tju@gmail.com
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
+Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Link: https://patch.msgid.link/20260627083028.3826810-1-maoyixie.tju@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/sta_info.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 4c31ef8817ce07..6d58571a364d14 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -355,6 +355,15 @@ static void sta_info_free_link(struct link_sta_info *link_sta)
+ free_percpu(link_sta->pcpu_rx_stats);
+ }
+
++static void sta_link_free_rcu(struct rcu_head *head)
++{
++ struct sta_link_alloc *alloc =
++ container_of(head, struct sta_link_alloc, rcu_head);
++
++ sta_info_free_link(&alloc->info);
++ kfree(alloc);
++}
++
+ static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id)
+ {
+ struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy,
+@@ -439,10 +448,8 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
+
+ RCU_INIT_POINTER(sta->link[link_id], NULL);
+ RCU_INIT_POINTER(sta->sta.link[link_id], NULL);
+- if (alloc) {
+- sta_info_free_link(&alloc->info);
+- kfree_rcu(alloc, rcu_head);
+- }
++ if (alloc)
++ call_rcu(&alloc->rcu_head, sta_link_free_rcu);
+
+ ieee80211_sta_recalc_aggregates(&sta->sta);
+ }
+--
+2.53.0
+
--- /dev/null
+From d6fd20a3b57868e5313d75a8916bce92503f16e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:32 -0700
+Subject: wifi: mac80211: fix fils_discovery double free on alloc failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 286e52a799fa158bdbd77da1426c4d93f9a6e7ad ]
+
+ieee80211_set_fils_discovery() calls kfree_rcu() on the old template
+before allocating the replacement. If the kzalloc() then fails, it
+returns -ENOMEM while link->u.ap.fils_discovery still points at the
+object already queued for freeing. A later update or AP teardown
+(ieee80211_stop_ap()) re-queues that same rcu_head; the second free is
+caught by KASAN when the RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800c065280 by task swapper/0/0
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-96 of size 96
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-2-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index e926bced6a313d..0bc10136b816ef 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1145,9 +1145,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ fd->max_interval = params->max_interval;
+
+ old = sdata_dereference(link->u.ap.fils_discovery, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+-
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+ if (!new)
+@@ -1159,6 +1156,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_FILS_DISCOVERY;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From aa388d2ecef303b1fa24fa8d8051ab76d5265562 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 02:35:31 -0700
+Subject: wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc
+ failure
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 1d067abcd37062426c59ec73dbc4e87a63f33fea ]
+
+ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old
+template before allocating the replacement. If the kzalloc() then fails,
+it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points
+at the object already queued for freeing. A later update or AP teardown
+re-queues that same rcu_head; the second free is caught by KASAN when the
+RCU sheaf is processed in softirq:
+
+ BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
+ Free of addr ffff88800d06f300 by task exploit/145
+ ...
+ __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
+ rcu_free_sheaf (mm/slub.c:5850)
+ rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
+ handle_softirqs (kernel/softirq.c:622)
+ The buggy address belongs to the cache kmalloc-128 of size 128
+
+Queue the old object for kfree_rcu() only after the new one is published,
+matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
+
+Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Link: https://patch.msgid.link/20260621093532.884188-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index f9ee9947a94d66..e926bced6a313d 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1178,8 +1178,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ link_conf->unsol_bcast_probe_resp_interval = params->interval;
+
+ old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata);
+- if (old)
+- kfree_rcu(old, rcu_head);
+
+ if (params->tmpl && params->tmpl_len) {
+ new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
+@@ -1192,6 +1190,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
+ RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL);
+ }
+
++ if (old)
++ kfree_rcu(old, rcu_head);
++
+ *changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
+ return 0;
+ }
+--
+2.53.0
+
--- /dev/null
+From a00403bc65620a89975c590996e5bf5111f12bad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jul 2026 22:08:41 +0800
+Subject: wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
+
+ieee80211_do_stop() removes AP_VLAN packets from the parent AP
+ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then
+calls ieee80211_free_txskb() before dropping the lock.
+
+ieee80211_free_txskb() is not just a passive SKB release. For SKBs with
+TX status state it can report a dropped frame through cfg80211/nl80211,
+and that path can reach netlink tap transmit. This is the same reason
+the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs
+under the queue lock and frees them after IRQ state is restored.
+
+The buggy scenario involves two paths, with each column showing the
+order within that path:
+
+AP_VLAN management TX: AP_VLAN stop:
+1. attach ACK-status state 1. clear the running state
+2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
+ parent ps->bc_buf disabled
+ 3. unlink the AP_VLAN SKB
+ 4. call ieee80211_free_txskb()
+
+Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock,
+but move them to a local free queue. Drop the lock and restore IRQ state
+before calling ieee80211_free_txskb().
+
+WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
+
+Fixes: 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Link: https://patch.msgid.link/20260706140841.581566-1-zzzccc427@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 95b779c4d627e8..a3a3b9f247214a 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -588,6 +588,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ WARN_ON(!list_empty(&sdata->u.ap.vlans));
+ } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* remove all packets in parent bc_buf pointing to this dev */
++ __skb_queue_head_init(&freeq);
+ ps = &sdata->bss->ps;
+
+ spin_lock_irqsave(&ps->bc_buf.lock, flags);
+@@ -595,10 +596,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ if (skb->dev == sdata->dev) {
+ __skb_unlink(skb, &ps->bc_buf);
+ local->total_ps_buffered--;
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
++
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ if (going_down)
+--
+2.53.0
+
--- /dev/null
+From e2c97adcb6271221994f9c00eb3691cc317158e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2026 21:45:18 -0500
+Subject: wifi: mac80211_hwsim: clamp virtio RX length before skb_put
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
+
+hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by
+the device straight to skb_put() on a fixed-size receive skb. A backend
+reporting a length larger than the skb tailroom drives skb_put() past the
+buffer end and hits skb_over_panic() -- a host-triggerable guest panic
+(denial of service).
+
+Clamp the length to the skb's available room before skb_put(). A
+conforming device never reports more than the posted buffer size, so valid
+frames are unaffected; a truncated over-report then fails the
+length/header checks in hwsim_virtio_handle_cmd() and is dropped, so
+truncating rather than dropping here cannot be turned into a parsing
+problem.
+
+Fixes: 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260620-b4-disp-474bee37-v1-1-1a4d37f3e2d4@proton.me
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index 1fcf5d0d2e13fe..17bf8e547b25be 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -7122,6 +7122,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
+
+ skb->data = skb->head;
+ skb_reset_tail_pointer(skb);
++ len = min(len, skb_end_offset(skb));
+ skb_put(skb, len);
+ hwsim_virtio_handle_cmd(skb);
+
+--
+2.53.0
+
--- /dev/null
+From c13adac32434d3ae6a4e5fd717cfd3b1e4cb7ce9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:56 +0800
+Subject: wifi: nl80211: constrain MBSSID TX link ID range
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 172f06023669f0a96d32511669ff45c600731380 ]
+
+MBSSID transmitted-profile link IDs are valid only in the range
+0..IEEE80211_MLD_MAX_NUM_LINKS - 1. Constrain the nl80211 policy to
+reject out-of-range values during attribute validation.
+
+Fixes: 37523c3c47b3 ("wifi: nl80211: add link id of transmitted profile for MLO MBSSID")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-4-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 264ae4e742a1c4..3024fa8dd78021 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -616,7 +616,7 @@ nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
+ [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
+ [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
+ [NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID] =
+- NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS),
++ NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1),
+ };
+
+ static const struct nla_policy
+--
+2.53.0
+
--- /dev/null
+From a85b10763ce26921dc519309293c18100341f853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 19:22:09 +0800
+Subject: wifi: nl80211: free RNR data on MBSSID mismatch
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
+
+nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR
+entries than MBSSID entries.
+
+The rejected RNR allocation has not been attached to the beacon data yet,
+so free it before returning the error.
+
+Fixes: dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260610112208.1308-2-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 21e43e08b5d795..c7edaea9873e0a 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6519,8 +6519,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (IS_ERR(rnr))
+ return PTR_ERR(rnr);
+
+- if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
++ if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
++ kfree(rnr);
+ return -EINVAL;
++ }
+
+ bcn->rnr_ies = rnr;
+ }
+--
+2.53.0
+
--- /dev/null
+From cc239f885f9fbafde4f25767b112e59e37afe7cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 21:18:55 +0800
+Subject: wifi: nl80211: validate nested MBSSID IE blobs
+
+From: Zhao Li <enderaoelyther@gmail.com>
+
+[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
+
+Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed
+information-element stream before storing it for beacon construction.
+
+RNR parsing already validates each nested blob with validate_ie_attr()
+before storing it. Apply the same syntactic IE validation to MBSSID
+entries before counting and copying their data and length pointers.
+
+Fixes: dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
+Assisted-by: Codex:gpt-5.5
+Assisted-by: Claude:claude-opus-4.8
+Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
+Link: https://patch.msgid.link/20260612131854.43575-3-enderaoelyther@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index c7edaea9873e0a..264ae4e742a1c4 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -6321,7 +6321,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
+ }
+
+ static struct cfg80211_mbssid_elems *
+-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
++nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
++ struct netlink_ext_ack *extack)
+ {
+ struct nlattr *nl_elems;
+ struct cfg80211_mbssid_elems *elems;
+@@ -6332,6 +6333,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+ return ERR_PTR(-EINVAL);
+
+ nla_for_each_nested(nl_elems, attrs, rem_elems) {
++ int ret;
++
++ ret = validate_ie_attr(nl_elems, extack);
++ if (ret)
++ return ERR_PTR(ret);
++
+ if (num_elems >= 255)
+ return ERR_PTR(-EINVAL);
+ num_elems++;
+@@ -6503,7 +6510,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
+ struct cfg80211_mbssid_elems *mbssid =
+ nl80211_parse_mbssid_elems(&rdev->wiphy,
+- attrs[NL80211_ATTR_MBSSID_ELEMS]);
++ attrs[NL80211_ATTR_MBSSID_ELEMS],
++ extack);
+
+ if (IS_ERR(mbssid))
+ return PTR_ERR(mbssid);
+--
+2.53.0
+
--- /dev/null
+From e5d8b09f61d89563cf7e9589dd76c9d79d57d6d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 17:05:10 -0700
+Subject: wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
+
+p54_rx_eeprom_readback() copies the requested EEPROM slice out of a
+device-supplied readback frame without checking that the skb actually holds
+that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in
+p54_rx_eeprom_readback()") closed the destination overflow by copying a
+fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len),
+but the source side is still unbounded: nothing verifies the frame is long
+enough to supply that many bytes.
+
+A malicious USB device can send a short frame whose advertised len matches
+priv->eeprom_slice_size while the payload is truncated. The equality check
+passes and memcpy() reads past the end of the skb, leaking adjacent heap:
+
+ BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
+ Call Trace:
+ <IRQ>
+ ...
+ __asan_memcpy (mm/kasan/shadow.c:105)
+ p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
+ p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
+ __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
+ dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
+ ...
+ </IRQ>
+
+ The buggy address belongs to the object at ffff88800f0770c0
+ which belongs to the cache skbuff_small_head of size 704
+ The buggy address is located 84 bytes inside of
+ allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
+
+Check that the slice fits in the skb before copying.
+
+Fixes: 7cb770729ba8 ("p54: move eeprom code into common library")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Link: https://patch.msgid.link/20260628000510.4152481-1-xmei5@asu.edu
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/intersil/p54/txrx.c b/drivers/net/wireless/intersil/p54/txrx.c
+index 1294a1d6528e2c..9f491334c8d043 100644
+--- a/drivers/net/wireless/intersil/p54/txrx.c
++++ b/drivers/net/wireless/intersil/p54/txrx.c
+@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
+ if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v2.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
+ } else {
+ if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
+ return;
+
++ if (eeprom->v1.data + priv->eeprom_slice_size >
++ skb_tail_pointer(skb))
++ return;
++
+ memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From d7f44c5eea8778f994a6e2d95d27785944da5e89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 11:01:17 +0800
+Subject: xfrm: clear mode callbacks after failed mode setup
+
+From: Cen Zhang <zzzccc427@gmail.com>
+
+[ Upstream commit 2538bd3cd1ff5af655908469544ac7b7ae259386 ]
+
+xfrm_state_gc_task can run long after a failed IPTFS state setup. In the
+reproduced case, __xfrm_init_state() cached x->mode_cbs, IPTFS setup
+returned -ENOMEM before publishing mode_data, and the temporary module
+reference from xfrm_get_mode_cbs() was dropped immediately. The dead state
+then kept x->mode_cbs until deferred GC ran after xfrm_iptfs had been
+unloaded.
+
+Clear x->mode_cbs when mode init or clone fails before publishing
+mode_data. Those states never installed mode-specific state or the
+long-term IPTFS module pin, so deferred GC has nothing mode-specific to
+destroy and must not retain a callback table pointer past the temporary
+lookup reference.
+
+The buggy scenario involves two paths, with each column showing the order
+within that path:
+
+failed setup path:
+1. cache x->mode_cbs
+2. mode setup fails before mode_data
+3. drop the temporary module ref
+4. dead state keeps x->mode_cbs cached
+
+GC/unload path:
+1. xfrm_state_put() queues GC work
+2. xfrm_iptfs unloads later
+3. xfrm_state_gc_task runs
+4. GC dereferences stale x->mode_cbs
+
+This also covers the failed clone path where clone_state() returns before
+publishing mode_data.
+
+Validation reproduced this kernel report:
+Kernel panic - not syncing: Fatal exception
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+failslab_stacktrace_filter matched xfrm_iptfs frames
+ack_error=-12
+FAULT_INJECTION: forcing a failure
+BUG: unable to handle page fault
+Workqueue: events xfrm_state_gc_task
+RIP: xfrm_state_gc_task+0x142/0x650
+Modules linked in: esp4_offload xfrm_user [last unloaded: xfrm_iptfs]
+Kernel panic - not syncing: Fatal exception
+
+Fixes: 4b3faf610cc6 ("xfrm: iptfs: add new iptfs xfrm mode impl")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 511a7402ada41b..37193d2fcc2f2b 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2070,8 +2070,11 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
+
+ x->mode_cbs = orig->mode_cbs;
+ if (x->mode_cbs && x->mode_cbs->clone_state) {
+- if (x->mode_cbs->clone_state(x, orig))
++ if (x->mode_cbs->clone_state(x, orig)) {
++ if (!x->mode_data)
++ x->mode_cbs = NULL;
+ goto error;
++ }
+ }
+
+
+@@ -3254,6 +3257,8 @@ int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
+ if (x->mode_cbs->init_state)
+ err = x->mode_cbs->init_state(x);
+ module_put(x->mode_cbs->owner);
++ if (err && !x->mode_data)
++ x->mode_cbs = NULL;
+ }
+ error:
+ return err;
+--
+2.53.0
+
--- /dev/null
+From fbe704d9f52f1403485d2ba84e01101523cd8bb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 02:40:23 +0000
+Subject: xfrm: fix sk_dst_cache double-free in xfrm_user_policy()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit c283e9ada7fcb7dd4b10592623086b2e6d2f9925 ]
+
+xfrm_user_policy() clears the socket dst cache with __sk_dst_reset(),
+i.e. the non-atomic __sk_dst_set(sk, NULL): it reads sk_dst_cache with
+rcu_dereference_protected(), stores NULL and dst_release()s the old dst.
+That is only safe if no other thread modifies sk_dst_cache concurrently.
+
+For a connected UDP socket that does not hold: the transmit fast path
+(udp_sendmsg -> sk_dst_check -> sk_dst_reset) resets the cache locklessly
+with an atomic xchg(). A per-socket policy change racing a send can make
+both sides observe the same old dst and each dst_release() it, dropping
+the socket's single reference twice and freeing the xfrm_dst bundle while
+it is still referenced:
+
+ BUG: KASAN: slab-use-after-free in dst_release
+ Write of size 4 at addr ffff88801897b6c0 by task exploit/155
+ Call Trace:
+ ...
+ dst_release (... ./include/linux/rcuref.h:109)
+ xfrm_user_policy (./include/net/sock.h:2239 ./include/net/sock.h:2256 net/xfrm/xfrm_state.c:3053)
+ do_ip_setsockopt (net/ipv4/ip_sockglue.c:1347)
+ ip_setsockopt (net/ipv4/ip_sockglue.c:1417)
+ do_sock_setsockopt (net/socket.c:2368)
+ __sys_setsockopt (net/socket.c:2393)
+ __x64_sys_setsockopt (net/socket.c:2396)
+ do_syscall_64 (arch/x86/entry/syscall_64.c:94)
+ entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Reachable by an unprivileged user via a user+network namespace.
+
+Use the atomic sk_dst_reset() so the cache is cleared and released with a
+single xchg(): whichever side wins releases the dst once, the other sees
+NULL and does nothing. Behaviour is otherwise unchanged.
+
+Fixes: 2b06cdf3e688 ("xfrm: Clear sk_dst_cache when applying per-socket policy.")
+Fixes: be8f8284cd89 ("net: xfrm: allow clearing socket xfrm policies.")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index ec9ecf72c76ba1..511a7402ada41b 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2973,7 +2973,7 @@ int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
+ if (sockptr_is_null(optval) && !optlen) {
+ xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
+ xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
+- __sk_dst_reset(sk);
++ sk_dst_reset(sk);
+ return 0;
+ }
+
+@@ -3013,7 +3013,7 @@ int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
+ if (err >= 0) {
+ xfrm_sk_policy_insert(sk, err, pol);
+ xfrm_pol_put(pol);
+- __sk_dst_reset(sk);
++ sk_dst_reset(sk);
+ err = 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 84f63b4cbda3548a984e5e3d24beffbb536ed929 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 12:03:27 +0200
+Subject: xfrm: fix stale skb->prev after async crypto steals a GSO segment
+
+From: Petr Wozniak <petr.wozniak@gmail.com>
+
+[ Upstream commit 3f4c3919baf0944ad96580467c302bc6c7758b00 ]
+
+skb_gso_segment() leaves the segment list head with ->prev pointing at
+the last segment, an invariant validate_xmit_skb_list() relies on when
+it sets its tail pointer (tail = skb->prev).
+
+When validate_xmit_xfrm() walks a GSO list and some segments are stolen
+by async crypto (->xmit() returns -EINPROGRESS), those segments are
+unlinked from the list but the head ->prev is never updated. If the
+last segment is the one stolen, the returned head still has ->prev
+pointing at it, even though it is now owned by the crypto engine and may
+be freed. validate_xmit_skb_list() later does tail->next = skb, writing
+through that stale pointer -- a use-after-free.
+
+Repoint skb->prev at the last retained segment before returning.
+
+Fixes: f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_device.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 8b526e3676389a..4719aba331cd66 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -224,6 +224,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ pskb = skb2;
+ }
+
++ /* skb_gso_segment() set skb->prev to the last segment, but async
++ * crypto may have stolen it above without updating ->prev. Repoint
++ * it at the last retained segment so validate_xmit_skb_list() does
++ * not chain onto a segment now owned by the crypto engine.
++ */
++ if (skb)
++ skb->prev = pskb;
++
+ return skb ? skb : ERR_PTR(-EINPROGRESS);
+ }
+ EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
+--
+2.53.0
+
--- /dev/null
+From 4a4cfad61c7440a30aa8ade648f3b27e96a3a2da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2026 11:31:52 +0800
+Subject: xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
+
+From: Chen YanJun <moomichen@tencent.com>
+
+[ Upstream commit 430ea57d6daf765e88f90046afbfd1e071cb7200 ]
+
+When iptfs_skb_add_frags() copies frag references from the source
+frag walk into a new SKB, it increments the page reference count via
+__skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the
+destination SKB's skb_shinfo->flags.
+
+If the source SKB carries shared frags (e.g. from a page-pool backed
+receive path), the new inner SKB will appear to ESP as having privately
+owned frags. A subsequent esp_input() call for a nested transport-mode
+SA then takes the no-COW fast path and decrypts in place, writing over
+pages that are still referenced by the outer IPTFS SKB. This causes
+kernel-visible memory corruption and can trigger a panic.
+
+All other frag-transfer helpers in the kernel (skb_try_coalesce,
+skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly
+propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this
+convention by setting the flag inside the loop immediately after
+__skb_frag_ref() and nr_frags++, so every exit path that attaches a frag
+unconditionally propagates SKBFL_SHARED_FRAG.
+
+Fixes: 5f2b6a909574 ("xfrm: iptfs: add skb-fragment sharing code")
+Signed-off-by: Chen YanJun <moomichen@tencent.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_iptfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c
+index ad810d1f97c067..597aedeac26eba 100644
+--- a/net/xfrm/xfrm_iptfs.c
++++ b/net/xfrm/xfrm_iptfs.c
+@@ -480,6 +480,7 @@ static int iptfs_skb_add_frags(struct sk_buff *skb,
+ }
+ __skb_frag_ref(tofrag);
+ shinfo->nr_frags++;
++ shinfo->flags |= SKBFL_SHARED_FRAG;
+
+ /* see if we are done */
+ fraglen = tofrag->len;
+--
+2.53.0
+
--- /dev/null
+From 6f67b13665946bc1ff6570953d2451392ce12659 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 05:19:32 +0000
+Subject: xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild
+ reinsert
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
+
+xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert
+loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or
+fail. But its guard is inverted: it skips policies with prefixlen <
+threshold and preallocates for the rest.
+
+prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and
+the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the
+loop preallocates for the exact policies (which never allocate) and skips
+the inexact ones, whose bin/node is then allocated GFP_ATOMIC during
+reinsert. On failure the error path only WARN_ONCE()s and continues,
+leaving a poisoned bydst node; the next rebuild's hlist_del_rcu()
+dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure,
+deterministic via failslab.
+
+Invert the guard so preallocation covers exactly the reinserted policies;
+the reinsert then allocates nothing and cannot fail.
+
+Crash:
+ Oops: general protection fault, probably for non-canonical address
+ 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
+ KASAN: maybe wild-memory-access in range [0xdead...]
+ ...
+ Workqueue: events xfrm_hash_rebuild
+ RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
+ RAX: dead000000000122 (LIST_POISON2 + offset)
+ ...
+ Call Trace:
+ hlist_del_rcu (include/linux/rculist.h:599)
+ xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
+ process_one_work (kernel/workqueue.c:3322)
+ worker_thread (kernel/workqueue.c:3486)
+ kthread (kernel/kthread.c:436)
+ ret_from_fork (arch/x86/kernel/process.c:158)
+ ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+ ...
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fixes: 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 639934f300167e..bed4b5a3fcce14 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1329,8 +1329,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
+ }
+ }
+
+- if (policy->selector.prefixlen_d < dbits ||
+- policy->selector.prefixlen_s < sbits)
++ if (policy->selector.prefixlen_d >= dbits &&
++ policy->selector.prefixlen_s >= sbits)
+ continue;
+
+ bin = xfrm_policy_inexact_alloc_bin(policy, dir);
+--
+2.53.0
+
--- /dev/null
+From 1d33af02420e8a4a593cc62bcd93c3fb486a5233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jun 2026 12:03:26 +0200
+Subject: xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()
+
+From: Petr Wozniak <petr.wozniak@gmail.com>
+
+[ Upstream commit 6860b467f569f732b11cbc588ae7e195e90e7e23 ]
+
+validate_xmit_xfrm() returns NULL both when a packet is dropped and
+when it is stolen by async crypto (-EINPROGRESS from ->xmit()).
+Callers cannot distinguish the two cases.
+
+f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+changed the semantics of a NULL return from "dropped" to "stolen or
+dropped", but __dev_queue_xmit() was not updated. On virtual/bridge
+interfaces (noqueue qdisc) __dev_queue_xmit() initialises rc=-ENOMEM
+and jumps to out: when skb is NULL, returning -ENOMEM to the caller
+even though the packet will be delivered correctly via xfrm_dev_resume().
+
+Return ERR_PTR(-EINPROGRESS) from validate_xmit_xfrm() for the async
+case so callers can tell it apart from a real drop. Update
+__dev_queue_xmit() to handle ERR_PTR(-EINPROGRESS) from
+validate_xmit_skb() correctly. Update validate_xmit_skb_list() to
+use IS_ERR_OR_NULL() so that ERR_PTR(-EINPROGRESS) is not mistakenly
+added to the transmitted list.
+
+Fixes: f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
+Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 10 ++++++++--
+ net/xfrm/xfrm_device.c | 4 ++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index f81ce83fb3250d..31741169cb0ba6 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4016,6 +4016,9 @@ static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb,
+ return NULL;
+ }
+
++/* Returns the skb on success, NULL if dropped, or ERR_PTR(-EINPROGRESS)
++ * if stolen by async xfrm crypto (delivered via xfrm_dev_resume()).
++ */
+ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev, bool *again)
+ {
+ netdev_features_t features;
+@@ -4087,7 +4090,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d
+ skb->prev = skb;
+
+ skb = validate_xmit_skb(skb, dev, again);
+- if (!skb)
++ if (IS_ERR_OR_NULL(skb))
+ continue;
+
+ if (!head)
+@@ -4858,8 +4861,11 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
+ goto recursion_alert;
+
+ skb = validate_xmit_skb(skb, dev, &again);
+- if (!skb)
++ if (IS_ERR_OR_NULL(skb)) {
++ if (PTR_ERR(skb) == -EINPROGRESS)
++ rc = NET_XMIT_SUCCESS;
+ goto out;
++ }
+
+ HARD_TX_LOCK(dev, txq, cpu);
+
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 550457e4c4f01d..8b526e3676389a 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -182,7 +182,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ err = x->type_offload->xmit(x, skb, esp_features);
+ if (err) {
+ if (err == -EINPROGRESS)
+- return NULL;
++ return ERR_PTR(-EINPROGRESS);
+
+ XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
+ kfree_skb(skb);
+@@ -224,7 +224,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ pskb = skb2;
+ }
+
+- return skb;
++ return skb ? skb : ERR_PTR(-EINPROGRESS);
+ }
+ EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
+
+--
+2.53.0
+
--- /dev/null
+From 703c32b81c93c9098705c5561e5d58d11ee80fcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jun 2026 10:23:43 +0200
+Subject: xfrm: reject optional IPTFS templates in outbound policies
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit ea528f18231ec0f33317be57f8866913b19aba6e ]
+
+syzbot reported a stack-out-of-bounds read in xfrm_state_find()
+which flows from xfrm_tmpl_resolve_one().
+
+Commit 3d776e31c841 ("xfrm: Reject optional tunnel/BEET mode
+templates in outbound policies") disallowed optional tunnel and
+BEET in outbound policies to prevent this. Later when IPTFS
+added, it was not covered by that fix and can still trigger
+the out-of-bounds read;
+
+Extend the check to disallow optional IPTFS in outbound policies
+as well. IPTFS should be identical to tunnel mode.
+IN and FWD policies are not affected: xfrm_tmpl_resolve_one()
+is only reachable via the outbound path.
+
+Reproducer, before:
+
+ip link add dummy0 type dummy
+ip link set dummy0 up
+ip addr add 10.1.1.1/24 dev dummy0
+ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl
+ src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs
+ level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid
+ 2 mode transport
+ping -W 1 -c 1 10.1.1.2
+PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
+
+[ 64.168420] ==================================================================
+[ 64.169977] BUG: KASAN: stack-out-of-bounds in __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] Read of size 4 at addr ffff88800e1ffd20 by task ping/2844
+
+[ 64.169977] CPU: 2 UID: 0 PID: 2844 Comm: ping Not tainted 7.1.0-rc7-00180-geb23b588430a #98 PREEMPT(full)
+[ 64.169977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 64.169977] Call Trace:
+[ 64.169977] <TASK>
+[ 64.169977] dump_stack_lvl+0x47/0x70
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] print_report+0x152/0x4b0
+[ 64.169977] ? ksys_mmap_pgoff+0x6d/0xa0
+[ 64.169977] ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
+[ 64.169977] ? __virt_addr_valid+0x21b/0x230
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] kasan_report+0xa8/0xd0
+[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] __xfrm6_addr_hash+0x11e/0x170
+[ 64.169977] __xfrm_dst_hash+0x24/0xc0
+[ 64.169977] xfrm_state_find+0xa2d/0x2f90
+[ 64.169977] ? __pfx_xfrm_state_find+0x10/0x10
+[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
+[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
+[ 64.169977] xfrm_tmpl_resolve_one+0x210/0x570
+[ 64.169977] ? __pfx_xfrm_tmpl_resolve_one+0x10/0x10
+[ 64.169977] ? __pfx_stack_trace_consume_entry+0x10/0x10
+[ 64.169977] ? kernel_text_address+0x5b/0x80
+[ 64.169977] ? __kernel_text_address+0xe/0x30
+[ 64.169977] ? unwind_get_return_address+0x5e/0x90
+[ 64.169977] ? arch_stack_walk+0x8c/0xe0
+[ 64.169977] xfrm_tmpl_resolve+0x130/0x200
+[ 64.169977] ? __pfx_xfrm_tmpl_resolve+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_inexact_lookup_rcu+0x10/0x10
+[ 64.169977] ? __refcount_add_not_zero.constprop.0+0xb2/0x110
+[ 64.169977] ? __pfx___refcount_add_not_zero.constprop.0+0x10/0x10
+[ 64.169977] xfrm_resolve_and_create_bundle+0xd5/0x310
+[ 64.169977] ? __pfx_xfrm_resolve_and_create_bundle+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
+[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
+[ 64.169977] xfrm_lookup_with_ifid+0x3d8/0xb80
+[ 64.169977] ? __pfx_xfrm_lookup_with_ifid+0x10/0x10
+[ 64.169977] ? ip_route_output_key_hash+0xc6/0x110
+[ 64.169977] ? kasan_save_track+0x10/0x30
+[ 64.169977] xfrm_lookup_route+0x18/0xe0
+[ 64.169977] ip4_datagram_release_cb+0x4c9/0x530
+[ 64.169977] ? __pfx_ip4_datagram_release_cb+0x10/0x10
+[ 64.169977] ? do_raw_spin_lock+0x71/0xc0
+[ 64.169977] ? __pfx_do_raw_spin_lock+0x10/0x10
+[ 64.169977] release_sock+0xb0/0x170
+[ 64.169977] udp_connect+0x43/0x50
+[ 64.169977] __sys_connect+0xa6/0x100
+[ 64.169977] ? alloc_fd+0x2e9/0x300
+[ 64.169977] ? __pfx___sys_connect+0x10/0x10
+[ 64.169977] ? preempt_latency_start+0x1f/0x70
+[ 64.169977] ? fd_install+0x7e/0x150
+[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
+[ 64.169977] ? __sys_socket+0xdf/0x130
+[ 64.169977] ? __pfx___sys_socket+0x10/0x10
+[ 64.169977] ? vma_refcount_put+0x43/0xa0
+[ 64.169977] __x64_sys_connect+0x7e/0x90
+[ 64.169977] do_syscall_64+0x11b/0x2b0
+[ 64.169977] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[ 64.169977] RIP: 0033:0x7f4851ecb570
+[ 64.169977] Code: 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 80 3d f9 ca 0d 00 00 74 17 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 54
+[ 64.169977] RSP: 002b:00007ffc830e3498 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
+[ 64.169977] RAX: ffffffffffffffda RBX: 00007ffc830e34d0 RCX: 00007f4851ecb570
+[ 64.169977] RDX: 0000000000000010 RSI: 00007ffc830e34d0 RDI: 0000000000000005
+[ 64.169977] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
+[ 64.169977] R10: 0000000000000006 R11: 0000000000000202 R12: 0000000000000005
+[ 64.169977] R13: 0000000000000000 R14: 00005619a863f340 R15: 0000000000000000
+[ 64.169977] </TASK>
+
+[ 64.169977] The buggy address belongs to stack of task ping/2844
+[ 64.169977] and is located at offset 88 in frame:
+[ 64.169977] ip4_datagram_release_cb+0x0/0x530
+
+[ 64.169977] This frame has 1 object:
+[ 64.169977] [32, 88) 'fl4'
+
+[ 64.169977] The buggy address belongs to the physical page:
+[ 64.169977] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xe1ff
+[ 64.169977] flags: 0x4000000000000000(zone=1)
+[ 64.169977] raw: 4000000000000000 0000000000000000 ffffea0000387fc8 0000000000000000
+[ 64.169977] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+[ 64.169977] page dumped because: kasan: bad access detected
+
+[ 64.169977] Memory state around the buggy address:
+[ 64.169977] ffff88800e1ffc00: f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00
+[ 64.169977] ffff88800e1ffc80: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00
+[ 64.169977] >ffff88800e1ffd00: 00 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00
+[ 64.169977] ^
+[ 64.169977] ffff88800e1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
+[ 64.169977] ffff88800e1ffe00: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 64.169977] ==================================================================
+[ 64.245153] Disabling lock debugging due to kernel taint
+
+After the fix:
+
+ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl \
+ src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs \
+ level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 \
+ mode transport
+
+Error: Mode in optional template not allowed in outbound policy.
+
+Fixes: d1716d5a44c3 ("xfrm: add generic iptfs defines and functionality")
+Reported-by: syzbot+0ac4d84afe1066a1f3e9@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/6a3ceb94.43b4ff68.30a095.0004.GAE@google.com/T/
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 61eb5de33b87ee..b36741c4ea3de9 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -2077,13 +2077,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
+ switch (ut[i].mode) {
+ case XFRM_MODE_TUNNEL:
+ case XFRM_MODE_BEET:
++ case XFRM_MODE_IPTFS:
+ if (ut[i].optional && dir == XFRM_POLICY_OUT) {
+ NL_SET_ERR_MSG(extack, "Mode in optional template not allowed in outbound policy");
+ return -EINVAL;
+ }
+ break;
+- case XFRM_MODE_IPTFS:
+- break;
+ default:
+ if (ut[i].family != prev_family) {
+ NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
+--
+2.53.0
+
--- /dev/null
+From 34689c1f84155c2b6012fda750473926334364ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 01:05:16 +0000
+Subject: xfrm6: clear dst.dev on error to avoid double netdev_put in
+ xfrm6_fill_dst()
+
+From: Xiang Mei (Microsoft) <xmei5@asu.edu>
+
+[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
+
+On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst()
+releases the device reference with netdev_put() but leaves
+xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev)
+again, so the same net_device reference is released twice, underflowing
+its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for
+<dev> to become free").
+
+Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM
+device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in
+net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
+
+ ref_tracker: reference already released.
+ ref_tracker: allocated in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
+ ...
+ udpv6_sendmsg (net/ipv6/udp.c:1696)
+ ...
+ ref_tracker: freed in:
+ xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
+ ...
+ WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
+ dst_destroy (net/core/dst.c:115)
+ rcu_core
+ handle_softirqs
+ ...
+
+Fixes: 84c4a9dfbf43 ("xfrm6: release dev before returning error")
+Reported-by: AutonomousCodeSecurity@microsoft.com
+Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/xfrm6_policy.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 125ea9a5b8a082..3b749475f6ed65 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+ if (!xdst->u.rt6.rt6i_idev) {
+ netdev_put(dev, &xdst->u.dst.dev_tracker);
++ xdst->u.dst.dev = NULL;
+ return -ENODEV;
+ }
+
+--
+2.53.0
+