Changelog in Linux kernel 7.2.11

 
ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers [+ + +]
Author: Harin Lee <[email protected]>
Date:   Thu Oct 1 23:45:01 2026 +0900

    ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers
    
    commit 593d46fc6af9a0178a46e77d6d24b20d2314165f upstream.
    
    Commit e576e7843c0d ("ALSA: ctxfi: Simplify dao_clear_{left,right}_input() functions")
    centralized the DAO input mapper clearing logic in
    dao_clear_input(), but omitted the kfree() calls.
    
    It removes the mapper entries from the list and sets their pointers
    to NULL without freeing the allocated array. This leaks memory each
    time dao_clear_input() is called.
    
    Store the base pointer of the allocation before clearing the mapper
    entries and free the array after removing entries from the list.
    
    Fixes: e576e7843c0d ("ALSA: ctxfi: Simplify dao_clear_{left,right}_input() functions")
    Cc: [email protected]
    Signed-off-by: Harin Lee <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Takashi Iwai <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ALSA: hda/tas2781: Accept V1 calibration data without CRC [+ + +]
Author: Mohamed Yassine Jebabli <[email protected]>
Date:   Thu Oct 1 12:24:42 2026 +0200

    ALSA: hda/tas2781: Accept V1 calibration data without CRC
    
    commit 408249089c48df1a4d23f60b831be3f3c311e6d1 upstream.
    
    Some Lenovo BIOSes (e.g. Legion Pro 7 16IRX9H, SSID 17aa:38cd) store
    valid V1 calibration data in the CALI_DATA EFI variable but leave the
    TimeStamp and CRC fields zeroed. The driver rejects such data, so the
    amplifiers always run with default parameters on these machines.
    
    The rejection was silent until
    commit 4fe238513407 ("ALSA: hda/tas2781: Move and unified the
    calibrated-data getting function for SPI and I2C into the tas2781_hda lib")
    turned it into "V1 CRC error".
    
    The stored values are consistent (R0 = 3.82/3.83 ohm, 1/R0 matching
    within 1e-4), so accept V1 data when both TimeStamp and CRC are zero
    and the first device entry is non-zero, and emit a warning.
    
    Fixes: 5be27f1e3ec9 ("ALSA: hda/tas2781: Add tas2781 HDA driver")
    Cc: [email protected]
    Signed-off-by: Mohamed Yassine Jebabli <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Takashi Iwai <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
amt: send the relay's General Query directly from the receive path [+ + +]
Author: Omar Ramadan <[email protected]>
Date:   Mon Sep 28 23:23:11 2026 +0300

    amt: send the relay's General Query directly from the receive path
    
    [ Upstream commit afae89de73dd693cfa329580ba0fba63bd3f0a11 ]
    
    An skb queued in a qdisc can outlive the tunnel it references
    through a raw pointer in skb->cb. For example, with igmp_qrv set
    to 1 on the relay a tunnel lives for 135s, so a netem delay of
    180s on the amt device outlives it; when the tunnel expires and is
    freed, the subsequent dequeue triggers a use-after-free in
    amt_dev_xmit().
    
      BUG: KASAN: slab-use-after-free in amt_dev_xmit+0x2763/0x2e20
      Call Trace:
       amt_dev_xmit+0x2763/0x2e20 [drivers/net/amt.c:1262]
       dev_hard_start_xmit+0x22f/0x620
       sch_direct_xmit+0x12e/0xac0
       netem_dequeue+0x333/0xc50
       net_tx_action+0x35c/0xa60
    
    amt_send_igmp_gq() and amt_send_mld_gq() are only called from
    amt_request_handler(), inside the rcu_read_lock_bh() section of
    amt_rcv(). amt_request_handler() already has the tunnel the query is
    for: it found or created it inside that section. Queuing the query with
    dev_queue_xmit() only leads back into amt_dev_xmit(), which strips the
    Ethernet header and calls amt_send_membership_query() for that tunnel.
    
    Make that call directly from the two senders instead, the same way
    amt_send_advertisement() transmits from the receive path. The query
    never waits in a qdisc, the tunnel is only dereferenced inside the
    RCU section that found or created it, and nothing is stored in
    skb->cb, so no lookup or refcount is needed. Remove the query branch
    of amt_dev_xmit(), amt_skb_cb() and struct amt_skb_cb, which have no
    users left.
    
    Behaviour changes:
     - The relay's own General Queries no longer pass through the amt
       device's egress path: its qdisc, tc egress (clsact/tcx), the
       netfilter egress hook and packet taps. They are still visible as
       UDP on the underlay.
     - A query that is sent successfully is no longer counted as
       tx_dropped. The old query branch left through the unlock label,
       which counted every sent query as dropped.
     - A query that reaches amt_dev_xmit() on a relay from elsewhere,
       such as a userspace querier, is now dropped at the IGMP/MLD type
       switch. Before, it trusted whatever skb->cb held, and a NULL
       tunnel hit the WARN_ON(1).
    
    Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
    Reported-by: [email protected]
    Reported-by: Xiang Mei (Microsoft) <[email protected]>
    Reported-by: Cen Zhang (Microsoft Security FORGE Labs) <[email protected]>
    Signed-off-by: Omar Ramadan <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
arm64/boot: Don't set PMUv3p9 FGT2 bits without PMUv3 [+ + +]
Author: Fuad Tabba <[email protected]>
Date:   Wed Sep 30 13:12:12 2026 +0100

    arm64/boot: Don't set PMUv3p9 FGT2 bits without PMUv3
    
    [ Upstream commit b52ef450139f5632d7e53e6fd5f5ec46c7029dac ]
    
    On a CPU with FGT2 and an IMPLEMENTATION DEFINED PMU (PMUVer 0b1111),
    __init_el2_fgt2 sets the PMUv3p9 bits in HDFGRTR2_EL2 and HDFGWTR2_EL2,
    which are RES0 there. The macro only checks that PMUVer is at least
    PMUv3p9, and 0b1111 passes.
    
    Exclude 0b1111 before the compare, as __init_el2_debug does.
    
    Fixes: 858c7bfcb35e1 ("arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9")
    Signed-off-by: Fuad Tabba <[email protected]>
    Reviewed-by: Bradley Morgan <[email protected]>
    Reviewed-by: Anshuman Khandual <[email protected]>
    Signed-off-by: Will Deacon <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single [+ + +]
Author: Vincent Jardin <[email protected]>
Date:   Mon Aug 24 23:25:30 2026 +0200

    arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single
    
    [ Upstream commit 6affdda171ca8f2e082e8c4fba56233a2f8c9910 ]
    
    IIC1_PMUX is a single bit field at RCWSR14 bit 10, so the mask for the
    two iic1 pinmux nodes was narrowed from 0x7 to 0x1 to avoid writing the
    two reserved bits next to it.
    
    With pinctrl-single,bit-per-mux the driver does not take the supplied
    mask as the bits to modify. It derives the field from the node's
    pinctrl-single,function-mask, which is 0x7 here, and then requires the
    supplied mask to match it exactly:
    
            bit_pos = __ffs(mask);                  /* 10 */
            mask_pos = ((pcs->fmask) << bit_pos);   /* 0x7 << 10 = 0x1c00 */
            submask = mask & mask_pos;              /* 0x400 */
            ...
            if (submask != mask_pos) {
                    dev_warn(pcs->dev,
                             "Invalid submask 0x%x for %pOFn at 0x%x\n",
                             submask, np, offset);
                    continue;
            }
    
    A one bit mask gives submask 0x400 against mask_pos 0x1c00, so both
    nodes are rejected and the pins are never muxed with this message:
    
      pinctrl-single 70010012c.pinmux: Invalid submask 0x400 for iic1-i2c-pins
      pinctrl-single 70010012c.pinmux: Invalid submask 0x400 for iic1-gpio-pins
    
    The values are not changed:
      - 0x0 selects IIC1
      - 0x1 << 10 selects GPIO_1[3:2].
    
    Fixes: 7a3cc49ad1fc ("arm64: dts: lx2160a: change i2c0 (iic1) pinmux mask to one bit")
    Signed-off-by: Vincent Jardin <[email protected]>
    Reviewed-by: Josua Mayer <[email protected]>
    Signed-off-by: Frank Li <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

arm64: dts: lx2160a: fix incorrect pinmux [+ + +]
Author: Vincent Jardin <[email protected]>
Date:   Mon Aug 24 23:25:29 2026 +0200

    arm64: dts: lx2160a: fix incorrect pinmux
    
    [ Upstream commit 8188a59dd6782786556b18f515090b79cb701c45 ]
    
    For gpio1 value set for pinctrl is outside the mask and so will do
    nothing.
    
    Add the missing offset for value field to be the same as the mask as
    expected.
    
    Fixes: 284ad7064aaa ("arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word")
    Suggested-by: Thibaut Collet <[email protected]>
    Reviewed-by: Josua Mayer <[email protected]>
    Signed-off-by: Vincent Jardin <[email protected]>
    Signed-off-by: Frank Li <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value [+ + +]
Author: Vincent Jardin <[email protected]>
Date:   Mon Aug 24 23:25:31 2026 +0200

    arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value
    
    [ Upstream commit f14f4dc8ea3810f8ed4f0f3ea13f8bba3e2b0f04 ]
    
    The iic5-spi3-pins node has both of its first two cells wrong.
    
    The offset selects the register within the node's reg range, where:
      0x0 is RCWSR12,
      0x4 is RCWSR13,
      0x8 is RCWSR14.
    
    An offset of 0x3 is not one of them and is not even aligned for the
    declared 32 bit register width. It is the only node in this pinmux that
    does not use 0x0, 0x4 neither 0x8.
    
    The value is wrong too:
      IIC5_PMUX is RCWSR12[11:9] and it encodes 0b000 for IIC5,
      0b001 for GPIO_1[25:24],
      0b010 for SDHC1_CLK_SYNC_OUT/IN,
      0b011 for {IIC5_SCL,IIC5_SDA} = {SPI3_SOUT,SPI3_SIN}.
    
    This node selects the last of those, so it needs 0x3, not the 0x2, which
    is the value of the neighbouring sdhc1 clock sync node it was copied
    from.
    
    Fixes: 284ad7064aaa ("arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word")
    Reviewed-by: Josua Mayer <[email protected]>
    Signed-off-by: Vincent Jardin <[email protected]>
    Signed-off-by: Frank Li <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

arm64: irq: exclude the softirq stack switch from KCOV [+ + +]
Author: Karl Mehltretter <[email protected]>
Date:   Sat Sep 26 21:13:25 2026 +0200

    arm64: irq: exclude the softirq stack switch from KCOV
    
    commit a9cd14bfb0c113f1cd77be4349784663bec71bb4 upstream.
    
    On IRQ exit, __irq_exit_rcu() drops HARDIRQ_OFFSET before calling
    invoke_softirq(). The arm64 do_softirq_own_stack() wrapper and its
    ____do_softirq() trampoline run before __do_softirq() establishes
    softirq context, so KCOV records their PCs in the interrupted task's
    coverage buffer. They also run outside softirq accounting when
    local_bh_enable() reaches do_softirq().
    
    The IRQ-exit coverage makes the KCOV boot selftest fail even after
    the scheduler and timer coverage leaks are suppressed. The generic
    softirq.o is already excluded from KCOV, but that exclusion does not
    cover the separately compiled arm64 wrappers.
    
    Exclude irq.o from KCOV instrumentation, as is already done for the
    arm64 entry code. This covers both wrappers even with compilers that
    lack the no_sanitize_coverage attribute. The softirq action functions
    remain instrumented for explicit remote coverage.
    
    Fixes: 8eb858c44b98 ("arm64: run softirqs on the per-CPU IRQ stack")
    Cc: [email protected]
    Assisted-by: LLM
    Signed-off-by: Karl Mehltretter <[email protected]>
    Signed-off-by: Will Deacon <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ASoC: adau1372: allow sleepy powerdown GPIOs [+ + +]
Author: Alvin Šipraga <[email protected]>
Date:   Tue Oct 6 14:55:56 2026 +0200

    ASoC: adau1372: allow sleepy powerdown GPIOs
    
    [ Upstream commit 64dd172bbffe6135d79a06ddad53dd2da4d8bd62 ]
    
    gpiod_set_value() emits a WARN when the GPIO provider indicates that it
    can sleep, as is typical for I2C controlled GPIO expanders. Since the
    powerdown GPIO is only manipulated in process context, use the _cansleep
    variant instead. This lets the driver use sleepy GPIOs to power off the
    chip.
    
    Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
    Signed-off-by: Alvin Šipraga <[email protected]>
    Acked-by: Nuno Sá <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes [+ + +]
Author: Alvin Šipraga <[email protected]>
Date:   Tue Oct 6 14:55:57 2026 +0200

    ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes
    
    [ Upstream commit 36d0e05815ce84266c8b138cd4f84c3feeaf15f4 ]
    
    The chip has strange power-on reset values for the registers that
    control the output ASRC and DAC source muxes - the values are actually
    marked "Reserved" in the datasheet [1]. This means that until the
    underlying kcontrols are modified, the codec will not function as
    expected.
    
    The registers in question are:
    
      register / field       reset value       valid values
    
      ASRCO_SOURCE_0_1       0x10
       ASRC_OUT_SOURCE0      0                 4 .. 16
       ASRC_OUT_SOURCE1      1                 4 .. 16
      ASRCO_SOURCE_2_3       0x10
       ASRC_OUT_SOURCE2      2                 4 .. 16
       ASRC_OUT_SOURCE3      3                 4 .. 16
      DAC_SOURCE_0_1         0x10
       DAC_SOURCE_0          0                 12 .. 13
       DAC_SOURCE_1          1                 12 .. 13
    
    Set some sane defaults during the driver probe:
    
      ADC Decimator0 -> Output ASRC0
      ADC Decimator1 -> Output ASRC1
      ADC Decimator2 -> Output ASRC2
      ADC Decimator3 -> Output ASRC3
      Input ASRC0 -> DAC0
      Input ASRC1 -> DAC1
    
    With this, the chip will behave as advertised by the default kcontrol
    state exposed by the driver.
    
    [1] https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1372.pdf
    
    Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
    Signed-off-by: Alvin Šipraga <[email protected]>
    Acked-by: Nuno Sá <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P) [+ + +]
Author: Michael Garland <[email protected]>
Date:   Mon Oct 5 01:10:32 2026 -0600

    ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P)
    
    commit d0cb7a7b2a490c381ad97f53155d02a748b60dea upstream.
    
    The Acer Aspire Go 15 (AG15-21P, board MDC Herbag2_MDU) has two PDM
    DMICs connected to the ACP. The BIOS does not set the AcpDmicConnected
    _DSD property, so the acp6x machine driver never registers the DMIC
    card. The existing Herbag_MDU entry does not match this board name, so
    add a DMI quirk for it.
    
    Tested on BIOS V1.11: the acp6x DMIC capture device is registered and
    records audio on both channels.
    
    Cc: [email protected]
    Signed-off-by: Michael Garland <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM [+ + +]
Author: Marek Szyprowski <[email protected]>
Date:   Fri Oct 2 11:21:12 2026 +0200

    ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM
    
    [ Upstream commit 7529254014764ae0b8c33d5c61a58f36c65b1a1c ]
    
    The probe function puts the device into the runtime PM active state with
    only the "iis" bus clock enabled, but it also sets priv->op_clk to the
    parent of the RCLK_SRC mux without enabling it. The runtime PM suspend
    callback disables both clocks, so the first runtime suspend after probe
    disables op_clk once more than it was enabled.
    
    On Exynos5250 Arndale both clocks resolve to the same EXYNOS_I2S_BUS gate,
    so this triggers the following warning during boot:
    
     WARNING: drivers/clk/clk.c:1270 at clk_core_disable+0xe4/0x23c, CPU#0: kworker/u8:3/45
     i2s_bus already disabled
     ...
     Workqueue: pm pm_runtime_work
     Call trace:
      ...
      clk_core_disable from clk_disable+0x28/0x34
      clk_disable from i2s_runtime_suspend+0x58/0x68 [snd_soc_i2s]
      i2s_runtime_suspend [snd_soc_i2s] from genpd_runtime_suspend+0xc4/0x298
      genpd_runtime_suspend from __rpm_callback+0x48/0x18c
      __rpm_callback from rpm_callback+0x4c/0x50
      rpm_callback from rpm_suspend+0xf4/0x718
      rpm_suspend from pm_runtime_work+0x9c/0xa0
      ...
    
    Fix this by enabling op_clk in probe right after getting it, so the clock
    state matches the runtime PM active state, and by disabling it in remove.
    
    Fixes: 48279c53fd1d ("ASoC: samsung: i2s: Prevent external abort on exynos5433 I2S1 access")
    Assisted-by: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Marek Szyprowski <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

ASoC: sdw_utils: Add codec info for CS35L62 [+ + +]
Author: Stefan Binding <[email protected]>
Date:   Wed Jul 15 13:01:34 2026 +0100

    ASoC: sdw_utils: Add codec info for CS35L62
    
    [ Upstream commit 0306d211558196e051b83e067ee4c30e1b6f94a8 ]
    
    CS35L62 is very similar to CS35L63, and uses the same driver, so we
    can use the same configuration.
    
    Signed-off-by: Stefan Binding <[email protected]>
    Signed-off-by: Richard Fitzgerald <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Stable-dep-of: 4b7f393a01f8 ("ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI")
    Signed-off-by: Sasha Levin <[email protected]>

ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI [+ + +]
Author: Richard Fitzgerald <[email protected]>
Date:   Mon Oct 5 16:52:35 2026 +0100

    ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI
    
    [ Upstream commit 4b7f393a01f88e8d03cba94cf4948652de14789b ]
    
    Change the CS35L56/57/62/63 entries in codec_info_list[] to use
    the OT25 DAI for amp feedback.
    
    The AMP feedback was incorrectly using a DAI connected to DP3,
    but that is reserved for SDCA companion amp. The correct amp
    output is DP4, which is the SDCA OT25 feedback output.
    
    Fixes: 898cd43bde307 ("ASoC: intel: sof_sdw: Add support for CS35L63 into machine driver")
    Signed-off-by: Richard Fitzgerald <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands [+ + +]
Author: Hengyu Liang <[email protected]>
Date:   Tue Sep 29 12:41:35 2026 -0400

    ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands
    
    commit bc8ce2cea5f77c4bd1a5184705e300e83546c0c4 upstream.
    
    Since commit 2e1d2e65e773 ("ata: libata-scsi: terminate deferred commands
    on time out"), atapi_qc_complete() sets SAM_STAT_CHECK_CONDITION for a
    failed command only if cmd->result is zero, so that the DID_TIME_OUT or
    DID_REQUEUE host byte of a terminated command is preserved.
    
    However, cmd->result can also be non-zero for a regular failed ATAPI
    command completed through libata EH: ata_eh_analyze_tf() calls
    ata_eh_decide_disposition(), that is, scsi_check_sense(), on the sense
    data obtained with REQUEST SENSE, and scsi_check_sense() sets the SCSI
    midlayer internal byte of the result for some sense codes, e.g.
    SCSIML_STAT_TGT_FAILURE for ILLEGAL REQUEST with ASC 0x20 (INVALID
    COMMAND OPERATION CODE) or 0x24 (INVALID FIELD IN CDB), or
    SCSIML_STAT_MED_ERROR for MEDIUM ERROR with ASC 0x11 (UNRECOVERED READ
    ERROR). For such commands, atapi_qc_complete() keeps the result as is and
    the command completes with a GOOD status byte, even though it failed and
    valid sense data is available.
    
    As a result, passthrough users see these failed ATAPI commands as
    successful. For example, with the emulated IDE CD-ROM drive of QEMU and
    no medium loaded, a PLAY AUDIO MSF command issued with SG_IO completes
    with status 0x00 (and no DRIVER_SENSE) instead of 0x02 (CHECK CONDITION)
    with sense key ILLEGAL REQUEST, ASC/ASCQ 0x20/0x00, and the CDROM ioctls
    CDROMPLAYTRKIND, CDROMSUBCHNL, CDROMPAUSE, CDROMRESUME, CDROMPLAYMSF and
    CDROM_GET_MCN return 0 instead of -ENOMEDIUM or -EOPNOTSUPP.
    
    Fix this by setting the status byte to SAM_STAT_CHECK_CONDITION whenever
    the host byte is not set. Use set_status_byte() rather than overwriting
    the whole result, so that the SCSI midlayer internal byte set by
    scsi_check_sense() is preserved, as ata_scsi_qc_complete() already does
    for ATA commands.
    
    Fixes: 2e1d2e65e773 ("ata: libata-scsi: terminate deferred commands on time out")
    Cc: [email protected]
    Suggested-by: Niklas Cassel <[email protected]>
    Signed-off-by: Hengyu Liang <[email protected]>
    Reviewed-by: Damien Le Moal <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Signed-off-by: Niklas Cassel <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
bareudp: set the inner protocol to the protocol of the packet [+ + +]
Author: Haishuang Yan <[email protected]>
Date:   Fri Oct 2 23:30:39 2026 +0800

    bareudp: set the inner protocol to the protocol of the packet
    
    [ Upstream commit c57b2e60d4bf29707c51b39ed3bacbcce2f3ba2e ]
    
    bareudp_xmit_skb() sets the inner protocol of the skb to the configured
    ethertype, and bareudp6_xmit_skb() does not set it at all. The inner
    protocol is used by skb_udp_tunnel_segment() to segment the inner packet
    when GSO has to be done in software, for instance when the lower device
    does not offload the checksum.
    
    With multiproto, an IPv4 device also carries IPv6, so the IPv6 header
    is parsed as an IPv4 one. With IPv6 underlay, the inner protocol is
    whatever the skb had before. In both cases segmentation fails and the
    packets are dropped. With veth tx checksum offload disabled, iperf3 TCP
    over bareudp gets about 10 Mbit/s with thousands of retransmits instead
    of about 700 Mbit/s for IPv6 over IPv4 and for both families over IPv6,
    while IPv4 over IPv4 works.
    
    At this point skb->protocol is the protocol of the inner packet, which
    bareudp_xmit() has already checked against the configuration, so use it
    on both paths.
    
    Fixes: 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
    Fixes: 4b5f67232d95 ("net: Special handling for IP & MPLS.")
    Signed-off-by: Haishuang Yan <[email protected]>
    Reviewed-by: Willem de Bruijn <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
Bluetooth: btintel_pcie: Add shared HW reset for clean start [+ + +]
Author: Sai Teja Aluvala <[email protected]>
Date:   Tue Sep 29 11:42:33 2026 +0530

    Bluetooth: btintel_pcie: Add shared HW reset for clean start
    
    [ Upstream commit 1465494e8d07426fa41c0021530cccb2a1ac38fa ]
    
    Reset shared Bluetooth hardware after mapping the BAR and before setting
    up MSI-X interrupts, so stale device state is cleared before IRQ handlers
    and interrupt masks are configured.
    
    Propagate reset errors so probe aborts rather than continuing when the
    reset fails.
    
    Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
    Signed-off-by: Sai Teja Aluvala <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

Bluetooth: btintel_pcie: fix TX descriptor bounds check [+ + +]
Author: Ravindra <[email protected]>
Date:   Tue Sep 29 12:26:41 2026 +0530

    Bluetooth: btintel_pcie: fix TX descriptor bounds check
    
    [ Upstream commit baa53af641c9e3644e717b8dfd1b95a55a0c111b ]
    
    btintel_pcie_prepare_tx() uses tfd_index to access the TFD and data
    buffer arrays before the index is advanced modulo txq->count. An index
    equal to txq->count is one past the end of both arrays, so reject it in
    the bounds check.
    
    Fixes: 6e65a09f9275 ("Bluetooth: btintel_pcie: Add *setup* function to download firmware")
    Signed-off-by: Ravindra <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

Bluetooth: btintel_pcie: use managed IRQ teardown [+ + +]
Author: Runyu Xiao <[email protected]>
Date:   Wed Sep 30 15:44:53 2026 +0800

    Bluetooth: btintel_pcie: use managed IRQ teardown
    
    commit 25016fe8c1ed0fccae107bd629089139ffbafe08 upstream.
    
    The PCIe driver registers its MSI-X handlers with
    devm_request_threaded_irq(), but remove() uses free_irq() directly. The
    devres actions then retain registrations and attempt to release them again
    during device cleanup.
    
    Use devm_free_irq() for the remove path and for already registered vectors
    when a later setup request fails. This removes the managed resource at the
    same time as the IRQ is released and keeps MSI-X vector teardown ordered
    after IRQ ownership is gone.
    
    Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
    Cc: [email protected]
    Assisted-by: LLM
    Signed-off-by: Runyu Xiao <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: hci_sock: Serialize dead-device detachment [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Mon Oct 5 00:24:42 2026 +0800

    Bluetooth: hci_sock: Serialize dead-device detachment
    
    commit 381a0925c556a8d91a80a9b9e3e86651d60ffee3 upstream.
    
    Rebinding an HCI socket after its controller is unregistered can race
    monitor control replay and crash the kernel. hci_sock_bind() clears
    hci_pi(sk)->hdev and drops the device reference under only the socket
    lock, whereas send_monitor_control_replay() holds hci_sk_list.lock for
    reading.
    
    Replay can observe a non-NULL hdev, then bind can clear it and drop the
    last reference before create_monitor_ctrl_open() reads hdev->id. This
    can cause a NULL pointer dereference if the pointer is reloaded, or a
    use-after-free if the old pointer is retained.
    
    The kernel reported:
    
      KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f]
      RIP: 0010:create_monitor_ctrl_open+0x579/0x800
      Call Trace:
       hci_sock_bind+0xd96/0x1190
       __sys_bind+0x166/0x200
       __x64_sys_bind+0x6d/0xb0
       do_syscall_64+0xdd/0x4a0
       entry_SYSCALL_64_after_hwframe+0x77/0x7f
    
    The same missing serialization lets hci_send_to_sock() select a socket
    for the old device and queue its frame after bind has detached the socket
    or installed a new binding.
    
    Take hci_sk_list.lock for writing when clearing the device pointer and
    resetting the socket state. This waits for existing replay and delivery
    readers to finish before detachment and prevents later readers from
    using the old binding. Keep hci_dev_put() outside the critical section
    because the final device release can sleep.
    
    Fixes: e04480920d1e ("Bluetooth: defer cleanup of resources in hci_unregister_dev()")
    Cc: [email protected]
    Assisted-by: GPT-6 Astra
    Signed-off-by: Chengfeng Ye <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: hci_sync: Fix command skb lifetime during scan setup [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Mon Oct 5 00:26:12 2026 +0800

    Bluetooth: hci_sync: Fix command skb lifetime during scan setup
    
    commit 9af12272061d206af8bc3e40215cb694421ab73a upstream.
    
    During PA sync scan setup, hci_le_set_ext_scan_param_sync() gets the
    address used for the PA_LINK lookup from hci_sent_cmd_data(). The
    returned pointer borrows storage from sent_cmd or req_skb, without
    holding a reference to either skb.
    
    The scan worker runs on req_workqueue while hci_cmd_work() runs on the
    separate device workqueue. After the scan worker loads sent_cmd, the
    command worker can free and replace it before hci_sent_cmd_data()
    dereferences the skb. The command payload can also be freed between
    returning from the helper and comparing the address. The connection
    lookup's RCU critical section does not protect the command skb.
    
    KASAN reported:
    
      BUG: KASAN: slab-use-after-free in hci_sent_cmd_data+0x27c/0x2f0
      Workqueue: hci0 hci_cmd_sync_work
      Call Trace:
       hci_sent_cmd_data+0x27c/0x2f0
       hci_le_set_scan_param_sync+0x43a/0x850
       hci_passive_scan_sync+0xb09/0x1460
       hci_update_passive_scan_sync+0x47c/0x6e0
       hci_le_pa_create_sync+0x200/0xa70
       hci_cmd_sync_work+0x13c/0x290
    
      Allocated by task 95:
       skb_clone+0x13f/0x340
       hci_cmd_work+0x2a9/0x7e0
    
      Freed by task 95:
       kmem_cache_free+0xba/0x3a0
       hci_cmd_work+0x29c/0x7e0
    
    Use hdev->lock to serialize the address snapshot with sent_cmd
    replacement. Protect req_skb replacement and completion cleanup with
    the same lock because the helper falls back to that skb. Copy the
    address before releasing the lock and use the copy for the existing
    RCU-protected connection lookup. Release the mutex before sending or
    waiting for commands, preserving the lookup and completion ordering.
    
    Fixes: 22cbf4f84c00 ("Bluetooth: hci_sync: Use QoS to determine which PHY to scan")
    Cc: [email protected]
    Assisted-by: GPT-6 Astra
    Signed-off-by: Chengfeng Ye <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: ISO: Reject concurrent BIS listener setup [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Mon Oct 5 00:25:48 2026 +0800

    Bluetooth: ISO: Reject concurrent BIS listener setup
    
    commit 555ff78fa719f50ff4cdbdb40aa1acc6e8e327d3 upstream.
    
    iso_sock_listen() drops the socket lock before calling iso_listen_bis()
    to preserve the hdev->lock ordering. Two concurrent listen() calls on
    the same broadcast socket can therefore both observe BT_BOUND. Caller
    A can attach connA and release the locks, then caller B can acquire
    them and attach connB before A publishes BT_LISTEN.
    
    __iso_chan_add() checks whether connB already has a socket, but not
    whether the socket already has a connection. The second attachment
    overwrites iso_pi(sk)->conn, leaking the connA reference and leaving
    connA->sk intact. Socket teardown follows connB, so later events on
    connA can cause a stale socket access.
    
    Recheck BT_BOUND and require iso_pi(sk)->conn to be NULL after taking
    both the HCI device and socket locks in iso_listen_bis(). The connection
    check also covers the interval between attachment and publication of
    BT_LISTEN. Reject a competing setup with -EBADFD through the existing
    unlock path before allocating another connection.
    
    A recorded KASAN report from an instrumented kernel shows:
    
      BUG: KASAN: slab-use-after-free in iso_sock_hold+0x119/0x1f0
      Call Trace:
       iso_sock_hold+0x119/0x1f0
       iso_conn_del+0xe4/0x270
       hci_disconn_complete_evt+0x351/0x8c0
       hci_event_packet+0x71b/0xb20
       hci_rx_work+0x293/0x730
    
      Allocated by task 93:
       sk_prot_alloc+0x113/0x220
       sk_alloc+0x2b/0x6d0
       bt_sock_alloc+0x29/0x370
       iso_sock_alloc.constprop.0+0x19/0x300
       iso_sock_create+0x94/0x100
    
      Freed by task 93:
       kfree+0x121/0x3c0
       __sk_destruct+0x42b/0x540
       iso_sock_release+0x29d/0x340
       __sock_release+0xa1/0x260
       sock_close+0x10/0x20
    
    Fixes: 168e28305b87 ("Bluetooth: iso: Fix circular lock in iso_listen_bis")
    Cc: [email protected]
    Assisted-by: GPT-6 Astra
    Signed-off-by: Chengfeng Ye <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: ISO: Serialize concurrent connect calls [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Mon Oct 5 15:50:31 2026 +0800

    Bluetooth: ISO: Serialize concurrent connect calls
    
    commit e32d80293a0e1a160d5e5101daa8c82148c07510 upstream.
    
    iso_sock_connect() checks the socket state before taking the socket lock
    and drops the lock again before setting up a connection. Two callers can
    both pass the admission check while the socket is open or bound.
    
    Caller A can copy its destination for route selection, then caller B can
    replace the socket destination before A binds or connects the CIS. A
    then uses B's destination with the route selected for its own request.
    B can also proceed after A attaches a connection and sets BT_CONNECT.
    For deferred BIS setup, B can bind a second BIS and overwrite
    iso_pi(sk)->conn, leaving the first connection's reference and conn->sk
    back-pointer stranded. Concurrent CIS connects can likewise replace the
    socket's connection. Later teardown only detaches the current connection,
    so a callback on the old connection can race with socket release and
    access a freed socket.
    
    KASAN reported:
    
      BUG: KASAN: slab-use-after-free in iso_sock_hold+0xf7/0x1b0
      Call Trace:
       iso_sock_hold+0xf7/0x1b0
       iso_conn_del+0x7b/0x1d0
       iso_connect_cfm+0x186/0x16a0
       hci_conn_failed+0x154/0x280
       hci_abort_conn_sync+0x3dc/0x7d0
       hci_cmd_sync_work+0x173/0x300
    
      Allocated by task 121:
       sk_alloc+0x2b/0x6d0
       bt_sock_alloc+0x29/0x370
       iso_sock_alloc.constprop.0+0x19/0x300
       iso_sock_create+0x94/0x100
    
      Freed by task 121:
       kfree+0x121/0x3c0
       __sk_destruct+0x42b/0x540
       iso_sock_release+0x29d/0x340
       __sock_release+0xa1/0x260
    
    Check admission under the socket lock and mark the connect operation in
    progress before publishing its destination. Keep that flag set across
    route lookup and connection setup, rejecting another connect with
    -EBADFD before it can change the destination or attach a connection.
    Clear the flag after either helper returns, including on failure, so a
    failed setup can be retried.
    
    A separate flag is needed because the socket lock must be released before
    acquiring the HCI device lock, while BT_CONNECT requires an attached
    connection. Keep the existing state transitions and the deferred CIS
    completion through iso_sock_recvmsg().
    
    Reject an existing socket attachment in __iso_chan_add() before taking
    a new reference or publishing either pointer, so every caller preserves
    the connection association. Keep the same-socket, same-connection success
    case for deferred CIS setup. Reject an attached socket before BIS setup
    so a reusable BIS is not claimed before the attachment is rejected.
    
    In CIS setup, reject a different HCI connection before iso_conn_add()
    and drop the per-attempt HCI hold directly. An unowned iso_conn may still
    carry another reference after detachment, so its destruction cannot be
    relied on to release that hold.
    
    iso_listen_bis() creates a fresh PA HCI/ISO pair under the device lock,
    so the temporary iso_conn_put() frees the ISO candidate and drops its
    HCI hold on rejection. iso_conn_ready() uses a freshly allocated,
    unpublished child with no connection, making the socket-side rejection
    unreachable.
    
    Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
    Cc: [email protected]
    Suggested-by: Pauli Virtanen <[email protected]>
    Assisted-by: GPT-6 Astra
    Signed-off-by: Chengfeng Ye <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: MGMT: Fix status of pending commands flushed on power off [+ + +]
Author: Iaroslav Voitovych <[email protected]>
Date:   Thu Sep 24 19:11:58 2026 +0200

    Bluetooth: MGMT: Fix status of pending commands flushed on power off
    
    commit 86ef0f58bdecdedb3a1240971c56d71b7e4ce3fc upstream.
    
    cmd_complete_rsp() receives a struct cmd_lookup and, for a pending
    command that has no cmd_complete callback, falls through to
    cmd_status_rsp(cmd, data). cmd_status_rsp() reads data as a u8 *, so
    the status sent comes from the first byte of match->sk's
    representation, not from match->mgmt_status.
    
    commit f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on
    mgmt_index_removed") changed the callers' data from &status to &match
    and updated the cmd_complete branch to match->mgmt_status, but left
    the fall-through passing data unchanged.
    
    In mgmt_index_removed() match->sk is NULL, so every such command is
    answered with status 0x00 (Success) instead of
    MGMT_STATUS_INVALID_INDEX. In __mgmt_power_off() it is NULL too,
    unless a Set Powered command was pending: then settings_rsp() has
    stored that command's socket in match->sk, and the byte sent comes
    from the socket pointer. Either way the status the caller set,
    MGMT_STATUS_NOT_POWERED (or MGMT_STATUS_INVALID_INDEX when the device
    is being unregistered), is lost.
    
    Pass the status the callers set.
    
    This was seen on a QCA9377 laptop: bluetoothd's Start Discovery,
    pending when the adapter was powered off, was answered with Command
    Status 0x00 and no parameters, and bluetoothd 5.72 crashed on the
    zero-length success. BlueZ master has since added the length check
    on that path ("adapter: Fix crash on short start discovery reply",
    BlueZ a734b06059cb), but userspace should still be told Not Powered,
    not Success.
    
    Tested on Ubuntu 7.0.0-31 with a virtual controller (hci_vhci):
    power off is held in HCI Write Scan Enable while a Start Discovery is
    submitted, and the flush answers it with status 0x00 before this
    change and 0x0f (Not Powered) after.
    
    Fixes: f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on mgmt_index_removed")
    Cc: [email protected]
    Signed-off-by: Iaroslav Voitovych <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex [+ + +]
Author: Mikhail Gavrilov <[email protected]>
Date:   Tue Sep 29 17:22:26 2026 +0500

    Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex
    
    commit ac022970e9fb0a5f7e7d1f6c8e104c1ed924dd1c upstream.
    
    An RFCOMM connect() issued while a BR/EDR link is being authenticated
    makes lockdep report a circular dependency, and the reported cycle is a
    real AB/BA between rfcomm_mutex and hdev->lock.
    
    rfcomm_security_cfm() is called from the HCI event path, which already
    holds hdev->lock:
    
      hci_rx_work()
        hci_event_packet()
          hci_cc_read_enc_key_size()   [hdev->lock]
            hci_encrypt_cfm()          [hci_cb_list_lock]
              rfcomm_security_cfm()    [rfcomm_mutex]
    
    while an RFCOMM connect() from userspace takes the same two locks the
    other way round:
    
      rfcomm_sock_connect()
        rfcomm_dlc_open()              [rfcomm_mutex]
          __rfcomm_dlc_open()
            rfcomm_session_create()
              kernel_connect()
                l2cap_sock_connect()
                  l2cap_chan_connect() [hdev->lock]
    
      WARNING: possible circular locking dependency detected
      kworker/u131:1/1128 is trying to acquire lock:
      rfcomm_mutex, at: rfcomm_security_cfm+0x31/0x3e0 [rfcomm]
      but task is already holding lock:
      hci_cb_list_lock, at: hci_cc_read_enc_key_size+0x1d2/0xcc0
      Chain exists of:
        rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock
    
    hci_auth_complete_evt() and hci_encrypt_change_evt() reach the callback
    the same way.
    
    Both orders have to be seen in the same boot, which is why a BR/EDR
    connection alone is not enough to show it: a session set up by the
    remote side is created by rfcomm_accept_connection() in krfcommd, which
    calls kernel_accept() and never takes hdev->lock under rfcomm_mutex.
    Connecting a device that authenticates and encrypts the link and then
    calling connect() on an RFCOMM socket towards any address - the connect
    does not have to succeed, the order is recorded before the page timeout
    - reports it every time.
    
    Only the session socket has to be connected with the lock held, and it
    does not: nothing else can see the socket before it is put on the
    session list.  So connect it first and take rfcomm_mutex afterwards,
    which removes the rfcomm_mutex -> hdev->lock order for good, rather
    than keeping the HCI event path out of rfcomm_mutex.
    
    rfcomm_session_create() becomes rfcomm_session_connect(), which returns
    the connected socket without touching the session list, and
    rfcomm_dlc_open() adds the session once it holds the lock again.  If
    another opener added a session for the same pair while this socket was
    connecting, that session is used and this socket is dropped.
    __rfcomm_dlc_open() now takes the session it should use, and its state
    check runs after the lock is re-acquired, so a DLC that was opened or
    closed in the meantime is still handled.
    
    Over an existing ACL link the connection can complete before the
    session reaches the list, and the wakeup from the socket callback is
    then lost, so krfcommd is woken once the session is visible.
    
    Connecting without the lock opens a window in which the socket can be
    closed.  The DLC is not on a session yet, so rfcomm_dlc_close() finds
    nothing to do and returns without touching it, and rfcomm_dlc_open()
    would then attach a DLC whose owner is gone.  rfcomm_dlc_close() now
    marks such a DLC with RFCOMM_CLOSED, and rfcomm_dlc_open() checks the
    mark once it holds rfcomm_mutex again and drops the socket instead of
    attaching the DLC.  The mark is cleared when an open starts, so a DLC
    that is reused is not affected.  This covers both callers of
    rfcomm_dlc_open(), the socket and the tty layer.
    
    Fixes: 759c185d0bbd ("Bluetooth: RFCOMM: serialize security confirmation handling")
    Suggested-by: Pauli Virtanen <[email protected]>
    Reported-by: Pauli Virtanen <[email protected]>
    Closes: https://lore.kernel.org/linux-bluetooth/[email protected]/
    Reported-by: [email protected]
    Closes: https://lore.kernel.org/linux-bluetooth/[email protected]/
    Reported-by: Jiaming Zhang <[email protected]>
    Closes: https://lore.kernel.org/all/CANypQFabseTuRiyz2pGkc_Qj0moGDnY7KEp1qdTOqkw6gAL3hw@mail.gmail.com/
    Cc: [email protected]
    Signed-off-by: Mikhail Gavrilov <[email protected]>
    Tested-by: [email protected]
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown [+ + +]
Author: Palla Raghunath <[email protected]>
Date:   Fri Oct 2 08:07:52 2026 +0100

    Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown
    
    commit 08e90633377f1b2567ab5ad6810b74c552246a07 upstream.
    
    syzbot hit a NULL pointer dereference in rfcomm_dev_shutdown() when an
    RFCOMM tty is closed.
    
    rfcomm_dev_add() puts the new device on rfcomm_dev_list first and only
    then registers the tty device and saves it in dev->tty_dev. If that
    registration fails, dev->tty_dev is never set at all. The device can be
    looked up in the meantime, so an open() of /dev/rfcommN gets through
    rfcomm_tty_install() and attaches to it. When that tty is closed again,
    rfcomm_dev_shutdown() uses dev->tty_dev without checking it:
    
      Oops: general protection fault, probably for non-canonical address
      KASAN: null-ptr-deref in range [0x0000000000000040-0x0000000000000047]
      RIP: 0010:rfcomm_dev_shutdown+0x48/0xb0 net/bluetooth/rfcomm/tty.c:131
      Call Trace:
       tty_port_shutdown+0x1bf/0x220 drivers/tty/tty_port.c:372
       tty_port_close+0x4e/0x150 drivers/tty/tty_port.c:705
       tty_release+0x359/0x1670 drivers/tty/tty_io.c:1718
       __fput+0x418/0xa50 fs/file_table.c:512
    
    rfcomm_dev_destruct() already copes with a NULL dev->tty_dev. Add the
    same check to rfcomm_dev_shutdown(), so the tty device is only moved
    when it was actually registered.
    
    Fixes: cad348a17e17 ("Bluetooth: Implement .activate, .shutdown and .carrier_raised methods")
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=4a807caf7680652d53b6
    Cc: [email protected]
    Signed-off-by: Palla Raghunath <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: RFCOMM: free the skb when the DLC has no owner [+ + +]
Author: Maxim Skokov <[email protected]>
Date:   Tue Sep 15 10:00:46 2026 +0300

    Bluetooth: RFCOMM: free the skb when the DLC has no owner
    
    commit 9d1afbf60ed53c5b051cd124153e0ae3078c8b93 upstream.
    
    rfcomm_recv_data() hands the skb to d->data_ready() and returns 0
    without freeing it, so the callback owns the skb from that point on.
    The tty implementation frees it when the DLC has been detached from its
    device:
    
      static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc,
                                        struct sk_buff *skb)
      {
              struct rfcomm_dev *dev = dlc->owner;
    
              if (!dev) {
                      kfree_skb(skb);
                      return;
              }
    
    The socket implementation returns without freeing it, and the skb is
    leaked.
    
    A connected DLC can have no owner: rfcomm_sock_destruct() clears
    d->owner, while the DLC itself stays on the session until it is closed.
    Data frames that arrive in that window still find d->state ==
    BT_CONNECTED in rfcomm_recv_data() and are handed to the callback, one
    leaked skb each.
    
    The leak does not stop on its own either.  The remote runs out of
    credits only once RFCOMM_RX_THROTTLED is set, and for a socket the only
    place that sets it is rfcomm_sk_data_ready() itself, below the return.
    rfcomm_process_dlcs() keeps granting credits, so the remote keeps
    sending and the leak keeps growing.
    
    Free the skb, as the tty side does.
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reported-by: Mikhail Gavrilov <[email protected]>
    Closes: https://lore.kernel.org/linux-bluetooth/CABXGCsPe5wykd8Aj-hm+SJ7SGQyb8yoGNnx3XDpPmBathj+EGg@mail.gmail.com/
    Cc: [email protected]
    Signed-off-by: Maxim Skokov <[email protected]>
    Assisted-by: Claude:claude-opus-5
    Reviewed-by: Mikhail Gavrilov <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata() [+ + +]
Author: Aldo Ariel Panzardo <[email protected]>
Date:   Sat Sep 26 18:21:45 2026 -0300

    Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()
    
    commit 816fb1590a4c8cf8d05cd076057616be02e276f0 upstream.
    
    sco_recv_scodata() upgrades the weak hcon->sco_data back-pointer to a
    strong reference under hdev->lock:
    
        hci_dev_lock(hdev);
        hcon = hci_conn_hash_lookup_handle(hdev, handle);
        ...
        conn = sco_conn_hold_unless_zero(hcon->sco_data);
        hci_dev_unlock(hdev);
    
    but the pointer is cleared from the other side without that lock. When
    the last sco_conn reference is dropped, sco_conn_free() ran
    
        conn->hcon->sco_data = NULL;
    
    with no hdev->lock held, so the RX path could read hcon->sco_data and
    call kref_get_unless_zero() on an sco_conn that was concurrently freed:
    
        BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero+0xbe/0x160
        Write of size 4 by task kworker/u17:0
        Workqueue: hci0 hci_rx_work
        Call Trace:
         sco_conn_hold_unless_zero+0xbe/0x160
         sco_recv_scodata+0x13f/0x490
         hci_rx_work+0x3af/0x730
    
    kref_get_unless_zero() only guards against a zero refcount, not against
    the backing memory already being freed.
    
    Give hcon->sco_data an actual reference on the sco_conn it points to, so
    the object cannot be freed while the pointer is still installed, and only
    clear and drop it from sco_conn_del(), which runs under hdev->lock (its
    callers, sco_connect_cfm() and sco_disconn_cfm(), hold it). The reader in
    sco_recv_scodata() also takes hdev->lock, so the store and the read are
    now serialised: the RX path either observes NULL or a reference that is
    guaranteed to stay valid until it drops its own.
    
    sco_conn_add() no longer hands its kref_init() reference to the caller as
    the connection's only reference; that initial reference is the one owned
    by hcon->sco_data, and callers get their own via sco_conn_hold().
    
    Because the sco_conn can now outlive the socket (the association keeps it
    alive until the link goes down), the hci_conn can no longer be dropped
    from sco_conn_free() without regressing socket close: closing a connected
    SCO socket must still tear the link down. Move hci_conn ownership to the
    socket instead: __sco_chan_add() takes an hci_conn reference and it is
    released from sco_chan_del() and sco_sock_destruct(), exactly once. The
    sco_conn no longer owns an hci_conn reference, so sco_conn_add() stops
    consuming one and sco_connect() drops the hci_connect_sco() reference on
    every path; sco_connect_cfm() no longer needs its hci_conn_hold() dance.
    
    Fixes: e6720779ae61 ("Bluetooth: SCO: Use kref to track lifetime of sco_conn")
    Cc: [email protected]
    Suggested-by: Pauli Virtanen <[email protected]>
    Signed-off-by: Aldo Ariel Panzardo <[email protected]>
    Signed-off-by: Luiz Augusto von Dentz <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
bnxt_en: Add bnxt_clear_bars() helper [+ + +]
Author: Michael Chan <[email protected]>
Date:   Mon Oct 5 13:42:44 2026 -0700

    bnxt_en: Add bnxt_clear_bars() helper
    
    [ Upstream commit 8f5d59b9cfa69beab3b52cca621bb301c5af98aa ]
    
    In bnxt_io_slot_reset(), we clear the 6 BAR registers.  Add a helper
    function to do that.  The helper will be used again in the next patch.
    
    Reviewed-by: Kalesh AP <[email protected]>
    Reviewed-by: Somnath Kotur <[email protected]>
    Reviewed-by: Joe Damato <[email protected]>
    Signed-off-by: Pavan Chebbi <[email protected]>
    Signed-off-by: Michael Chan <[email protected]>
    Reviewed-by: Jacob Keller <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Stable-dep-of: 386f887c8290 ("bnxt_en: Fix driver init in kdump kernel")
    Signed-off-by: Sasha Levin <[email protected]>

bnxt_en: fix DMA mapping length for padded small packets [+ + +]
Author: Eric Dumazet <[email protected]>
Date:   Wed Oct 7 07:17:47 2026 +0200

    bnxt_en: fix DMA mapping length for padded small packets
    
    [ Upstream commit a51d233ccd4889aadb71dace863525cc2b00271e ]
    
    Stefan Fleischmann reported Intel IOMMU DMA Read faults on BCM57412
    NetXtreme-E NICs when transmitting packets on VLAN/macvlan interfaces:
    
      DMAR: [DMA Read NO_PASID] Request device [18:00.0] fault addr 0xfc499000
            [fault reason 0x06] PTE Read access is not set
      bnxt_en 0000:18:00.0 eno1np0: Abandoning msg {0xb4 0x41a} len: 0 due to firmware status: 0x2000001
      ...
      NETDEV WATCHDOG: eno1np0 (bnxt_en): transmit queue 0 timed out
    
    The fault address (0xfc499000) is on an exact 4KB page boundary,
    pointing to a DMA read buffer overrun.
    
    In bnxt_start_xmit(), packets smaller than BNXT_MIN_PKT_SIZE (52 bytes),
    such as 42-byte untagged ARP frames, are padded:
    
        if (length < BNXT_MIN_PKT_SIZE) {
            pad = BNXT_MIN_PKT_SIZE - length;
            if (skb_pad(skb, pad))
                goto tx_kick_pending;
            length = BNXT_MIN_PKT_SIZE;
        }
    
        mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE);
        ...
        dma_unmap_len_set(tx_buf, len, len);
    
    However, 'len' was initialized earlier to skb_headlen(skb) (e.g. 42 bytes)
    and is left unadjusted after padding. Consequently, dma_map_single() and
    dma_unmap_len_set() map and track only 42 bytes.
    
    Later, the hardware TX buffer descriptor is programmed with the padded length:
    
        txbd->tx_bd_len_flags_type =
            cpu_to_le32(((len + pad) << TX_BD_LEN_SHIFT) | flags |
                        TX_BD_FLAGS_PACKET_END);
    
    The NIC DMA engine is thus instructed to read 52 bytes from a region where
    only 42 bytes were DMA-mapped. If skb->data ends near the boundary of a 4KB
    page (within 'pad' bytes of the next page), the hardware DMA read overruns
    into the unmapped adjacent page, triggering an IOMMU fault.
    
    This issue was exposed after commit 447cbe95ebb9 ("vlan: fix skb_under_panic
    and races when toggling HW VLAN offload") because reserving extra VLAN
    headroom rounded LL_RESERVED_SPACE from 48 up to 64 bytes, shifting skb->data
    offsets and potentially causing small frames to land right against page
    boundaries.
    
    Fix this by using skb_put_padto(skb, BNXT_MIN_PKT_SIZE) in
    bnxt_start_xmit(), before skb_shinfo(skb)->nr_frags is sampled,
    because padding might linearize the skb.
    This ensures skb->len and skb_headlen(skb) reflect the padded size so
    that dma_map_single() maps the full buffer and the descriptor length is
    consistent. This also removes the temporary 'pad' variable and masking logic.
    
    The padding is done after the SW USO branch, otherwise
    bnxt_sw_udp_gso_xmit() would account the padding as UDP payload
    and send it in extra segments.
    
    Note that SW USO segments are still not padded: with IPv4, a segment
    carrying less than 10 bytes of UDP payload (small gso_size, or a short
    last segment) is sent as a frame shorter than BNXT_MIN_PKT_SIZE.
    This is a separate issue, left for a followup patch.
    
    Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.")
    Cc: [email protected]
    Reported-by: Stefan Fleischmann <[email protected]>
    Closes: https://lore.kernel.org/netdev/20261004122616.56714cbd@nargothrond/
    Signed-off-by: Eric Dumazet <[email protected]>
    Reviewed-by: Michael Chan <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>
bnxt_en: Fix driver init in kdump kernel [+ + +]
Author: Michael Chan <[email protected]>
Date:   Mon Oct 5 13:42:45 2026 -0700

    bnxt_en: Fix driver init in kdump kernel
    
    [ Upstream commit 386f887c8290f0747dd0180e98ec7a82811bc506 ]
    
    Fix and strengthen the FLR sequence when initializing in the kdump
    kernel.  If the NIC is behind a PCIe switch in synthetic (smart)
    mode, the switch may need to see that the BARs have been initialized
    before it will pass mem read/write TLPs to the NIC.
    
    On a Dell system with a PEX89144 PCIe switch, echo c > /proc/sysrq-trigger
    will trigger fatal AER without this patch:
    
    bnxt_en 0000:67:00.0: enabling device (0000 -> 0002)
    [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 5
    [Hardware Error]: event severity: recoverable
    [Hardware Error]:  Error 0, type: fatal
    [Hardware Error]:   section_type: PCIe error
    [Hardware Error]:   port_type: 5, upstream switch port
    ...
    
    Add a new bnxt_kdump_reset() to do the expanded FLR sequence in the
    kdump kernel.  We now disable bus master and memory, save the PCI
    state, do the FLR, clear the BARs, and restore the PCI state.  The
    BARs have to be cleared to ensure that they get re-initialized and
    visible to the PCIe switch.
    
    Since it is the kdump kernel, we make every effort to continue in
    the best possible way even if pci_save_state() or pcie_flr() returns
    error.  After FLR, we poll for an additional 5 seconds before
    aborting in case the device is not properly returning CRS.  This is
    similar to the 5-second wait in bnxt_io_slot_reset().
    
    Fixes: 8743db4a9acf ("bnxt_en: Issue PCIe FLR in kdump kernel to cleanup pending DMAs.")
    Reviewed-by: Kalesh AP <[email protected]>
    Signed-off-by: Pavan Chebbi <[email protected]>
    Signed-off-by: Michael Chan <[email protected]>
    Reviewed-by: Jacob Keller <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

bnxt_en: Re-write the BARs following any type of PCIe errors [+ + +]
Author: Pavan Chebbi <[email protected]>
Date:   Mon Oct 5 13:42:46 2026 -0700

    bnxt_en: Re-write the BARs following any type of PCIe errors
    
    [ Upstream commit 2e52da27096d9dbc487f303bbc10d44ad837a8c4 ]
    
    Currently the driver zeroes the BARs only when fatal PCIe errors
    are reported so that pci_restore_state() restores it.  However
    firmware handles both fatal and non-fatal errors the same way when
    it sees the slot reset resulting from the PCI_ERS_RESULT_NEED_RESET
    return code from the driver.  This means that we must re-write the
    BARs post recovery even during non-fatal errors.  Otherwise we will
    see that every MMIO access returns all-ones and the firmware appears
    dead.
    
    Zero-out the BARs during PCIe error recovery regardless of type of
    PCIe error, and make the wait after the hot reset unconditional.
    
    Disable memory decode and bus mastering before rewriting the BARs so
    the device doesn't decode a half-updated address, bailing out if
    config space is still inaccessible.  Defer pci_enable_device() until
    after the BAR rewrite and restore, so the device isn't re-enabled
    while its BARs are still being rewritten, then re-enable the device
    and re-assert bus mastering.  Guard the same Command register cleanup
    on the re-enable failure path against an inaccessible device.
    
    Skip re-enabling the device in bnxt_io_slot_reset() if it is already
    enabled, so enable_cnt does not go unbalanced.  A concurrent
    bnxt_fw_reset_task() can also be re-enabling the same device in its
    ENABLE_DEV state, so guard that call the same way.
    
    Fixes: f75d9a0aa967 ("bnxt_en: Re-write PCI BARs after PCI fatal error.")
    Reviewed-by: Kalesh AP <[email protected]>
    Reviewed-by: Scott Branden <[email protected]>
    Signed-off-by: Pavan Chebbi <[email protected]>
    Signed-off-by: Michael Chan <[email protected]>
    Reviewed-by: Jacob Keller <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
bonding: fix the program leak when XDP is replaced [+ + +]
Author: Jakub Kicinski <[email protected]>
Date:   Wed Sep 30 18:26:39 2026 -0700

    bonding: fix the program leak when XDP is replaced
    
    [ Upstream commit 184b5ddf82d45d6f75cc83719a2e453392512bd2 ]
    
    We need to release the reference on the old BPF prog, whether
    we are going to no-prog, or replacing the prog with another.
    
    Spotted by AI while running tests for the propagation series
    (leaked programs were accumulating). Selftest will come in
    the net-next series to avoid conflicts.
    
    Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver")
    Fixes: 6d5f1ef83868 ("bonding: Fix negative jump label count on nested bonding")
    Acked-by: Daniel Borkmann <[email protected]>
    Reviewed-by: Jiayuan Chen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio [+ + +]
Author: Yang Xiuwei <[email protected]>
Date:   Wed Aug 19 10:54:32 2026 +0800

    btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio
    
    [ Upstream commit 80a8dbb30d2b00b9c671b02bd73f700f6d20100f ]
    
    If all bios finish before btrfs_encoded_read_regular_fill_pages()
    returns, it calls btrfs_uring_read_extent_endio() and previously
    returned the I/O status.  A negative errno then made
    btrfs_uring_read_extent() unlock and free while
    btrfs_uring_read_finished() did the same again.
    
    Return -EIOCBQUEUED so only the deferred path cleans up.
    
    Reported-by: Yue Sun <[email protected]>
    Closes: https://lore.kernel.org/linux-btrfs/[email protected]/
    Suggested-by: Jens Axboe <[email protected]>
    Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
    Signed-off-by: Yang Xiuwei <[email protected]>
    Reviewed-by: David Sterba <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

btrfs: don't stash io_uring encoded data across -EAGAIN [+ + +]
Author: Yang Xiuwei <[email protected]>
Date:   Wed Aug 19 10:54:35 2026 +0800

    btrfs: don't stash io_uring encoded data across -EAGAIN
    
    [ Upstream commit 51562a8cb11628d3a5e105b4c347ec5473e5745f ]
    
    Returning -EAGAIN while leaving btrfs_uring_encoded_data in the cmd PDU
    leaks if the request is cancelled or the ring exits before reissue.
    io_uring does not free driver PDU allocations on cleanup.
    
    Write: io_queue_sqe() always issues with IO_URING_F_NONBLOCK first, so
    return -EAGAIN before allocating and free data on every exit.
    
    Read: free on nowait -EAGAIN too; only -EIOCBQUEUED keeps the allocation
    for btrfs_uring_read_finished().
    
    Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
    Fixes: e32dcdb0af9f ("btrfs: add io_uring interface for encoded writes")
    Signed-off-by: Yang Xiuwei <[email protected]>
    Reviewed-by: David Sterba <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

btrfs: fix lost error return value in btrfs_listxattr() [+ + +]
Author: Filipe Manana <[email protected]>
Date:   Fri Sep 25 17:12:45 2026 +0100

    btrfs: fix lost error return value in btrfs_listxattr()
    
    [ Upstream commit 41c8899d59898f6fa51ceebd2b6e55257191a8ee ]
    
    If the input buffer does not have enough space to store the current xattr,
    we set 'iter_ret' to -ERANGE and then do "break", but that only exits the
    while loop over the xattrs in the current btrfs_dir_item, and then we
    continue the btrfs_for_each_slot() iteration, which overwrites the value
    of 'iter_ret' causing us to lose the error return value and proceed as if
    the buffer has enough space.
    
    Fix this by returning -ERANGE directly (the path is automatically freed)
    instead of breaking from the while loop.
    
    Fixes: 184b3d190087 ("btrfs: use btrfs_for_each_slot in btrfs_listxattr")
    Assisted-by: LLM (found the bug)
    Reviewed-by: Qu Wenruo <[email protected]>
    Signed-off-by: Filipe Manana <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

btrfs: fix xattr replace when multiple xattrs are packed in the same item [+ + +]
Author: Filipe Manana <[email protected]>
Date:   Fri Sep 25 13:47:21 2026 +0100

    btrfs: fix xattr replace when multiple xattrs are packed in the same item
    
    [ Upstream commit 858bee1c77857aabcc2327cd32dd8266332de332 ]
    
    If we have a btrfs_dir_item item that packs multiple xattrs and then we
    replace the value of one of them (with the setxattr(2) family of syscalls)
    with another value of a different size, we end up not having a fully
    initialized btrfs_dir_item, resulting in a corruption that the tree
    checker will detect at extent buffer writeback time.
    
    This is because in btrfs_setxattr() when we find a btrfs_dir_item with
    multiple xattrs (due to the crc32c hash of their name being the same)
    we delete one of the xattr items (btrfs_dir_item) and then insert a new
    one, but the deletion and insertion results in shifting existing data in
    the leaf and therefore when the new value of a xattr has a different size,
    the new btrfs_dir_item is placed in a leaf section that was not
    initialized and we only copy the value's data and set the value's length
    in the new btrfs_dir_item, without setting the name, the name's length,
    the key (which must be all zeroes for xattrs), flags (BTRFS_FT_XATTR) and
    transaction ID.
    
    The following script reproduces the issue:
    
      $ cat test.sh
      #!/bin/bash
    
      DEV=/dev/sdi
      MNT=/mnt/sdi
    
      mkfs.btrfs -f $DEV
      mount $DEV $MNT
    
      touch $MNT/testfile
    
      # Add two xattrs that, on btrfs, have the same hash (crc32c) for their
      # name and therefore are packed into the same btrfs_dir_item.
      setfattr -n user.foobar -v 123 $MNT/testfile
      setfattr -n user.WvG1c1Td -v qwerty $MNT/testfile
    
      # Verify the xattrs are present.
      echo "xattrs before:"
      getfattr --absolute-names --dump $MNT/testfile
    
      # Now replace the value of the foobar xattr with a significantly larger
      # value.
      setfattr -n user.foobar -v abcdefghijklmnopqrstuvwxyz $MNT/testfile
    
      # Check the xattrs have the expected values.
      echo "xattrs after:"
      getfattr --absolute-names --dump $MNT/testfile
    
      umount $MNT
    
    Running it:
    
      $ ./test.sh
      (...)
      xattrs before:
      # file: /mnt/sdi/testfile
      user.WvG1c1Td="qwerty"
      user.foobar="123"
    
      xattrs after:
      # file: /mnt/sdi/testfile
      user.WvG1c1Td="qwerty"
    
    So the "user.foobar" xattr is missing and there was a transaction abort
    when unmounting the fs with the following traces in dmesg:
    
      $ dmesg
      [869800.159271] BTRFS warning (device sdi): access to eb bytenr 30474240 len 16384 out of range start 16015 len 25964
      [869800.159293] ------------[ cut here ]------------
      [869800.159296] WARNING: fs/btrfs/extent_io.c:4408 at report_eb_range+0x44/0x60 [btrfs], CPU#8: getfattr/2605179
      [869800.168961] Modules linked in: btrfs dm_thin_pool (...)
      [869800.190527] CPU: 8 UID: 0 PID: 2605179 Comm: getfattr Tainted: G        W           7.3.0-rc3-btrfs-next-244+ #1 PREEMPT(full)
      [869800.193726] Tainted: [W]=WARN
      [869800.194502] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
      [869800.197576] RIP: 0010:report_eb_range+0x44/0x60 [btrfs]
      [869800.198985] Code: 48 8b 7b 18 (...)
      [869800.203531] RSP: 0018:ffffce4541937d58 EFLAGS: 00010246
      [869800.204609] RAX: 0000000000000000 RBX: ffff8dde054b8738 RCX: 0000000000000000
      [869800.206137] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffffc04c92a0
      [869800.207645] RBP: 0000000000003e8f R08: 0000000000000000 R09: 3fffffffffefffff
      [869800.226175] R10: ffffce4541937a88 R11: 0000000000000003 R12: 000000000000656c
      [869800.227594] R13: ffff8dde14be800f R14: 000000000000656c R15: 0000000000000069
      [869800.229097] FS:  00007f59023bb780(0000) GS:ffff8de5788ed000(0000) knlGS:0000000000000000
      [869800.231137] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [869800.232321] CR2: 0000558dc45e6a78 CR3: 0000000765b16004 CR4: 0000000000370ef0
      [869800.233783] Call Trace:
      [869800.234330]  <TASK>
      [869800.234791]  read_extent_buffer+0x4d/0x100 [btrfs]
      [869800.235898]  btrfs_listxattr+0x199/0x240 [btrfs]
      [869800.236912]  vfs_listxattr+0x51/0xa0
      [869800.237683]  listxattr+0x7e/0x100
      [869800.238398]  path_listxattrat+0x9e/0x190
      [869800.239117]  do_syscall_64+0x89/0x470
      [869800.239877]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
      [869800.240914] RIP: 0033:0x7f59024cdcb7
      [869800.241686] Code: f0 ff ff 73 (...)
      [869800.245353] RSP: 002b:00007ffd056dcdb8 EFLAGS: 00000246 ORIG_RAX: 00000000000000c2
      [869800.246892] RAX: ffffffffffffffda RBX: 00007ffd056df2e2 RCX: 00007f59024cdcb7
      [869800.248853] RDX: 0000000000006600 RSI: 0000558dc45e0470 RDI: 00007ffd056df2e2
      [869800.250514] RBP: 00007ffd056df2e2 R08: 0000000000006600 R09: 0000000000006600
      [869800.252295] R10: 0000000000000004 R11: 0000000000000246 R12: 00000000ffffff9c
      [869800.254105] R13: 0000558dc45e0470 R14: 0000000000006600 R15: 0000000000000000
      [869800.255931]  </TASK>
      [869800.256529] ---[ end trace 0000000000000000 ]---
      [869800.260071] page: refcount:2 mapcount:0 mapping:000000007ccfc77f index:0x1d10 pfn:0x608c69
      [869800.260075] memcg:ffff8dde00344d40
      [869800.260076] aops:btree_aops [btrfs] ino:1
      [869800.260151] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff)
      [869800.260154] raw: 017fffc00000402a fffff4adc773d4c8 fffff4adc48f3d88 ffff8de36504ba30
      [869800.260155] raw: 0000000000001d10 ffff8dde054b8738 00000002ffffffff ffff8dde00344d40
      [869800.260156] page dumped because: eb page dump
      [869800.260157] BTRFS critical (device sdi): corrupt leaf: root=5 block=30474240 slot=5 ino=257, invalid location key type, have 46, expect 132 or 1
      [869800.260161] BTRFS info (device sdi): leaf 30474240 gen 9 total ptrs 6 free space 15629 owner 5
      [869800.260163] BTRFS info (device sdi): refs 3 lock_owner 0 current 2550294
      [869800.260164]       item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
      [869800.260165]               inode generation 3 transid 0 size 0 nbytes 16384
      [869800.260166]               block group 0 mode 40755 links 1 uid 0 gid 0
      [869800.260167]               rdev 0 sequence 0 flags 0x0
      [869800.260168]               atime 1790340637.0
      [869800.260169]               ctime 1790340637.0
      [869800.260169]               mtime 1790340637.0
      [869800.260170]               otime 1790340637.0
      [869800.260170]       item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
      [869800.260172]               index 0 name_len 2
      [869800.260172]       item 2 key (256 DIR_ITEM 982728850) itemoff 16073 itemsize 38
      [869800.260173]               location key (257 1 0) type 1
      [869800.260174]               transid 9 data_len 0 name_len 8
      [869800.260175]       item 3 key (257 INODE_ITEM 0) itemoff 15913 itemsize 160
      [869800.260176]               inode generation 9 transid 9 size 0 nbytes 0
      [869800.260177]               block group 0 mode 100664 links 1 uid 0 gid 0
      [869800.260177]               rdev 0 sequence 0 flags 0x0
      [869800.260178]               atime 1790340638.38778502
      [869800.260179]               ctime 1790340638.38778502
      [869800.260179]               mtime 1790340638.38778502
      [869800.260180]               otime 1790340638.38778502
      [869800.260180]       item 4 key (257 INODE_REF 256) itemoff 15895 itemsize 18
      [869800.260181]               index 2 name_len 8
      [869800.260182]       item 5 key (257 XATTR_ITEM 751495445) itemoff 15779 itemsize 116
      [869800.260183]               location key (0 0 0) type 8
      [869800.266052]               transid 9 data_len 6 name_len 13
      [869800.266053]               location key (8243121639454149888 46 7229457603934778967) type 0
      [869800.266055]               transid 113 data_len 26 name_len 0
      [869800.266056]               location key (8608196880778817904 120 162425) type 9
      [869800.266057]               transid 8391162079612502016 data_len 26982 name_len 25964
      [869800.266058] BTRFS error (device sdi): block=30474240 write time tree block corruption detected
      [869800.266091] ------------[ cut here ]------------
      [869800.266092] WARNING: fs/btrfs/disk-io.c:336 at btree_csum_one_bio+0x20b/0x220 [btrfs], CPU#7: kworker/u50:7/2550294
      [869800.268392] Modules linked in: btrfs dm_thin_pool (...)
      [869800.365851] CPU: 7 UID: 0 PID: 2550294 Comm: kworker/u50:7 Tainted: G        W           7.3.0-rc3-btrfs-next-244+ #1 PREEMPT(full)
      [869800.368937] Tainted: [W]=WARN
      [869800.369834] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
      [869800.372778] Workqueue: writeback wb_workfn (flush-btrfs-3821)
      [869800.374314] RIP: 0010:btree_csum_one_bio+0x20b/0x220 [btrfs]
      [869800.375915] Code: 89 44 24 04 (...)
      [869800.380639] RSP: 0018:ffffce4548e3f7d0 EFLAGS: 00010246
      [869800.382008] RAX: 0000000000000000 RBX: ffff8dde054b8738 RCX: 0000000000000000
      [869800.383850] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8de091c2ddc0
      [869800.385710] RBP: ffff8dde196a2000 R08: 0000000000000000 R09: 3fffffffffefffff
      [869800.387388] R10: ffffce4548e3f500 R11: 0000000000000003 R12: ffffce4548e3f7d8
      [869800.388973] R13: ffff8dde196a2000 R14: ffff8de36504b750 R15: ffff8dde4c497b00
      [869800.390414] FS:  0000000000000000(0000) GS:ffff8de5788ad000(0000) knlGS:0000000000000000
      [869800.392002] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [869800.393160] CR2: 000055cd6e92ad5c CR3: 00000007cb264001 CR4: 0000000000370ef0
      [869800.394595] Call Trace:
      [869800.395113]  <TASK>
      [869800.395570]  btrfs_submit_bbio+0x872/0x890 [btrfs]
      [869800.397284]  write_meta_extent_buffer+0x70/0x80 [btrfs]
      [869800.398940]  btree_writepages+0x141/0x4f0 [btrfs]
      [869800.400426]  ? get_random_u32+0x8a/0xf0
      [869800.401417]  ? build_slab_freelist+0x47/0x130
      [869800.402574]  ? preempt_count_add+0x6b/0xa0
      [869800.403633]  ? _raw_spin_lock_irqsave+0x23/0x50
      [869800.404807]  ? _raw_spin_unlock_irqrestore+0x22/0x40
      [869800.406085]  ? alloc_from_new_slab+0x18f/0x330
      [869800.407223]  do_writepages+0xc6/0x160
      [869800.408191]  ? refill_objects+0xd8/0x300
      [869800.409211]  __writeback_single_inode+0x42/0x350
      [869800.410408]  writeback_sb_inodes+0x231/0x560
      [869800.411511]  wb_writeback+0x8a/0x300
      [869800.412440]  wb_workfn+0xbf/0x460
      [869800.413291]  ? _raw_spin_unlock+0x14/0x30
      [869800.414328]  ? finish_task_switch.isra.0+0xb9/0x380
      [869800.415105]  process_one_work+0x1d1/0x3d0
      [869800.416633]  worker_thread+0x1c4/0x330
      [869800.417467]  ? __pfx_worker_thread+0x10/0x10
      [869800.418452]  kthread+0xfc/0x130
      [869800.419257]  ? __pfx_kthread+0x10/0x10
      [869800.420089]  ret_from_fork+0x1f7/0x2c0
      [869800.420863]  ? __pfx_kthread+0x10/0x10
      [869800.421654]  ret_from_fork_asm+0x1a/0x30
      [869800.422484]  </TASK>
      [869800.422953] ---[ end trace 0000000000000000 ]---
      [869800.424005] BTRFS error (device sdi state A): Transaction 9 aborted (-EIO)
      [869800.424010] BTRFS: error (device sdi state A) in __btrfs_run_delayed_items:1162: errno=-5 IO failure
      [869800.424011] BTRFS info (device sdi state EA): forced readonly
      [869800.424013] BTRFS warning (device sdi state EA): Skipping commit of aborted transaction.
      [869800.424014] BTRFS: error (device sdi state EA) in cleanup_transaction:2076: errno=-5 IO failure
    
    Fix this by always setting all fields in the new btrfs_dir_item when we
    replace an existing xattr.
    
    Fixes: 5f5bc6b1e2d5 ("Btrfs: make xattr replace operations atomic")
    Reviewed-by: Qu Wenruo <[email protected]>
    Signed-off-by: Filipe Manana <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

btrfs: free iov when btrfs_uring_read_extent() fails [+ + +]
Author: Yang Xiuwei <[email protected]>
Date:   Wed Aug 19 10:54:33 2026 +0800

    btrfs: free iov when btrfs_uring_read_extent() fails
    
    [ Upstream commit a8ea92830b3e0e163d4e829bdcb17ca83c0f951c ]
    
    After btrfs_uring_read_extent(), the caller always jumped to out_acct.
    That skips kfree(data->iov), which is only correct for -EIOCBQUEUED
    where the deferred path owns the iov. On failure, fall through to
    out_free instead.
    
    Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
    Signed-off-by: Yang Xiuwei <[email protected]>
    Reviewed-by: David Sterba <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode() [+ + +]
Author: Wentao Liang <[email protected]>
Date:   Wed Sep 16 17:16:10 2026 +0000

    btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode()
    
    commit 1fd742c7479961da6d0bb794ef8ac6b7b9442847 upstream.
    
    When paths_from_inode() fails, scrub_print_warning_inode() jumps to err
    without dropping the reference taken by btrfs_get_fs_root(), leaking a
    reference to the root every time path resolution fails while printing
    scrub warnings.  Every other error and success path of the function
    drops the reference.
    
    Drop the reference on the paths_from_inode() failure path too.
    
    Fixes: 558540c17771 ("btrfs scrub: print paths of corrupted files")
    CC: [email protected]
    Reviewed-by: Qu Wenruo <[email protected]>
    Signed-off-by: Wentao Liang <[email protected]>
    Reviewed-by: David Sterba <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

btrfs: unlock inode and extent in caller when io_uring read extent fails [+ + +]
Author: Yang Xiuwei <[email protected]>
Date:   Wed Aug 19 10:54:34 2026 +0800

    btrfs: unlock inode and extent in caller when io_uring read extent fails
    
    [ Upstream commit b6e8add5d79d1f6f819a054c833bab452bd7365d ]
    
    btrfs_uring_read_extent() runs only after btrfs_encoded_read() has taken
    the inode shared lock and the extent lock.  On failure it used to unlock
    in out_fail, and a pages-array allocation failure returned -ENOMEM
    without unlocking at all.
    
    Unlock in the caller instead on all failure returns, matching the
    copy_to_user() error path.  The deferred -EIOCBQUEUED path still unlocks
    in btrfs_uring_read_finished().
    
    Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
    Suggested-by: Qu Wenruo <[email protected]>
    Reviewed-by: Qu Wenruo <[email protected]>
    Signed-off-by: Yang Xiuwei <[email protected]>
    Reviewed-by: David Sterba <[email protected]>
    Signed-off-by: David Sterba <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
can: dev: init_can_skb(): restore skb header initialization [+ + +]
Author: zjamg <[email protected]>
Date:   Thu Sep 17 20:37:16 2026 +0800

    can: dev: init_can_skb(): restore skb header initialization
    
    commit 0a04c0cb8606ff88399489d03ef255afe90d0d5f upstream.
    
    Commit 9f10374bb024 ("can: remove private CAN skb headroom infrastructure")
    removed the skb_reset_mac_header()/skb_reset_network_header()/
    skb_reset_transport_header() calls from init_can_skb(). As a result, RX
    skbs from alloc_can_skb() and friends again carry mac_header = 0xFFFF.
    When such an skb reaches packet_rcv_spkt() (SOCK_PACKET), the push length
    calculation overflows and triggers skb_under_panic -> kernel BUG -> full
    machine panic.
    
    The same issue was originally reported in 2014 on linux-can and fixed by
    commit 969439016d2c ("can: add missing initialisations in CAN related
    skbuffs"). packet_rcv_spkt() itself has never been hardened: only
    packet_rcv() and tpacket_rcv() gained dev_has_header() checks in
    commit d549699048b4 ("net/packet: fix packet receive on L3 devices
    without visible hard header").
    
    Fixes: 9f10374bb024 ("can: remove private CAN skb headroom infrastructure")
    Cc: [email protected]
    Reviewed-by: Oliver Hartkopp <[email protected]>
    Acked-by: Oliver Hartkopp <[email protected]>
    Signed-off-by: zjamg <[email protected]>
    Tested-by: Quchaosheng <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Reported-by: Shaunak Datar <[email protected]>
    Closes: https://lore.kernel.org/all/[email protected]
    Signed-off-by: Marc Kleine-Budde <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

can: fix unique skb identifier regression under RPS [+ + +]
Author: Oliver Hartkopp <[email protected]>
Date:   Thu Oct 1 13:57:24 2026 +0200

    can: fix unique skb identifier regression under RPS
    
    commit 7093c3b8314a4ef7405c4066a2521398c455efe7 upstream.
    
    Commit d4fb6514ff8e ("can: use skb hash instead of private variable in
    headroom") moved the per-skb unique identifier used for raw_rcv()
    duplicate detection into skb->hash.
    
    With RPS enabled, get_rps_cpu() calls skb_get_hash() before the frame
    reaches the CAN subsystem. Since CAN skbs have no L3/L4 headers, the
    flow dissector assigns every CAN frame the same non-zero software
    hash. can_set_skb_uid() only generated a new identifier when
    skb->hash was 0, so it kept this constant hash. When the SLAB
    allocator later reused the same skb address, raw_rcv() mistook the
    next legitimate frame for a duplicate and dropped it.
    
    Fix this by storing the CAN UID in the CAN skb extension
    (struct can_skb_ext::can_skb_uid) instead of skb->hash, decoupling it
    from any hash the network stack may compute. can_set_skb_uid() keeps
    its "assign only if unset" behaviour, which preserves UIDs set before
    transmission (e.g. by isotp to identify echo frames) across the local
    loopback path.
    
    Frames whose extension is shared with another clone (e.g. via tc mirred
    or netem duplicate) are given a private extension copy before the UID
    is assigned, so that independently received skb clones from real CAN
    interfaces (can_skb_uid = 0) don't end up with the same UID.
    The limitation that tc mirred/netem skb duplicates might be dropped in
    raw_rcv for looped back isotp echo frame skbs is accepted. There is no
    valid use-case for tc mirred or netem together with isotp which is not
    capable to operate on different CAN interfaces simultaneously.
    For routing and modifying CAN frames together with isotp use can-gw.
    
    can-gw and vxcan additionally clear the UID of forwarded/duplicated
    frames so each newly routed frame gets its own unique identifier.
    
    Fixes: d4fb6514ff8e ("can: use skb hash instead of private variable in headroom")
    Reported-by: Joerg Willmann <[email protected]>
    Closes: https://lore.kernel.org/linux-can/[email protected]/
    Cc: [email protected]
    Tested-by: Oliver Hartkopp <[email protected]>
    Tested-by: Joerg Willmann <[email protected]>
    Signed-off-by: Oliver Hartkopp <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Marc Kleine-Budde <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug() [+ + +]
Author: Waiman Long <[email protected]>
Date:   Mon Oct 5 06:43:10 2026 -0400

    cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug()
    
    [ Upstream commit b8eb5fd5bdb4c03758b056c70e5e1d962ca89757 ]
    
    It is reported by sashiko that calling is_in_v2_mode() outside of
    cpuset_mutex critical section in cpuset_handle_hotplug() can introduce
    a TOCTOU race where cgroup hierarchy may have changed from v1 to v2 or
    vice versa after is_in_v2_mode() is called leading to erroneously skip
    the allocation of tmpmasks or incorrectly modify cpus_allowed masks,
    resulting in cpuset state corruption. Fix that by calling is_in_v2_mode()
    after acquiring the cpuset_mutex.
    
    Fixes: b8d1b8ee93df ("cpuset: Allow v2 behavior in v1 cgroup")
    Signed-off-by: Waiman Long <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

cgroup/cpuset: Don't access cpuset_cgrp_subsys.root in is_in_v2_mode() [+ + +]
Author: Waiman Long <[email protected]>
Date:   Tue Sep 29 23:18:33 2026 -0400

    cgroup/cpuset: Don't access cpuset_cgrp_subsys.root in is_in_v2_mode()
    
    [ Upstream commit e06b678e3b4e12fdaa0b51a7a5a54abc5dbd6469 ]
    
    After seeing the patch [1] to guard is_in_v2_mode() with RCU, it makes
    me realize that is_in_v2_mode() may be called in a context where a new
    cgroup filesystem is being rebound with stale cpuset_cgrp_subsys.root
    pointer. Avoid this potential UaF situation by adding a new cpuset_v2_mode
    flag which is set when the cpuset_v2_mode mount option is used. This
    flag is written into only when cpuset_bind() is being called with a
    stable cpuset_cgrp_subsys.root value. The is_in_v2_mode() helper is
    modified to read the new cpuset_v2_mode flag instead of accessing
    cpuset_cgrp_subsys.root directly.
    
    [1] https://lore.kernel.org/lkml/[email protected]
    
    Fixes: b8d1b8ee93df ("cpuset: Allow v2 behavior in v1 cgroup")
    Signed-off-by: Waiman Long <[email protected]>
    Reviewed-by: Ridong Chen <[email protected]>
    Reviewed-by: Andrea Righi <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus() [+ + +]
Author: Waiman Long <[email protected]>
Date:   Fri Oct 2 12:54:38 2026 -0400

    cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus()
    
    commit 23b1ab15ca91f2cffaf149d9bb0fafeb700c7db2 upstream.
    
    With commit 2125c0034c5d ("cgroup/cpuset: Make cpuset hotplug processing
    synchronous"), the cpuset hotplug operation becomes synchronous. That
    commit also removes the code that handles race between cpuset_hotplug_work
    and cpu hotplug notifier with the assumption that race is now gone.
    Later commit 7a0aabd9ce69 ("cgroup/cpuset: Always use cpu_active_mask")
    updates the cpuset code to always use cpu_active_mask instead of
    cpu_online_mask in some places including guarantee_online_cpus() which
    is renamed to guarantee_active_cpus() in that commit.
    
    In the case of CPU offline operation, cpu_active_mask is updated
    first in sched_cpu_deactivate() to remove the offline CPU before
    cpuset_handle_hotplug() is called to update the effective_cpus of the
    affected cpusets. The cpu_online_mask is updated after that near the end
    of the offline operation to remove the offline CPU. As a result, the race
    comes back and the top cpuset may not have any active CPU leading to NULL
    pointer dereference during the race window when guarantee_active_cpus()
    is called after cpu_active_mask is updated to remove the CPU to be torn
    down but before cpuset_handle_hotplug() is able to properly update the
    effective_cpus of the top cpuset.
    
    Fix this by adding back the NULL cs check to avoid this problem.
    
    Fixes: 7a0aabd9ce69 ("cgroup/cpuset: Always use cpu_active_mask")
    Cc: [email protected] # v6.16+
    Reported-by: Farhad Alemi <[email protected]>
    Link: https://lore.kernel.org/lkml/CA+0ovChh3VjsKN1g+ZGjwwY2fGTpP7uD+aCCByLj5Qbymw=bfQ@mail.gmail.com
    Signed-off-by: Waiman Long <[email protected]>
    Tested-by: Farhad Alemi <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
cipso: adjust cached option offsets when removing CIPSO [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Tue Oct 6 12:51:08 2026 +0900

    cipso: adjust cached option offsets when removing CIPSO
    
    commit 6d25ffca055a77787c21a36b66c253f76239411b upstream.
    
    cipso_v4_skbuff_delattr() removes the CIPSO bytes but does not adjust
    cached offsets for options that follow them.
    
    For example, with a valid 10-byte CIPSO option followed by a seven-byte
    RR option, parsing records rr at offset 30.  Removing CIPSO moves RR to
    offset 20, while the cached offset remains 30.  Consumers such as
    ip_forward_options() and __ip_options_echo() then access the wrong bytes;
    the latter may interpret packet data as the option length and copy it into
    fixed-size option storage.
    
    Mirror cipso_v4_delopt() and subtract cipso_len from the srr, rr, ts and
    router_alert offsets when they follow CIPSO.  cipso_len is the distance
    the first memmove() shifts those options.  The later header move and
    network-header reset relocate the bytes and their offset base together.
    
    Fixes: 89aa3619d141 ("cipso: make cipso_v4_skbuff_delattr() fully remove the CIPSO options")
    Cc: [email protected]
    Reviewed-by: Ondrej Mosnáček <[email protected]>
    Signed-off-by: Daehyeon Ko <[email protected]>
    Acked-by: Paul Moore <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks [+ + +]
Author: Luca Weiss <[email protected]>
Date:   Fri Aug 7 09:46:04 2026 +0200

    clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks
    
    [ Upstream commit 5ffd02d16f4e2f0566b8f31d5610538987e1944c ]
    
    The critical_cbrcrs array will get qcom_branch_set_clk_en() called on
    each entry which will set BIT(0) to enable the clock. This is however
    wrong for these two PCIE_RSCC clocks which need BIT(20) and BIT(21) set
    respectively to enable them.
    
    Fixes: 3d356ab4a1ec ("clk: qcom: Add support for Global clock controller on Eliza")
    Signed-off-by: Luca Weiss <[email protected]>
    Tested-by: Abel Vesa <[email protected]>
    Reviewed-by: Abel Vesa <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Signed-off-by: Bjorn Andersson <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

clk: qcom: gcc-kaanapali: Fix always-enabling PCIE_RSCC clocks [+ + +]
Author: Luca Weiss <[email protected]>
Date:   Fri Aug 7 09:46:06 2026 +0200

    clk: qcom: gcc-kaanapali: Fix always-enabling PCIE_RSCC clocks
    
    [ Upstream commit 0bfb542fc3368371cefb4cf45ef21c3ba2d37c3f ]
    
    The critical_cbrcrs array will get qcom_branch_set_clk_en() called on
    each entry which will set BIT(0) to enable the clock. This is however
    wrong for these two PCIE_RSCC clocks which need BIT(20) and BIT(21) set
    respectively to enable them.
    
    Fixes: d1919c375f21 ("clk: qcom: Add support for Global clock controller on Kaanapali")
    Signed-off-by: Luca Weiss <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Signed-off-by: Bjorn Andersson <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable [+ + +]
Author: Taniya Das <[email protected]>
Date:   Sat Aug 1 23:01:17 2026 +0530

    clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable
    
    [ Upstream commit 8f3f88309fa4e975ac27368ee945c2c202251a7c ]
    
    The GPU CX GDSC on Glymur is a votable power domain and hence should
    not be polled for power-off status during GDSC disable. Also, its
    power-on status should be read from the GDS hardware control register.
    
    Accommodate this by removing POLL_CFG_GDSCR and adding the VOTABLE
    flag for the GPU CX GDSC, similar to other platforms (e.g. SM8750 and
    Milos).
    
    Fixes: 67e645285dd0 ("clk: qcom: Add support for GPUCC and GXCLK for Glymur")
    Signed-off-by: Taniya Das <[email protected]>
    Reviewed-by: Jagadeesh Kona <[email protected]>
    Link: https://lore.kernel.org/r/20260801-kaanapali-gpu-voteable-v1-1-fe804d24d2e9@oss.qualcomm.com
    Signed-off-by: Bjorn Andersson <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

clk: qcom: gpucc-kaanapali: Mark the GPU CX GDSC as votable [+ + +]
Author: Taniya Das <[email protected]>
Date:   Sat Aug 1 23:01:18 2026 +0530

    clk: qcom: gpucc-kaanapali: Mark the GPU CX GDSC as votable
    
    [ Upstream commit 55981579b27b6541aeeab81c768f248dba0491ac ]
    
    The GPU CX GDSC on Kaanapali is a votable power domain and hence
    should not be polled for power-off status during GDSC disable. Also,
    its power-on status should be read from the GDS hardware control
    register.
    
    Accommodate this by removing POLL_CFG_GDSCR and adding the VOTABLE
    flag for the GPU CX GDSC, similar to other platforms (e.g. SM8750 and
    Milos).
    
    Fixes: 685ec348339b ("clk: qcom: Add support for GPUCC and GXCLK for Kaanapali")
    Signed-off-by: Taniya Das <[email protected]>
    Reviewed-by: Jagadeesh Kona <[email protected]>
    Link: https://lore.kernel.org/r/20260801-kaanapali-gpu-voteable-v1-2-fe804d24d2e9@oss.qualcomm.com
    Signed-off-by: Bjorn Andersson <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
cxgb4/ch_ktls: disable softirqs around tid_list erases [+ + +]
Author: Sang-Hoon Choi <[email protected]>
Date:   Wed Sep 30 02:37:34 2026 +0900

    cxgb4/ch_ktls: disable softirqs around tid_list erases
    
    [ Upstream commit 4c9dc0faca98084922caeb689579d338cf3e1c29 ]
    
    chcr_ktls_cpl_act_open_rpl() inserts into tid_list from the receive path
    using xa_insert_bh().  The array is shared by the adapter's connections
    and initialized with XA_FLAGS_LOCK_BH.  However, chcr_ktls_dev_del() and
    the chcr_ktls_dev_add() error path use xa_erase(), which takes the XArray
    lock without disabling softirqs.
    
    When cleanup runs with softirqs enabled, a receive softirq for another
    connection on the same CPU can interrupt the erase and spin on the lock
    held by the interrupted task.  Use xa_erase_bh() at both sites to match
    the insertion path.
    
    Fixes: 65e302a9bd57 ("cxgb4/ch_ktls: Clear resources when pf4 device is removed")
    Reported-by: Changyul Lee <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Sang-Hoon Choi <[email protected]>
    Reviewed-by: Ayush Sawal <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
dcache: don't put a mountpoint on a dentry that's being removed [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:07 2026 +0200

    dcache: don't put a mountpoint on a dentry that's being removed
    
    commit 75f4197f1e11d2eb75c2d6f916a7d4764db621e5 upstream.
    
    rmdir(), unlink() and rename() call dont_mount() on the victim and then
    detach_mounts() with the victim's inode locked. do_lock_mount() takes
    the inode lock of the mountpoint and checks cant_mount() so a mount
    can't show up after detach_mounts().
    
    But attach_recursive_mnt() makes a second mountpoint for the root of the
    source mount so that the mounts already located at the destination can
    be put on top of it. No inode is locked for that one and d_set_mounted()
    only refuses a dentry that is unlinked. Between detach_mounts() and
    d_delete() the victim is still hashed:
    
      rmrace: b passed dont_mount() and detach_mounts(), sleeping
      T2: move_mount(S, /tmp/plcant/x, BENEATH) = 0 errno 0 ()
      T1: rmdir(/tmp/plcant/d/b) = 0 errno 0
          109 107 0:61 /d/b//deleted /tmp/plcant/x rw,relatime - tmpfs tmpfs rw
          108 109 0:63 / /tmp/plcant/x rw,relatime - tmpfs T rw
    
    A bind mount of the directory that's being removed is moved beneath an
    existing mount while the rmdir() is located between the two calls. The
    mount ends up on the removed directory and nothing will ever detach it.
    
    Check cant_mount() in d_set_mounted() as well. dont_mount() raises the
    flag under d_lock before detach_mounts() runs so either the mountpoint
    is set first and detach_mounts() finds the mount or the flag is seen and
    the mount is refused.
    
    Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
devlink: fix devlink_rel reference leak when notify work is pending [+ + +]
Author: Haishuang Yan <[email protected]>
Date:   Thu Oct 1 12:22:32 2026 +0800

    devlink: fix devlink_rel reference leak when notify work is pending
    
    [ Upstream commit c5381ae1cd1481cc431c2bd79460472c6f1d3ce3 ]
    
    devlink_rel_nested_in_notify_work_schedule() takes a reference on the
    devlink_rel for the notify work and then queues the work, ignoring the
    return value of schedule_delayed_work(). If the work is already pending,
    nothing new is queued, the work runs only once and drops only one
    reference, so the extra one is leaked together with the devlink_rel and
    its index in devlink_rels.
    
    This is easy to hit. devl_register() of a nested instance queues the
    work, and if the instance is unregistered before the work has run,
    devlink_rel_put() queues it again while it is still pending. The work
    also keeps rescheduling itself for as long as the parent devlink lock
    cannot be taken, which widens the window. Registering and unregistering
    a nested devlink instance 100 times while holding the parent lock leaks
    all 100 devlink_rel objects.
    
    The reschedule path in devlink_rel_nested_in_notify_work() has the same
    problem: if the work was queued again while it was running, the
    reference it holds is never dropped.
    
    Drop the reference in both places when the work was already pending.
    The pending work holds its own reference, so this can not be the last
    one.
    
    Fixes: c137743bce02 ("devlink: introduce object and nested devlink relationship infra")
    Signed-off-by: Haishuang Yan <[email protected]>
    Reviewed-by: Simon Horman <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
dm ioctl: don't let data_start run past the buffer [+ + +]
Author: Palla Raghunath <[email protected]>
Date:   Sat Sep 19 00:43:39 2026 +0100

    dm ioctl: don't let data_start run past the buffer
    
    commit 9b3fcf519d370df94a56f3b272d9eddffffa5be8 upstream.
    
    struct dm_ioctl has seven bytes of trailing padding, so the smallest
    buffer userspace is allowed to ask for, offsetof(struct dm_ioctl, data),
    is seven bytes shorter than sizeof(struct dm_ioctl).
    
    get_result_buffer() sets data_start to sizeof(struct dm_ioctl) without
    looking at how big the buffer actually is. Ask for the minimum and
    data_start ends up seven bytes past the end. Callers add it to
    data_size, and ctl_ioctl() copies that much back to userspace:
    
      BUG: KASAN: slab-out-of-bounds in _copy_to_user+0xad/0xd0
      Read of size 312 at addr ffff8880169e4c00 by task repro-dm/140
       ctl_ioctl+0x5e3/0xcb0
       dm_ctl_ioctl+0x25/0x40
      allocated 305-byte region [ffff8880169e4c00, ffff8880169e4d31)
    
    A DM_LIST_DEVICES with data_size set to 305 is enough to hit it, and the
    seven bytes that leak are whatever sat next to the allocation.
    
    Clamp data_start to the buffer size.
    
    Note that this is not a security bug because the out-of-bounds read can
    only be triggered by root.
    
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=48d935cf48a4a76be346
    Fixes: 76c072b48e39 ("dm ioctl: move compat code")
    Cc: [email protected]
    Signed-off-by: Palla Raghunath <[email protected]>
    Signed-off-by: Mikulas Patocka <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
dm-crypt: reject the lmk IV mode with AEAD ciphers [+ + +]
Author: Ben Cressey <[email protected]>
Date:   Tue Sep 15 00:39:10 2026 +0000

    dm-crypt: reject the lmk IV mode with AEAD ciphers
    
    commit 3195e0daf590683992edb4eed32269e569e04924 upstream.
    
    A "capi:" table line that pairs an AEAD cipher with the lmk IV mode,
    for example "capi:gcm(aes)-lmk" with the integrity:28:aead option,
    causes an oops when it is loaded. lmk sets tfms_count to 64, but
    crypt_alloc_tfms_aead only allocates one transform, so crypt_setkey
    reads past the end of the tfms_aead array and calls crypto_aead_setkey
    on the values it finds there.
    
    lmk exists for compatibility with Loop-AES, which uses CBC, so refuse
    it with an AEAD cipher rather than allocate 64 AEAD transforms. The
    check cannot go in crypt_iv_lmk_ctr with the other lmk checks, because
    the IV constructor runs after crypt_set_key.
    
    Note that this is not a security bug because the memory corruption can
    only be triggered by root.
    
    Fixes: 33d2f09fcb35 ("dm crypt: introduce new format of cipher with "capi:" prefix")
    Cc: [email protected]
    Signed-off-by: Ben Cressey <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Mikulas Patocka <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
dm-integrity: fix buffer overflow in inline mode with large tag size [+ + +]
Author: Ben Cressey <[email protected]>
Date:   Tue Sep 15 00:37:35 2026 +0000

    dm-integrity: fix buffer overflow in inline mode with large tag size
    
    commit 764b683a6180fd72c931c13fea98d383506a3475 upstream.
    
    In inline mode, dm_integrity_check and dm_integrity_inline_recheck
    compute the checksum of each block into an on-stack buffer of
    HASH_MAX_DIGESTSIZE bytes. integrity_sector_checksum pads its result
    with zeroes up to the tag size, so if the tag size is larger than
    HASH_MAX_DIGESTSIZE, the padding runs past the end of the buffer. With
    CONFIG_STACKPROTECTOR the kernel panics in dm_integrity_check on the
    first read.
    
    Enlarge both buffers to hold MAX_TAG_SIZE bytes, as commit b93b6643e9b5
    ("dm integrity: fix a crash with unusually large tag size") did for
    integrity_metadata.
    
    Note that this is not a security bug because the buffer overflow can only
    be triggered by root.
    
    Fixes: fb0987682c62 ("dm-integrity: introduce the Inline mode")
    Cc: [email protected]
    Signed-off-by: Ben Cressey <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Mikulas Patocka <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
dm-snap: reject the transient exception store for snapshot-merge [+ + +]
Author: Ma Xinmeng <[email protected]>
Date:   Fri Sep 25 11:05:39 2026 +0800

    dm-snap: reject the transient exception store for snapshot-merge
    
    commit fcbde6227fcc53c73f08c56b2539e462d545cac6 upstream.
    
    snapshot_merge_next_chunks() calls s->store->type->prepare_merge() without
    checking it. The transient store ("N") implements neither prepare_merge nor
    commit_merge, and snapshot_ctr() validates those callbacks only on the handover
    path (__validate_exception_handover()), so a directly constructed snapshot-merge
    calls a NULL prepare_merge on resume:
    
      snapshot_merge_resume -> snapshot_merge_next_chunks -> prepare_merge(...)
    
    commit_merge() is NULL for the same reason. Userspace only issues documented
    device-mapper ioctls (CAP_SYS_ADMIN); this is a misconfiguration the kernel must
    reject rather than oops on.
    
    Reject the combination in snapshot_ctr() at table-load time (-EINVAL), the same
    check the handover path already performs; this also covers the commit_merge()
    call site, which a guard local to the prepare_merge call would miss.
    
    Tested on Linux v6.6.157 KASAN: unpatched, the dmsetup reproducer oopses in
    snapshot_merge_next_chunks(); with this patch, the table load fails with -EINVAL
    and no oops. Also present on v6.6.145; still present on the linux-dm tree
    (555f3d7be91a) and on torvalds/linux master (62f4c998b297) as of 2026-09-22.
    
    Note that this is not a security bug because only root can trigger it.
    
    Signed-off-by: Ma Xinmeng <[email protected]>
    Signed-off-by: Mikulas Patocka <[email protected]>
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
dm: fix reading free memory in do_resume [+ + +]
Author: Mikulas Patocka <[email protected]>
Date:   Wed Sep 23 12:40:16 2026 +0200

    dm: fix reading free memory in do_resume
    
    commit c9417c1c5269e2bd0570fbe53e4ec03a8d31f008 upstream.
    
    When do_resume calls dm_table_get_mode(new_map), the call is done without
    holding any locks (it only holds a reference to the md). It may be
    possible that another concurrent ioctl on the same device will swap table
    after dm_swap_table and before dm_table_get_mode. In this case,
    dm_table_get_mode(new_map) reads freed memory.
    
    This race condition was triggered by syzbot.
    
    This commit fixes the race by reading mode of the new table before
    dm_swap_table. Note that new_map is also passed to dm_ima_need_measure,
    but this function doesn't attempt to dereference it, so this call should
    be safe.
    
    Note that this is not a security bug because only root can trigger it and
    the commonly used tools such as lvm or cryptsetup do not call the ioctls
    concurrently, so that they can't trigger it acceidentally.
    
    Signed-off-by: Mikulas Patocka <[email protected]>
    Reported-by: [email protected]
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/amd/display: disable self-refresh on tearing flips [+ + +]
Author: Leo Li <[email protected]>
Date:   Wed Sep 30 12:30:52 2026 -0400

    drm/amd/display: disable self-refresh on tearing flips
    
    commit 2e54a92e0136c3ff5c7b542b95bf0940ad6687bf upstream.
    
    [Why & How]
    
    Immediate (tearing) flips breaks self refresh state machine assumptions,
    so disable PSR/Replay for them.
    
    Tested-by: Timur Kristóf <[email protected]>
    Reviewed-by: Harry Wentland <[email protected]>
    Signed-off-by: Leo Li <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit acbdd213b37e095f15685f3e3ee6d35defa05616)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amd/display: Don't replace a sink mode that shares the native totals [+ + +]
Author: Adrian Betschart <[email protected]>
Date:   Fri Sep 25 09:48:29 2026 +0200

    drm/amd/display: Don't replace a sink mode that shares the native totals
    
    commit 54c998c55fc9cbc391b350d67b86e0c2a0748f1a upstream.
    
    decide_crtc_timing_for_drm_display_mode() copies the native mode's CRTC
    timing into the requested mode when clock, htotal and vtotal match.
    That is meant for the modes amdgpu inserts itself:
    amdgpu_dm_create_common_mode() duplicates the native mode and changes
    only hdisplay and vdisplay, so those are sent with the native timing
    and scaled.
    
    A sink can also offer a real mode with the same clock and totals as
    its native mode. CTA-861 VIC 102 (4096x2160@60) and VIC 97
    (3840x2160@60) both use 594 MHz and 4400x2250. With 3840x2160@60 as
    the preferred mode, a 4096x2160@60 request goes out with the 3840x2160
    timing and the framebuffer scaled into it (dst 3840x2025 at y=67),
    while the AVI InfoFrame still carries VIC 102. A JVC projector then
    reports 3840x2160 and shows a corrupted right edge. 4096x2160@24,
    whose totals differ, is sent and displayed correctly.
    
    Inserted modes keep the native sync positions; a real mode with its
    own active width does not. Compare those too, so only inserted modes
    are patched.
    
    Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
    Signed-off-by: Adrian Betschart <[email protected]>
    Assisted-by: Claude-Code:claude-opus-5-5
    Tested-by: Dan Wheeler <[email protected]>
    Reviewed-by: Roman Li <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit 22f9a2da101c37f821cd00954f81dc598754f4d5)
    Cc: [email protected]
    [ Adrian: this tree keeps the function in amdgpu_dm.c; dropped the KUnit
      test, its file does not exist here. ]
    Signed-off-by: Adrian Betschart <[email protected]>
    Assisted-by: Claude-Code:claude-opus-5-5
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs [+ + +]
Author: Leo Li <[email protected]>
Date:   Tue Sep 29 17:32:32 2026 -0400

    drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs
    
    commit 7744262f5d63f9faa4d59dec127ae1c8b2d56495 upstream.
    
    [Why]
    
    DM was declaring it's own list of has_alpha DRM formats to check against
    for enabling alpha blending, when the format->has_alpha already does
    that for us.
    
    The self-declared list missed some has_alpha formats, causing
    direct-scanout planes with such formats to appear opaque.
    
    [How]
    
    Drop the self-declared list, instead use the format->has_alpha field
    directly.
    
    Signed-off-by: Leo Li <[email protected]>
    Reviewed-by: Harry Wentland <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit 9ecdac91ed43d836683d5daa467f4907405420e2)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/amdgpu/userq: only accept doorbell BOs as queue doorbell [+ + +]
Author: Jesse Zhang <[email protected]>
Date:   Wed Sep 30 14:21:19 2026 +0800

    drm/amdgpu/userq: only accept doorbell BOs as queue doorbell
    
    commit 7f7c88dbf4d543f6703e53bdeed380e886733167 upstream.
    
    amdgpu_userq_get_doorbell_index() pins any BO passed as doorbell_handle
    into the doorbell domain. For a regular BO, TTM moves it with
    ttm_bo_move_null() and its contents are lost. Since an importer on the
    same device gets the exporter's GEM object, a client can do this to a
    buffer another client shared with it.
    
    Reject BOs that were not created in the doorbell domain.
    
    v2: drop the error message, use a local abo variable (Christian)
    
    Fixes: f09c1e6077ab ("drm/amdgpu: generate doorbell index for userqueue")
    Reviewed-by: Christian König <[email protected]>
    Signed-off-by: Jesse Zhang <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit f7497bbc19db4821c62b9d97b31c9086feb2d917)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amdgpu/userq: return the memdup_user() error for the user MQD [+ + +]
Author: Jesse Zhang <[email protected]>
Date:   Wed Sep 30 14:21:19 2026 +0800

    drm/amdgpu/userq: return the memdup_user() error for the user MQD
    
    commit 76ceb6ed610cbf14341a9ba78c5c0b2199b9030a upstream.
    
    mes_userq_mqd_create() returns -ENOMEM when copying the user MQD fails,
    even though memdup_user() returns -EFAULT for a bad pointer or -EINTR
    when interrupted by a signal. Return PTR_ERR() instead.
    
    While at it drop the error messages. Neither case is a driver error and
    userspace shouldn't be able to spam the log with invalid IOCTL
    parameters.
    
    v2: drop the error messages (Christian)
    
    Fixes: 2c695d7c0720 ("drm/amdgpu: enable compute/gfx usermode queue")
    Fixes: 543b61453774 ("drm/amdgpu: enable SDMA usermode queues")
    Reviewed-by: Christian König <[email protected]>
    Signed-off-by: Jesse Zhang <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit 49a443fcb829be9fc780f10850652ddea2fe81f0)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks [+ + +]
Author: Mikhail Gavrilov <[email protected]>
Date:   Thu Oct 1 21:13:07 2026 +0500

    drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks
    
    commit 16c64495859f13f75602f439588883f2a4a4d6a6 upstream.
    
    Reading or writing a register through the amdgpu_regs2 debugfs file
    with GRBM bank selection, which umr does for every banked access (a
    single "umr -b x x x -r <reg>" is enough, as is the wave dump with
    "-O halt_waves"), makes lockdep report a circular locking dependency,
    after which lockdep stays off until reboot:
    
      WARNING: possible circular locking dependency detected
      umr/63306 is trying to acquire lock:
      ffff8882cf4b8350 (&mm->mmap_lock){++++}-{4:4}, at: __might_fault+0x9b/0x140
      but task is already holding lock:
      ffff8881aec010d0 (&amdgpu_grbm_lock_key){+.+.}-{4:4}, at: amdgpu_debugfs_regs2_op.isra.0+0x20d/0xd00 [amdgpu]
      ...
      Chain exists of:
        &mm->mmap_lock --> &amdgpu_srbm_lock_key --> &amdgpu_grbm_lock_key
      ...
       __might_fault+0xc5/0x140
       amdgpu_debugfs_regs2_op.isra.0+0x441/0xd00 [amdgpu]
       full_proxy_write+0x10e/0x1d0
       vfs_write+0x1d0/0xf50
       ksys_write+0x116/0x250
    
    amdgpu_debugfs_regs2_op() and amdgpu_debugfs_process_reg_op() call
    get_user()/put_user() for every dword while holding grbm_idx_mutex or
    srbm_mutex, and pm.mutex if requested, so a fault there takes mmap_lock
    inside those locks. The lock hierarchy in amdgpu_lockdep.c puts
    srbm_mutex and grbm_idx_mutex below notifier_lock, which
    amdgpu_cs_submit() takes with the BO reservations held, and
    dma_resv_lockdep() orders the reservations inside mmap_lock. So
    mmap_lock is outside grbm_idx_mutex and srbm_mutex, and these two
    debugfs paths nest it the other way round. The copies under the locks
    are as old as the bank selection in both files; commit 1d0f5838b126
    ("drm/amdgpu: Add lockdep annotations for lock ordering validation")
    only made them visible to lockdep.
    
    Copy the user buffer in before any of the locks is taken and the result
    out after all of them are dropped, as amdgpu_debugfs_wave_read(),
    amdgpu_debugfs_gpr_read() and amdgpu_debugfs_gprwave_read() already do.
    The buffer is sized by the count passed to read() or write(), so an
    access larger than PAGE_SIZE is now rejected with -EINVAL; umr reads and
    writes one register at a time. A fault on the user buffer of a write now
    fails with -EFAULT before any register is written, instead of after a
    partial write.
    
    Fixes: 566281595037 ("drm/amd/amdgpu: Add bank selection for MMIO debugfs (v3)")
    Fixes: 37df9560cd3e ("drm/amd/amdgpu: New debugfs interface for MMIO registers (v5)")
    Acked-by: Christian König <[email protected]>
    Acked-by: Tom St Denis <[email protected]>
    Reviewed-by: Vitaly Prosyak <[email protected]>
    Signed-off-by: Mikhail Gavrilov <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit ccf9e35ed6811f2c25ba6368e7dc6481da17159d)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amdgpu: make Mac FB workaround generic [+ + +]
Author: Alex Deucher <[email protected]>
Date:   Fri Sep 25 09:16:26 2026 -0400

    drm/amdgpu: make Mac FB workaround generic
    
    commit c7f44ec5c4ec760e74351f1843dcb8322f67cbf6 upstream.
    
    Rather than adding a case of every chip where this is seen
    just check if the FB is at 0 and the ssid is apple.  This
    should cover all chips which fall into this case.
    
    Tested-by: Ayhan Çiçek <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit c54e4d10507722398dc90cf3c532e50b86cf425a)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amdgpu: serialize vblank counter reads against GPU reset [+ + +]
Author: Vitaly Prosyak <[email protected]>
Date:   Tue Sep 29 20:18:26 2026 -0400

    drm/amdgpu: serialize vblank counter reads against GPU reset
    
    commit 1a6023edfbb5673f55fab6348f135fb3b1428ea5 upstream.
    
    The vblank counter callback reads display registers and scanout
    position without holding reset_domain->sem. During GPU recovery,
    display commit work can call the callback while reset owns the
    semaphore for writing. The hardware access then triggers the
    lockdep_assert_held() in amdgpu_device_skip_hw_access() and sets
    TAINT_WARN when lockdep is enabled.
    
    Try to acquire the reset semaphore for reading before accessing the
    hardware, and hold it across the counter and scanout-position reads.
    If reset is already in progress, return DRM's cached software vblank
    count instead. This avoids blocking behind reset and avoids accessing
    display hardware while it is being reset.
    
    The cached count is less accurate than the hardware count, but is
    used only when reset prevents a safe hardware read. This addresses
    the reset-time warning from this vblank path; it does not suppress or
    fix unrelated lockdep warnings.
    
    Cc: Christian König <[email protected]>
    Cc: Alex Deucher <[email protected]>
    Cc: Harry Wentland <[email protected]>
    Cc: Sunpeng Li <[email protected]>
    Signed-off-by: Vitaly Prosyak <[email protected]>
    Reviewed-by: Sunpeng Li <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit 51a4359f7431a4be5e42803c8bdaf7e0e5be2934)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/amdkfd: align SDMA doorbell base for shader doorbell writes [+ + +]
Author: Saleel Kudchadker <[email protected]>
Date:   Thu Sep 24 23:52:19 2026 +0000

    drm/amdkfd: align SDMA doorbell base for shader doorbell writes
    
    commit f145d5b3f740de05d85257acdc82f6877180f5c6 upstream.
    
    On GC 9.4.3, 9.4.4 and 9.5.0, doorbell writes issued from shaders are
    routed to an SDMA engine at 32-byte (4 doorbell index) granularity.
    SDMA engine doorbell ranges are 10 indices apart, so the range of every
    odd engine starts 2 indices into a 4-index block that begins in the
    previous engine's range. A shader ringing the doorbell of a queue on an
    odd engine therefore rings the previous engine instead. The intended
    queue never sees the doorbell, so its work stalls and the application
    hangs.
    
    Align the per-engine doorbell base up to a 4-index boundary on these
    ASICs. Each engine only uses 4 of its 10 indices, so the aligned base
    plus the queue offset stays within the engine's range. Even engines are
    already aligned, so only the doorbell IDs of odd-engine queues change.
    
    Only doorbells rung by the device itself are routed this way. Doorbell
    writes from the host, including the kernel's own SDMA rings, are not
    affected.
    
    The doorbell ID of an SDMA queue is saved in CRIU checkpoints and
    checked again on restore. A checkpoint taken before this change that
    contains an SDMA queue on an odd engine will fail to restore with
    -EINVAL. This is intentional: the restored process still holds the old
    doorbell address, so accepting the stale ID would bring back the same
    stall.
    
    Tested on MI300X with a shader-rung SDMA doorbell test: queues on odd
    engines hung before this change and complete with it.
    
    v2: use u32 instead of uint32_t for the new locals (checkpatch)
    v3: name the routing granularity, use dev->node_id, document the
        layout invariants, describe impact
    v4: express the granularity in doorbell indices, drop unrelated
        cleanups, explain the CRIU restore behavior, add test note
    
    Fixes: 6df442a03d1a ("drm/amdgpu: add new doorbell assignment table for aqua_vanjaram")
    Signed-off-by: Saleel Kudchadker <[email protected]>
    Reviewed-by: Felix Kuehling <[email protected]>
    Reviewed-by: Alex Deucher <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit ee1379e6d7da47bdf7a8d5b89c2d1b28473701fb)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info [+ + +]
Author: Haojie Li <[email protected]>
Date:   Fri Oct 2 10:29:27 2026 +0800

    drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info
    
    commit e6895021a328594368a2a19406a53ffca1ce51c7 upstream.
    
    When kzalloc fails for metadata_buffer in
    amdgpu_amdkfd_get_dmabuf_info(), the function returns -ENOMEM directly
    without calling dma_buf_put(), leaking the dma_buf reference obtained
    earlier via dma_buf_get().
    
    Fix both issues by:
    - Adding an error check after the first amdgpu_bo_get_metadata() call
    - Replacing the direct return with r = -ENOMEM and goto out_put to
      ensure dma_buf_put() is called on all error paths
    
    Fixes: f54ce9e8cbd3 ("drm/amdkfd: Let driver decide buffer size at AMDKFD_IOC_GET_DMABUF_INFO ioctl")
    Signed-off-by: Haojie Li <[email protected]>
    Signed-off-by: Alex Deucher <[email protected]>
    (cherry picked from commit ffa699553332f8caf8688d312279ddcea9e3c141)
    Cc: [email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/aspeed: Balance the display clock enable on teardown [+ + +]
Author: Myeonghun Pak <[email protected]>
Date:   Sun Sep 13 18:30:19 2026 -0400

    drm/aspeed: Balance the display clock enable on teardown
    
    [ Upstream commit ecce445c6489895463b7ddec2af66338287fee4c ]
    
    aspeed_gfx_load() enables the display clock without checking the return
    value and never disables it on probe failure or removal. devm_clk_get()
    only releases the clock reference, leaving the enable unbalanced.
    
    Use devm_clk_get_enabled() to handle enable failures and automatically
    disable and unprepare the clock on probe failure or removal.
    
    This issue was identified during our ongoing static-analysis research
    while reviewing kernel code.
    
    Fixes: 4f2a8f5898ec ("drm: Add ASPEED GFX driver")
    Co-developed-by: Ijae Kim <[email protected]>
    Signed-off-by: Ijae Kim <[email protected]>
    Signed-off-by: Myeonghun Pak <[email protected]>
    Assisted-by: OpenAI:GPT-5.6
    Reviewed-by: Thomas Zimmermann <[email protected]>
    Signed-off-by: Thomas Zimmermann <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Sasha Levin <[email protected]>

 
drm/bridge: Fix unlocked list access in drm_bridge_attach() [+ + +]
Author: Cristian Ciocaltea <[email protected]>
Date:   Tue Sep 1 21:50:38 2026 +0300

    drm/bridge: Fix unlocked list access in drm_bridge_attach()
    
    [ Upstream commit 57889076afd1be890150c32ffde3b691fe5707c8 ]
    
    drm_bridge_attach() inspects bridge->list to warn about bridges being
    attached without a previous drm_bridge_add() call, but it does so
    without holding bridge_lock.
    
    The list head can be concurrently written by drm_bridge_add(),
    drm_bridge_remove() and __drm_bridge_free() while they operate on
    neighbouring entries of bridge_list or bridge_lingering_list, all of
    them under bridge_lock.  Hence the unlocked read is a data race, even
    though it is unlikely to change the outcome of list_empty() in practice.
    
    Perform the check with bridge_lock held.
    
    Fixes: 76f1a9711b83 ("drm/bridge: add warning for bridges attached without being added")
    Signed-off-by: Cristian Ciocaltea <[email protected]>
    Reviewed-by: Luca Ceresoli <[email protected]>
    Tested-by: Luca Ceresoli <[email protected]>
    Tested-by: Igor Paunovic <[email protected]> # RK3588 Orange Pi 5 Plus, dual HDMI
    Tested-by: Robin Räber <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Luca Ceresoli <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/bridge: Fix unlocked list_del in drm_bridge_add() [+ + +]
Author: Cristian Ciocaltea <[email protected]>
Date:   Tue Sep 1 21:50:36 2026 +0300

    drm/bridge: Fix unlocked list_del in drm_bridge_add()
    
    [ Upstream commit b62e3db8cdc1680e1c3390591e872f485148541a ]
    
    When re-adding a bridge that was previously removed, drm_bridge_add()
    drops it from bridge_lingering_list without holding bridge_lock.
    
    Both bridge_list and bridge_lingering_list are protected by bridge_lock,
    as they are concurrently modified by drm_bridge_remove() and
    __drm_bridge_free(), and walked by the debugfs 'bridges' file.  Running
    the list_empty() test and the list_del_init() outside of the lock may
    therefore corrupt either list.
    
    Perform both under bridge_lock.
    
    Fixes: 17805a15d175 ("drm/bridge: add list of removed refcounted bridges")
    Reported-by: Sashiko <[email protected]>
    Closes: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Cristian Ciocaltea <[email protected]>
    Reviewed-by: Luca Ceresoli <[email protected]>
    Tested-by: Luca Ceresoli <[email protected]>
    Tested-by: Igor Paunovic <[email protected]> # RK3588 Orange Pi 5 Plus, dual HDMI
    Tested-by: Robin Räber <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Luca Ceresoli <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value [+ + +]
Author: Felix Gu <[email protected]>
Date:   Sat Mar 21 03:12:10 2026 +0800

    drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value
    
    commit add916cfcec5b71cb242db85b91b2437be7390cf upstream.
    
    The error check after calling dw_hdmi_probe() was incorrectly checking
    the struct pointer hdmi instead of the probe result hdmi->dw_hdmi.
    
    Fix this by checking the correct variable.
    
    Fixes: 96f30ee0fb9d ("drm/bridge: add a driver for T-Head TH1520 HDMI controller")
    Signed-off-by: Felix Gu <[email protected]>
    Reviewed-by: Dmitry Baryshkov <[email protected]>
    Cc: [email protected]
    Signed-off-by: Icenowy Zheng <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/bridge: th1520-dw-hdmi: Fix remove() callback [+ + +]
Author: Felix Gu <[email protected]>
Date:   Sat Mar 21 03:12:11 2026 +0800

    drm/bridge: th1520-dw-hdmi: Fix remove() callback
    
    commit 01c83795d50ccdb441f60e89ff50767cb2f6045a upstream.
    
    This driver stores struct th1520_hdmi * in platform drvdata, but
    th1520_dw_hdmi_remove() was reading it back as struct dw_hdmi *
    and passing it to dw_hdmi_remove(), so teardown runs on the wrong
    pointer.
    
    Retrieve struct th1520_hdmi * from platform drvdata and pass
    hdmi->dw_hdmi to dw_hdmi_remove().
    
    Fixes: 96f30ee0fb9d ("drm/bridge: add a driver for T-Head TH1520 HDMI controller")
    Signed-off-by: Felix Gu <[email protected]>
    Reviewed-by: Dmitry Baryshkov <[email protected]>
    Cc: [email protected]
    Signed-off-by: Icenowy Zheng <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/dp: don't mark the AUX backlight enabled when enabling failed [+ + +]
Author: Oleg Keri <[email protected]>
Date:   Fri Sep 25 15:25:58 2026 +0200

    drm/dp: don't mark the AUX backlight enabled when enabling failed
    
    [ Upstream commit 707ce102521496c67860d81221b20c56d8255f2f ]
    
    If drm_edp_backlight_enable() fails, dp_aux_backlight_update_status()
    still marks the backlight as enabled. From then on every brightness
    change only updates the level and the enable is never retried, so the
    panel stays dark until something blanks and unblanks the backlight.
    
    Return the error instead, so the next update tries to enable again.
    
    Fixes: 10f7b40e4f30 ("drm/panel: add basic DP AUX backlight support")
    Signed-off-by: Oleg Keri <[email protected]>
    Reviewed-by: Douglas Anderson <[email protected]>
    Signed-off-by: Douglas Anderson <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Sasha Levin <[email protected]>

 
drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN [+ + +]
Author: Nguyen Ngoc Thang <[email protected]>
Date:   Sun Sep 27 14:54:34 2026 +0700

    drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN
    
    commit 755c94d178b7e972bb766199d34e4ba4f63a89eb upstream.
    
    __drm_fb_helper_initial_config_and_unlock() calls
    drm_client_modeset_probe() first, which already fills in each
    mode_set->mode/num_connectors for every connected output, and only
    afterwards calls drm_fb_helper_single_fb_probe() to create
    fb_helper->fb and wire it into those mode_sets via
    drm_setup_crtcs_fb().
    
    If drm_fb_helper_single_fb_probe() fails with anything other than
    -EAGAIN (e.g. dev->driver->fbdev_probe() itself fails), the function
    bails out before drm_setup_crtcs_fb() runs and before setting
    fb_helper->deferred_setup. The client is left with mode_sets that
    have a mode and connectors but mode_set->fb == NULL, and nothing
    marks this fb_helper as needing a retry.
    
    __drm_fb_helper_restore_fbdev_mode_unlocked() only skips committing
    when fb_helper->deferred_setup is set, so a later .restore() call
    (drm_lastclose() on process exit, in this report) commits the stale
    mode_set through drm_client_modeset_commit() ->
    drm_client_modeset_commit_atomic() -> __drm_atomic_helper_set_config(),
    which hits WARN_ON(!set->fb).
    
    Mark fb_helper->deferred_setup on any drm_fb_helper_single_fb_probe()
    failure, not just -EAGAIN, so restore keeps skipping the commit until
    a later hotplug event successfully re-probes and re-populates
    mode_set->fb. The real error code is still returned to the caller
    unchanged.
    
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=ca23c8570669ead78867
    Fixes: ca91a2758fce ("drm/fb-helper: Support deferred setup")
    Cc: [email protected]
    Signed-off-by: Nguyen Ngoc Thang <[email protected]>
    Signed-off-by: Thomas Zimmermann <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/gud: don't keep a connector without a CRTC as connector_state [+ + +]
Author: Sajal Gupta <[email protected]>
Date:   Tue Sep 22 14:10:08 2026 +0530

    drm/gud: don't keep a connector without a CRTC as connector_state
    
    commit 71ec70ea26e399eb8371fe9d2d5bf5dab09570fb upstream.
    
    If the 'for_each_new_connector_in_state()' loop finishes without
    hitting the break, connector_state is left pointing at the last
    connector visited, which has no CRTC, instead of
    staying NULL.
    
    That skips the "if (!connector_state)" fallback below the loop, which
    looks up the active connector when the state contains none. The
    function then carries on with a connector that is not driven.
    
    Fix by resetting connector_state to NULL for each connector visited that
    has no CRTC, so that it is NULL when none was found and the fallback runs.
    
    Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
    Reported-by: Sashiko <[email protected]>
    Link: https://sashiko.dev/#/patchset/[email protected]?part=1
    Signed-off-by: Sajal Gupta <[email protected]>
    Acked-by: Ruben Wauters <[email protected]>
    Cc: <[email protected]>
    Signed-off-by: Ruben Wauters <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/i915/gem: Prevent overstepping exec array boundary [+ + +]
Author: Krzysztof Karas <[email protected]>
Date:   Fri Sep 11 06:11:45 2026 +0000

    drm/i915/gem: Prevent overstepping exec array boundary
    
    commit ebe162db655881a38de43301151ff7ac940602b5 upstream.
    
    It is possible for eb_relocate_parse_slow() to call kvfree() on
    entries outside the original exec array during following
    scenario inside eb_relocate_parse_slow():
    
    1) eb_copy_relocations() allocates as many as eb->buffer_count
       copies for exec entries;
    2) eb_parse() appends up to two VMAs, right after incrementing
       eb->buffer_count;
    3) cleanup under "out" label uses this incremented buffer_count
       to release relocation pointers from exec array via kvfree(),
       not from VMA array.
    
    To amend this problem, ensure that relocation cleanup uses the
    original exec object count, excluding the VMAs appended by the
    command parser.
    
    Fixes: 8e4ba491b0ba ("drm/i915: Parse command buffer earlier in eb_relocate(slow)")
    Signed-off-by: Krzysztof Karas <[email protected]>
    Assisted-by: GitHub-Copilot:gpt-6-astra
    Cc: [email protected] # 5.10+
    Reviewed-by: Andi Shyti <[email protected]>
    Signed-off-by: Andi Shyti <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    (cherry picked from commit 2a0158925fb943c7ba8f3216e2734952128defc9)
    Signed-off-by: Jani Nikula <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/i915/gt: Unmask interrupts only when ACTIVE is true [+ + +]
Author: Krzysztof Karas <[email protected]>
Date:   Thu Sep 10 08:13:29 2026 +0000

    drm/i915/gt: Unmask interrupts only when ACTIVE is true
    
    commit 5346b1cec6afa4f9b4b49a9f84e3cfef95a3f7bb upstream.
    
    There is a small race window between intel_rps_boost() reading
    a stale ACTIVE state and queuing rps->work, where ACTIVE may be
    changed via asynchronous calls triggered by wakeref drop.
    This means that rps_work() could be triggered after the GT has
    been parked, so unmasking RPS PM interrupts would happen without
    holding PM wakelock. This sequence of events may be observed
    during live_rc6_ctx_wa() selftest:
    
    1) live_rc6_ctx_wa()
       -> intel_engine_pm_put()
          -> wakeref_put()
    
    ASYNC1) wakeref_put() callback
              -> __engine_park()
                 -> intel_gt_pm_put_async()
                    -> intel_gt_pm_put_async_untracked()
                       -> intel_wakeref_put_async()
    
    ASYNC2) wakeref_put_async() callback
              -> __gt_park()
                 -> intel_rps_park()
                    -> intel_rps_clear_active() [clear ACTIVE]
                    WITH INTERRUPTS:
                    -> rps_disable_interrupts()
                       -> cancel_work_sync(rps->work)
                       -> rps_reset_interrupts() [rps->pm_iir = 0]
                    WITHOUT INTERRUPTS (TIMER mode):
                    -> rps_stop_timer()
                       -> cancel_work_sync(rps->work)
    
    2) live_rc6_ctx_wa()
       -> intel_gt_wait_for_idle()
          -> intel_gt_retire_requests_timeout()
             -> dma_fence_wait_timeout()
                -> ops->wait() [i915_fence_wait()]
                   -> i915_request_wait_timeout()
                      -> intel_rps_boost()
                         -> intel_rps_is_active() [check ACTIVE]
                            [OPEN RACE WINDOW]
                         -> queue_work(rps->work)
             -> retire_requests()
                -> i915_request_retire()
                   -> intel_rps_dec_waiters() [from 1 to 0]
    
    If ASYNC1 and ASYNC2 would execute during [OPEN RACE WINDOW],
    then:
    
    3) rps_work() executes from the workqueue and may satisfy
       "(!pm_iir && !client_boost)" test (in TIMER mode rps->pm_iir
       is zeroed by an earlier rps_work() call or never gets a new
       value after previous intel_rps_unpark() event), so it jumps
       to "out" label, bypassing intel_rps_is_active() guard and
       executes gen6_gt_pm_unmask_irq();
    
    4) GT is parked and runtime PM wakelock is dropped, so only
       a raw reference in __gt_park() ->
       intel_display_power_put_async() remains for 100ms, then the
       MMIO write in gen6_gt_pm_unmask_irq() detects missing
       wakelock via assert_rpm_wakelock_held() and emits
       "RPM wakelock ref not held during HW access" tainting kernel.
    
    Commit 3e7abf814193 ("drm/i915: Extract GT render power state management")
    dropped the "if (rps->interrupts_enabled)" guard that
    gen6_pm_rps_work() had around this unmask in i915_irq.c.
    INTEL_RPS_ACTIVE brackets the same window, since it is set in
    intel_rps_unpark() before rps_enable_interrupts() and
    rps_start_timer() and cleared in intel_rps_park() before
    rps_stop_timer() and rps_disable_interrupts().
    
    Skip unmasking when RPS is no longer active (reaching unmask
    operation is independent of INTERRUPT mode). This does not
    prevent RPS operation from resuming on the next unpark.
    In interrupt mode, intel_rps_unpark() calls
    rps_enable_interrupts(), which enables and unmasks the PM
    interrupts. In timer mode, it calls rps_start_timer(),
    restarting periodic engine-busyness evaluation. The timer
    generates software RPS events and queues rps_work() directly,
    independently of PM interrupt delivery. Neither mode requires
    the late worker to unmask interrupts while the GT is parked
    
    Fixes: 3e7abf814193 ("drm/i915: Extract GT render power state management")
    Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16562
    Cc: [email protected] # v5.5+
    Assisted-by: GitHub-Copilot:claude-opus-5
    Assisted-by: GitHub-Copilot:gpt-6-astra
    Signed-off-by: Krzysztof Karas <[email protected]>
    Reviewed-by: Andi Shyti <[email protected]>
    Signed-off-by: Andi Shyti <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    (cherry picked from commit ca4a6deadad15b91ee083afe445fa6bdbfb68206)
    Signed-off-by: Jani Nikula <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/imagination: Fix reference and vm_bo handling in remap() [+ + +]
Author: Gyeyoung Baek <[email protected]>
Date:   Thu Oct 1 22:39:12 2026 +0900

    drm/imagination: Fix reference and vm_bo handling in remap()
    
    [ Upstream commit 196d4d10c1b33ae176685ff42a9994a5952b1d0f ]
    
    When a map overlaps part of an existing mapping, pvr_vm_gpuva_remap()
    splits the mapping into prev/next parts covering what the request did
    not take, instead of creating something new. It gets two things wrong.
    
    - A GEM reference is taken for each part but it's never needed and never
      dropped, so it leaks one reference per split (remap-next-in-2m in
      tests/imagination/pvr_vm_map.c):
    
        CRITICAL: 33558528 bytes of shmem still held after close
    
    - The parts still belong to the original object being split, but
      pvr_vm_gpuva_remap() links them to ctx->gpuvm_bo, the new object's
      vm_bo:
    
        prev_va --obj--> BO_A          BO_B <--obj-- vm_bo (ctx->gpuvm_bo)
                \___________link___________/  (mismatch: BO_A != BO_B)
    
      drm_gpuva_link() catches the mismatch:
    
        WARNING: drivers/gpu/drm/drm_gpuvm.c:2108 at drm_gpuva_link+0x2ec/0x310
          drm_WARN_ON(obj != vm_bo->obj)
        Call trace:
         drm_gpuva_link
         pvr_vm_gpuva_remap
         __drm_gpuvm_sm_map
         pvr_vm_map
         pvr_ioctl_vm_map
    
      Link them to op->remap.unmap->va->vm_bo instead.
    
    The locking of the GPUVA lists of the other objects touched by a split is
    not addressed here; it is handled by switching the GPUVM to immediate
    mode.
    
    Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
    Signed-off-by: Gyeyoung Baek <[email protected]>
    Reviewed-by: Brajesh Gupta <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Alessio Belle <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/imagination: Size page table preallocation by device address [+ + +]
Author: Gyeyoung Baek <[email protected]>
Date:   Thu Oct 1 22:39:13 2026 +0900

    drm/imagination: Size page table preallocation by device address
    
    commit 789f290b2e81d42820bddcb4010ffbc2ae2ded54 upstream.
    
    Commit 0a8224058a58 ("drm/imagination: Fix page count for page table for
    map() interface") passed the device address to
    pvr_mmu_op_context_create(), but the preallocation is still sized from
    device_addr + sgt_offset with an exclusive end. The offset into the
    object's pages has no place in a device-virtual range, and the exclusive
    end allocates one table too many when the range ends on a table
    boundary.
    
    Count the tables from device_addr and the inclusive end of the range.
    
    The new calculation does not take page table indices into account. This
    fixes another issue with the previous implementation, where the
    difference between start and end indices could underflow when a mapping
    crossed a page table boundary. This would lead to the driver
    preallocating a huge number of MMU pages, exhausting system memory and
    triggering an out of memory panic.
    
    Fixes: 0a8224058a58 ("drm/imagination: Fix page count for page table for map() interface")
    Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
    Signed-off-by: Gyeyoung Baek <[email protected]>
    Reviewed-by: Brajesh Gupta <[email protected]>
    Reviewed-by: Alessio Belle <[email protected]>
    Cc: [email protected]
    [Alessio: add paragraph to point out OOM bug being fixed, cc stable]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Alessio Belle <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/panthor: validate userspace queue count against initialized firmware slot count [+ + +]
Author: Osama Abdelkader <[email protected]>
Date:   Tue Aug 4 18:00:47 2026 +0200

    drm/panthor: validate userspace queue count against initialized firmware slot count
    
    commit ec86c43dcfff68eab4db9bdafcd3e2b16e342e18 upstream.
    
    In panthor_drv.c:panthor_ioctl_group_create(),
    the queue count is validated against the hardcoded maximum:
    
            if (!args->queues.count || args->queues.count > MAX_CS_PER_CSG)
                    return -EINVAL;
    
    However, if the firmware reports fewer slots than MAX_CS_PER_CSG,
    panthor_fw_init_ifaces() will only initialize that smaller number of
    stream interfaces.
    
    If unprivileged userspace requests more queues than the firmware reported
    (but no more than MAX_CS_PER_CSG), cs_slot_prog_locked() fetches an
    uninitialized stream interface and may crash when dereferencing
    cs_iface->input->ringbuf_base.
    
    Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
    Cc: [email protected]
    Reported-by: [email protected]
    Closes: https://sashiko.dev/#/patchset/[email protected]?part=1
    Signed-off-by: Osama Abdelkader <[email protected]>
    Reviewed-by: Steven Price <[email protected]>
    Reviewed-by: Liviu Dudau <[email protected]>
    Reviewed-by: Boris Brezillon <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Steven Price <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/vc4: Disable the V3D interrupt across runtime suspend [+ + +]
Author: Maíra Canal <[email protected]>
Date:   Fri Sep 25 16:10:19 2026 -0300

    drm/vc4: Disable the V3D interrupt across runtime suspend
    
    [ Upstream commit 6abc8e4dcfbc1d26a94c0ac037dfb3716f686b1f ]
    
    vc4_irq_disable() masks the V3D interrupt sources and then calls
    synchronize_irq() before the V3D is powered down. However, by itself,
    this is not enough to quiesce the interrupt handler.
    
    synchronize_irq() waits for handlers that have already set
    IRQD_IRQ_INPROGRESS, and for irqchips reporting IRQCHIP_STATE_ACTIVE.
    A GIC interrupt chip is able to mark an interrupt active as soon as a
    CPU acknowledges it, so there these checks cover the whole dispatch path.
    On RPi 0-3, however, the interrupt controller is ARMCTRL, which has no
    active state. A CPU that has read the hwirq out of the pending register
    but has not yet reached handle_level_irq() stays invisible to
    synchronize_irq().
    
    During a power transition, vc4_irq() may therefore run after the power
    domain is off, where every V3D register read will return 0xdeadbeef.
    0xdeadbeef has FLDONE, FRDONE and OUTOMEM set. This problem doesn't
    trigger NULL pointer dereference issues only because the functions
    vc4_irq_finish_bin_job() and vc4_irq_finish_render_job() return early
    when there is no job pointer, but OUTOMEM is still able to schedule
    vc4_overflow_mem_work() after vc4_irq_disable() has already cancelled it.
    
    Therefore, fix the spurious interrupts by disabling the interrupt line
    across the PM transition. To preserve the enable/disable balance, move
    vc4_irq_install() and request the IRQ line disabled before the first
    runtime resume.
    
    Fixes: 9b6f461582e6 ("drm/vc4: v3d: Stop disabling interrupts")
    Reviewed-by: Iago Toral Quiroga <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/vc4: drain the hangcheck timer and works on V3D unbind [+ + +]
Author: Fan Wu <[email protected]>
Date:   Tue Sep 15 09:51:03 2026 +0000

    drm/vc4: drain the hangcheck timer and works on V3D unbind
    
    commit 94cf5971b1d04c6382437387c4dc3836cc7a1437 upstream.
    
    Nothing stops the hangcheck timer that submitted jobs arm, or the
    job_done_work that the render-done interrupt queues, at teardown:
    vc4_irq_disable() cancels only overflow_mem_work, and vc4_gem_destroy()
    runs from the drm-managed release, after vc4_v3d_unbind() has already
    uninstalled the V3D interrupt and cleared vc4->v3d. A timer still armed
    by then reads V3D registers through the NULL vc4->v3d pointer, and the
    late callbacks run on the vc4_dev embedding them after it has been
    freed.
    
    Drain them in vc4_v3d_unbind(): shut the timer down and cancel
    reset_work before the interrupt is taken down, because its
    vc4_irq_reset() re-enables it, then flush job_done_work so that
    completions queued at teardown still release their jobs.
    
    This issue was found by an in-house static analysis tool.
    
    Fixes: d5b1a78a772f ("drm/vc4: Add support for drawing 3D frames.")
    Cc: [email protected] # 6.2+
    Assisted-by: Codex:gpt-5.6
    Co-developed-by: Song Li <[email protected]>
    Signed-off-by: Song Li <[email protected]>
    Signed-off-by: Fan Wu <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Reviewed-by: Maíra Canal <[email protected]>
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/vc4: Fix binner slot allocation failing on an idle GPU [+ + +]
Author: Maíra Canal <[email protected]>
Date:   Wed Sep 30 15:20:44 2026 -0300

    drm/vc4: Fix binner slot allocation failing on an idle GPU
    
    [ Upstream commit cca01232d94adcb10f7c8c5bb8ce072b045fcb58 ]
    
    A job's binner slots are returned to bin_alloc_used by vc4_complete_exec(),
    which runs from the job_done workqueue, but the seqno
    vc4_v3d_get_bin_slot() waits on is incremented earlier, in the function
    vc4_irq_finish_render_job(). Therefore, a waiter can wake, retry, and still
    find the pool full because the worker has not run. By then, the job might
    have left the render_job_list, so no seqno remains to wait on and the
    allocation fails returning -ENOMEM.
    
    This scenario can be reproduced on a Raspberry Pi 3 by using a burst of
    small jobs (e.g. Piglit's `quick_gl` suite), with userspace seeing a
    rejected submit for a pool about to become free.
    
    Note that the slots are held from validation until the render completes,
    so the pool can also be exhausted by jobs still queued on bin_job_list,
    leaving render_job_list empty and nothing to wait on.
    
    Release the slots from the FRDONE handler and wait on the pool instead of
    on one job's seqno. This bounds the wait to the actual resource. Also, by
    claiming the slot inside the wait condition, another submit is unable to
    take the slot between the wakeup and the retry. vc4_complete_exec() keeps
    clearing the slots for jobs that never completed, and now wakes the
    waiters too.
    
    Note that the wait takes a deadline, since the two callers need different
    ones. The submit path is a user task and can be interrupted, so it waits
    without one. On the other hand, vc4_overflow_mem_work() runs on a worker
    and never sees a signal, so it needs a deadline. During a reset,
    vc4_irq_disable() masks V3D_DRIVER_IRQS before draining the worker, and
    with those masked nothing can release a slot. This deadlocks: the worker
    would wait for slots that only the reset can free, while the reset waits
    in cancel_work_sync() for the worker.
    
    Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.")
    Reviewed-by: Iago Toral Quiroga <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/vc4: Fix firmware reference leak in vc4_drm_bind() [+ + +]
Author: Wentao Liang <[email protected]>
Date:   Wed Sep 16 15:40:15 2026 +0000

    drm/vc4: Fix firmware reference leak in vc4_drm_bind()
    
    commit b816da5d5df1461446a0a5f3fe2b4948a659a790 upstream.
    
    The firmware reference obtained via rpi_firmware_get() is leaked when
    aperture_remove_all_conflicting_devices() fails, as the error label
    returns without putting it. This happens before the firmware is
    consumed and put further down in the function.
    
    Put the firmware reference before jumping to err.
    
    Fixes: c406ad5e4a85 ("drm/vc4: Notify the firmware when DRM is in charge")
    Cc: [email protected]
    Signed-off-by: Wentao Liang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Reviewed-by: Maíra Canal <[email protected]>
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/vc4: Free the BO cache size list on teardown [+ + +]
Author: Maíra Canal <[email protected]>
Date:   Wed Sep 30 16:06:50 2026 -0300

    drm/vc4: Free the BO cache size list on teardown
    
    [ Upstream commit b41ff8b529278216cba22a5dcdc93fea2a3a9619 ]
    
    vc4_bo_cache_destroy() purges the cached BOs but never frees the size
    list, leaking it on every unbind.
    
    Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
    Assisted-by: LLM
    Reviewed-by: Thadeu Lima de Souza Cascardo <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/vc4: Use kvmalloc_objs() for the BO cache size list [+ + +]
Author: Maíra Canal <[email protected]>
Date:   Wed Sep 30 16:06:51 2026 -0300

    drm/vc4: Use kvmalloc_objs() for the BO cache size list
    
    [ Upstream commit bca45af5998a05f34b13a2ef11e639bac9c62643 ]
    
    The BO cache size list has one entry per BO page count, so its size
    scales with the largest BO ever freed. A 64 MiB BO already needs at
    least an order-6 allocation, which fails under fragmentation and
    triggers a warn_alloc() splat on BO close:
    
      page allocation failure: order:7, mode:0x40cc0(GFP_KERNEL|__GFP_COMP)
      Call trace:
       ...
       warn_alloc+0x118/0x190
       __alloc_pages_slowpath+0x4a8/0x520
       ...
       __kmalloc_noprof+0x3ac/0x5d8
       vc4_free_object+0x128/0x370 [vc4]
       drm_gem_object_handle_put_unlocked+0xb8/0x158 [drm]
       drm_gem_object_release_handle+0x74/0xe8 [drm]
       drm_gem_handle_delete+0x6c/0xa8 [drm]
       drm_gem_close_ioctl+0x34/0x50 [drm]
    
    The list doesn't need physically contiguous memory. Use kvmalloc_objs()
    so large lists can fall back to vmalloc(), avoiding the allocation
    failure.
    
    Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
    Reviewed-by: Thadeu Lima de Souza Cascardo <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Maíra Canal <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
drm/vmwgfx: validate pitch coming from userspace [+ + +]
Author: Zack Rusin <[email protected]>
Date:   Sun Aug 9 16:45:15 2026 -0400

    drm/vmwgfx: validate pitch coming from userspace
    
    commit 21bc51cb89ced74d6645a138cc2f21184bc75094 upstream.
    
    Validate the pitch, alongside the box dimensions before trying
    to copy data from the underlying surface. Fixes possible
    out of bounds reads with cursor snooping.
    
    Fixes: 2ac863719e51 ("vmwgfx: Snoop DMA transfers with non-covering sizes")
    Cc: [email protected]
    Reported-by: Youness HFA <[email protected]>
    Signed-off-by: Zack Rusin <[email protected]>
    Reviewed-by: Maaz Mombasawala <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/xe/i2c: cancel the client work on remove [+ + +]
Author: Fan Wu <[email protected]>
Date:   Mon Oct 5 20:04:14 2026 -0400

    drm/xe/i2c: cancel the client work on remove
    
    commit 611857adc9e7b0ee1239a0baf38498922ca5a12e upstream.
    
    xe_i2c_notifier() stores the DesignWare adapter in i2c->adapter and
    schedules i2c->work when the adapter is registered under the xe I2C
    platform device, and xe_i2c_client_work() then instantiates the AMC
    client device on that adapter.
    
    xe_i2c_remove() tears down the AMC, unregisters the client devices,
    the bus notifier and the adapter platform device, but it never drains
    i2c->work. A work item that is still queued or running when the
    adapter is unregistered dereferences i2c->adapter in
    i2c_new_client_device() after platform_device_unregister() has
    released the adapter. The work item is also embedded in the
    devm-allocated struct xe_i2c, so a work item still queued after the
    drm device devm unwind frees that allocation runs its callback on
    freed memory.
    
    The bus notifier is the only thing that schedules this work, and it is
    unregistered after the client devices. An instance that is still queued
    when the teardown runs can therefore write
    i2c->client[XE_I2C_CLIENT_AMC] while the loop is unregistering and
    clearing the same array, and an AMC client it instantiates late is only
    cleaned up by the adapter's own child sweep in i2c_del_adapter().
    
    Move bus_unregister_notifier() in front of the client teardown loop
    and cancel the work right after it, so no new instance can be
    scheduled and a queued instance is drained before the client array is
    touched. A running instance still finds a live adapter, since the
    adapter is unregistered later.
    
    Fixes: f0e53aadd702 ("drm/xe: Support for I2C attached MCUs")
    Link: https://lore.kernel.org/intel-xe/[email protected]/
    Cc: [email protected]
    Assisted-by: LLM, in-house static analysis tool
    Co-developed-by: Song Li <[email protected]>
    Signed-off-by: Song Li <[email protected]>
    Signed-off-by: Fan Wu <[email protected]>
    Reviewed-by: Heikki Krogerus <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Rodrigo Vivi <[email protected]>
    (cherry picked from commit a23f27d5ec11c3f418c5e5531eea34ccda2b5b20)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums [+ + +]
Author: Alan Previn <[email protected]>
Date:   Tue Sep 29 12:20:37 2026 -0700

    drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums
    
    [ Upstream commit e7ed652b1312ffcb9ea2153946615856b5097c78 ]
    
    Check for overflow in udelay use in __xe_mmio_wait32 and
    avoid growing delays becoming intollerably large by capping the
    in-loop wait time.
    
    v7: - Change assisted-by to "LLM" (Rodrigo).
        - Move the max-wait macro to outside the function (Rodrigo).
    v6: - Fix commit message to remove items dropped in v5. Fix the
          use of MAX_UDELAY_MS for microsecond unit. (Shasiko review).
    v5: - Simplify: don't introduce additional redesign and
          use min_t with a backoff to cap wait. (Rodrigo).
    v4: - Simplify using poll_timeout_us and poll_timeout_us_atomic and
          update all callers to never use a param for atomic (Jani)
    v3: - Use div64_s64 kernel API for 32-bit vs 64-bit division.
    v2: - Fixed checkpatch failure.
        - Added helper for 64-bit DIV_ROUND_UP on 32-bit CPU (Shasiko
          review). Fixed bug max range in usleep_range(Shasiko review)
    
    Fixes: 5c09bd6ccd41 ("drm/xe/mmio: Move xe_mmio_wait32() to xe_mmio.c")
    Signed-off-by: Alan Previn <[email protected]>
    Reviewed-by: Rodrigo Vivi <[email protected]>
    Assisted-by: LLM
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Rodrigo Vivi <[email protected]>
    (cherry picked from commit 70dab9ee7d620e6018a64798aed065d14e9baed1)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
drm/xe/sysctrl: Fix mailbox header handling [+ + +]
Author: Mallesh Koujalagi <[email protected]>
Date:   Thu Sep 24 11:39:07 2026 +0530

    drm/xe/sysctrl: Fix mailbox header handling
    
    [ Upstream commit f0a4447789ef28ba1aded2db19543d69c640b5e5 ]
    
    The mailbox header was defined as __le32, which required
    cpu_to_le32() and le32_to_cpu() conversions whenever it was
    write or read.
    
    These conversions are unnecessary because the header is always
    handled as a 32-bit value, not as raw bytes. It is written with
    xe_mmio_write32() and read with xe_mmio_read32(), which already
    handle any required byte-order conversion through the underlying
    writel()/readl() accessors.
    
    As a result, the header value is already in CPU byte order when
    used by the driver. Keeping the extra conversions had no effect
    on little-endian systems and could cause an incorrect on
    big-endian systems.
    
    So use u32 for the mailbox header and remove the unnecessary
    endianness conversions.
    
    Fixes: 1f95f618182b ("drm/xe/xe_sysctrl: Add System Controller mailbox communication support")
    Suggested-by: Michal Wajdeczko <[email protected]>
    Signed-off-by: Mallesh Koujalagi <[email protected]>
    Tested-by: Anoop Vijay <[email protected]>
    Reviewed-by: Umesh Nerlige Ramappa <[email protected]>
    Signed-off-by: Umesh Nerlige Ramappa <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    (cherry picked from commit 5137b391599579371c32f555958d3cf55e19bd88)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
drm/xe: Do not emit Wa_16010904313 twice [+ + +]
Author: Tvrtko Ursulin <[email protected]>
Date:   Fri Sep 25 09:00:16 2026 +0100

    drm/xe: Do not emit Wa_16010904313 twice
    
    [ Upstream commit f7fc61e66041b1f8300cad87005ba84604bfefd9 ]
    
    During development of commit e8372edec948 ("drm/xe/xelp: Implement
    Wa_16010904313")
    one of the interim patch versions contained an incorrect rebase on top of
    some upstream changes, which caused Wa_16010904313 to be emitted both from
    the indirect context and from the workaround batch buffer.
    
    As this workaround needs to be emitted from the indirect context for rcs
    and ccs, but from the workaround batch buffer for bcs, vcs and vecs, we
    need to pass the location as an input parameter to setup_timestamp_wa() so
    it can decide whether to emit itself or not.
    
    Signed-off-by: Tvrtko Ursulin <[email protected]>
    Fixes: e8372edec948 ("drm/xe/xelp: Implement Wa_16010904313")
    Cc: Matt Roper <[email protected]>
    Cc: Rodrigo Vivi <[email protected]>
    Reviewed-by: Matt Roper <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Rodrigo Vivi <[email protected]>
    [Rodrigo: small adjustments on commit message for check-patch]
    (cherry picked from commit 38631a7bce195b88814b93bf2b6d3e48c827fef2)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

drm/xe: Fix shrinker accounting double-subtraction on nested external pins [+ + +]
Author: Thomas Hellström <[email protected]>
Date:   Fri Oct 2 12:08:29 2026 +0200

    drm/xe: Fix shrinker accounting double-subtraction on nested external pins
    
    commit 83d5acca1f4f6132038ea88c72c5844f62e42d44 upstream.
    
    xe_bo_pin_external() and xe_bo_unpin_external() support nested pins,
    since the underlying ttm_bo_pin()/ttm_bo_unpin() maintain a pin_count
    refcount rather than a boolean. However, the shrinker accounting calls
    xe_ttm_tt_account_subtract() and xe_ttm_tt_account_add() are invoked
    unconditionally on every pin_external()/unpin_external() call, instead
    of only on the transition into and out of the pinned state.
    
    An external BO (dma-buf) can be pinned more than once while already
    pinned, for example when it has multiple attachments/importers, each
    independently calling xe_bo_pin_external(). Each such nested pin
    subtracts the BO's pages from the shrinker's accounting again, even
    though the BO's pages were already removed from consideration by the
    first pin. Symmetrically, each nested unpin adds them back again
    before the BO is actually unpinned. This desynchronizes the
    shrinker's page and object counts from reality, and since they are
    declared as signed long but interpreted as unsigned long in
    xe_shrinker_count(), the underflow can turn into an enormous
    shrinkable/purgeable page count, causing the shrinker to be invoked
    excessively under memory pressure.
    
    Guard the accounting calls with the same pin-count transition checks
    already used to guard the pinned_link list maintenance, so accounting
    is only updated on the outermost pin and the final unpin.
    
    While centralizing this logic into xe_bo_account_pin()/
    xe_bo_account_unpin(), also close a second, related accounting gap
    affecting imported dma-bufs. For an imported bo's ttm_tt, xe's
    ttm_tt_populate hook (xe_ttm_tt_populate()) early-returns without
    calling xe_ttm_tt_account_add(), since TTM_TT_FLAG_EXTERNAL is set
    without TTM_TT_FLAG_EXTERNAL_MAPPABLE. However, TTM core's
    ttm_tt_populate() wrapper unconditionally marks the tt as populated
    on driver-hook success, so ttm_tt_is_populated() still reports true
    for it. xe_bo_account_pin()/xe_bo_account_unpin() trusted
    ttm_tt_is_populated() as a proxy for "these pages are accounted for
    by the shrinker", and would subtract/add pages for such a tt that
    were never added in the first place, again underflowing the
    shrinker's counts. This is reachable today via xe_bo_pin_external(),
    and would have become newly reachable via the fb-pin path once this
    patch routes __xe_pin_fb_vma() through xe_bo_pin_account() below, so
    fix it here rather than in a later patch, to avoid a commit in this
    series that introduces the regression before fixing it. Skip the
    accounting for imported bos, using the same EXTERNAL &&
    !EXTERNAL_MAPPABLE test xe_ttm_tt_populate()/xe_ttm_tt_unpopulate()
    use to decide whether to act, via a new xe_ttm_bo_is_imported()
    helper (hoisted up from its only prior use site).
    
    v2:
    - Fix the critical issue caught by Sashiko AI review: the pin-count
      transition check introduced here was still bypassed by the fb-pin
      path (__xe_pin_fb_vma()/__xe_unpin_fb_vma()), which could leave a
      stale pinned_link entry and a permanent shrinker accounting leak
      when the fb-unpin performed the true last unpin. Addressed in a
      separate follow-up patch in this series rather than folded in here,
      since it is a distinct bug with its own Fixes: tag.
    - Drop the unneeded local "last_unpin" variable in
      xe_bo_unpin_external(), restoring the original inline
      bo->ttm.pin_count == 1 check; it was a no-op rename not used by any
      of the new accounting helpers, and was going to be deleted again by
      the follow-up patch anyway.
    
    v3:
    - Exclude imported dma-bufs from the pin/unpin shrinker accounting,
      fixing another underflow caught by Sashiko AI review.
    - Add a short comment on the backup-object pin site noting it's
      already populated/accounted at pin time, addressing (as a
      false-positive clarification, no code fix needed) a separate
      Medium-severity accounting-leak concern also caught by Sashiko AI
      review.
    
    Fixes: 00c8efc3180f ("drm/xe: Add a shrinker for xe bos")
    Cc: Thomas Hellström <[email protected]>
    Cc: Matthew Brost <[email protected]>
    Cc: Rodrigo Vivi <[email protected]>
    Cc: [email protected]
    Cc: <[email protected]> # v6.15+
    Reviewed-by: Matthew Auld <[email protected]>
    Reviewed-by: Himal Prasad Ghimiray <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Thomas Hellström <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    (cherry picked from commit 6a117a2bb7ca657e3a19f83f4c06265d38dee06c)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin [+ + +]
Author: Thomas Hellström <[email protected]>
Date:   Fri Oct 2 12:08:30 2026 +0200

    drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin
    
    commit cf238c067eaae1cbfb00738e29219b9568d2313e upstream.
    
    xe_bo_pin_external() and xe_bo_unpin_external() maintain the bo's
    pinned_link list membership in xe->pinned.late.external, based on
    whether the current call is the outermost pin or the final unpin.
    However, the same external bo's pin_count can also be raised and
    lowered directly by __xe_pin_fb_vma()/__xe_unpin_fb_vma(), which pin
    the bo as a display scanout buffer without going through
    xe_bo_pin_external()/xe_bo_unpin_external() at all, and have no
    notion of, or ownership over, pinned_link.
    
    If a bo is pinned both externally (e.g. dma-buf export) and as an fb,
    and the external unpin happens first, xe_bo_unpin_external() correctly
    observes pin_count > 1 and leaves the bo on pinned_link. When the fb
    unpin later performs the true last unpin (pin_count 1 -> 0), it never
    touches pinned_link, leaving the bo linked on xe->pinned.late.external
    indefinitely. Once the bo is subsequently freed, this stale list entry
    points into freed memory, corrupting the list and risking a
    use-after-free the next time the list is walked or spliced.
    
    The backup object pin/unpin sites in xe_bo_notifier_prepare_pinned()/
    xe_bo_notifier_unprepare_pinned() have the same bypass characteristic,
    though they never add their bo to a pinned list, so are not affected
    by this particular list-corruption issue.
    
    Move the pinned_link removal into xe_bo_account_unpin(), which already
    runs on every unpin path (kernel, external, framebuffer, backup
    object) right before the true 1 -> 0 pin_count transition. Since
    list_del_init() only operates on the node itself, this removal is
    list-agnostic and safe to perform regardless of which list (external
    or kernel_bo_present) the bo happens to be linked on, or which code
    path is performing the final unpin. Drop the now-redundant explicit
    list_del_init() calls in xe_bo_unpin_external() and xe_bo_unpin().
    
    v2:
    - New patch
    
    v3:
    - Rebased on changes to previous patch.
    
    Fixes: 44e694958b95 ("drm/xe/display: Implement display support")
    Cc: Maarten Lankhorst <[email protected]>
    Cc: Rodrigo Vivi <[email protected]>
    Cc: [email protected]
    Cc: <[email protected]> # v6.8+
    Reviewed-by: Matthew Auld <[email protected]>
    Reviewed-by: Himal Prasad Ghimiray <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Thomas Hellström <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    (cherry picked from commit ca58d36a1f93af586ee93b340c9f9fd81312cc01)
    Signed-off-by: Rodrigo Vivi <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
e1000e: add system to disable K1 list [+ + +]
Author: Tony Nguyen <[email protected]>
Date:   Thu Oct 1 15:24:39 2026 -0700

    e1000e: add system to disable K1 list
    
    commit 1d6500523b8d5112afe0118173ebc8c1ca23784e upstream.
    
    Javier reports seeing packet loss issues related to the re-enablement
    of K1; disabling it makes the issues go away. Add the reported system
    to have K1 disabled by default.
    
    Reproduction steps (from the Link):
    Plug the cable and ping the default gateway on the LAN. No suspend/resume
    involved, machine freshly booted and on AC power. Nothing e1000e-related in
    dmesg apart from the link up/down messages; no "Hardware Unit Hang".
    
    Default (K1 enabled):
    
      $ ping -c 30 192.168.10.1
      --- 192.168.10.1 ping statistics ---
      30 packets transmitted, 18 received, 40% packet loss, time 29734ms
      rtt min/avg/max/mdev = 0.211/0.315/0.384/0.046 ms
    
    The lost packets are spread over the run (seq 6, 8, 9, 11, 13, 14, 16, 19,
    20, 24, 25, 30), not a single burst. DHCP on this link also takes 1-2
    minutes to get a lease, consistent with incoming packets being dropped.
    
    With K1 disabled at runtime:
    
      # ethtool --set-priv-flags enp0s31f6 disable-k1 on
      $ ethtool --show-priv-flags enp0s31f6
      Private flags for enp0s31f6:
      s0ix-enabled: on
      disable-k1  : on
    
      $ ping -c 30 192.168.10.1
      --- 192.168.10.1 ping statistics ---
      30 packets transmitted, 30 received, 0% packet loss, time 29713ms
      rtt min/avg/max/mdev = 0.169/0.251/0.468/0.054 ms
    
      $ ping -c 30 192.168.10.1
      --- 192.168.10.1 ping statistics ---
      30 packets transmitted, 30 received, 0% packet loss, time 29677ms
      rtt min/avg/max/mdev = 0.101/0.222/0.360/0.064 ms
    
    I have only compile tested this, but Javier has tested that disabling K1
    on his system (Lenovo ThinkPad P14s Gen 5 (Intel), I219-LM [8086:550a])
    resolves his issues.
    
    Cc: [email protected]
    Fixes: 578294b8b60d ("e1000e: Reconfigure PLL clock gate timeout and re-enable K1 on Meteor Lake")
    Reported-by: Javier Herrera <[email protected]>
    Link: https://lore.kernel.org/intel-wired-lan/CAKRuCQLWEcci9hPgNUmvq44Bd2H30T5_vP=exMjsknXMN5Yh9A@mail.gmail.com/
    Reviewed-by: Aleksandr Loktionov <[email protected]>
    Signed-off-by: Tony Nguyen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
EDAC/amd64: Mask UMC chip select to the four implemented selects [+ + +]
Author: Vishal Badole <[email protected]>
Date:   Fri Oct 2 17:02:03 2026 +0530

    EDAC/amd64: Mask UMC chip select to the four implemented selects
    
    commit 7484bc43ba6b8e189b482db5b75e7842890a82b1 upstream.
    
    For DRAM ECC errors, the chip select value can be found in the
    MCA_SYND[ErrorInformation] field.
    
    ErrorInformation[2:0] was first documented in Zen1. The 3 bit field
    implied that up to 8 chip selects may be used.
    
    However, all Zen-based systems have only ever had up to 4 chip selects.
    So only bits [1:0] would contain a valid chip select value.
    
    Future systems are redefining the field to ErrorInformation[1:0]. This
    matches the existing 'up to 4 chip selects' implementations. And it
    frees up the extra bit for other decoding.
    
    Change the current chip select mask from 0x7 to 0x3 to prepare for the
    decode change.
    
    Fixes: 713ad54675fd ("EDAC, amd64: Define and register UMC error decode function")
    Suggested-by: Yazen Ghannam <[email protected]>
    Signed-off-by: Vishal Badole <[email protected]>
    Signed-off-by: Borislav Petkov (AMD) <[email protected]>
    Reviewed-by: Yazen Ghannam <[email protected]>
    Cc: <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
fcntl: refuse F_SET_RW_HINT on an immutable inode [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:34 2026 +0200

    fcntl: refuse F_SET_RW_HINT on an immutable inode
    
    commit b0d1022b9bdb1e98aa7fb3244fdd50a58c61766c upstream.
    
    An immutable inode is never written to so write hints are pointless.
    Refuse the hint on an immutable inode the way setattr(), fallocate() and
    etxattr() refuse their changes.
    
    Fixes: c75b1d9421f8 ("fs: add fcntl() interface for setting/getting write life time hints")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect() [+ + +]
Author: Eric Dumazet <[email protected]>
Date:   Wed Oct 7 06:56:15 2026 +0200

    flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect()
    
    [ Upstream commit f202578efc738b883cfa04889eb97328914265a7 ]
    
    bpf_flow_dissect() sanitizes the offsets returned by the BPF program
    with clamp_t(u16, ..., hlen).
    
    If hlen is bigger than 65535, the upper bound is truncated before
    the comparison. For instance, with hlen == 65536, both nhoff and
    thoff are forced to zero, even if the program returned sane values.
    
    This is the same class of bug as the one fixed in commit 99bda1ecbd56
    ("flow_dissector: avoid u16 truncation of skb->len when computing
    thoff"). That fix does not cover the BPF path, because
    __skb_flow_dissect() returns early when a BPF flow dissector
    handles the packet.
    
    struct bpf_flow_keys stores nhoff and thoff as u16, so cap hlen
    to U16_MAX before clamping.
    
    Found by sashiko while reviewing the commit above.
    
    Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
    Signed-off-by: Eric Dumazet <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

flow_dissector: avoid u16 truncation of skb->len when computing thoff [+ + +]
Author: Eric Dumazet <[email protected]>
Date:   Thu Oct 1 19:11:38 2026 +0000

    flow_dissector: avoid u16 truncation of skb->len when computing thoff
    
    [ Upstream commit 99bda1ecbd56905f8bd934b9cdccd3bd251192b1 ]
    
    __skb_flow_dissect() computes key_control->thoff using:
    
      key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
    
    min_t(u16, ...) casts both arguments to u16 before comparing them.
    Whenever skb->len (or hlen) modulo 65536 is smaller than nhoff, the
    truncated length wins and thoff is set to a bogus small value, even
    when the dissection succeeded. For example, an IPv4/TCP frame with
    skb->len == 65540 and nhoff == 34 gets thoff == 4, so callers such as
    skb_probe_transport_header() point the transport header inside the
    Ethernet header.
    
    Such skbs are not exotic:
    - At the time of commit d0c081b49137 ("flow_dissector: properly cap
      thoff field"), AF_PACKET with PACKET_VNET_HDR could already build GSO
      skbs larger than 64KB (MTU checks are skipped for GSO, and
      alloc_skb_with_frags() accepted up to MAX_SKB_FRAGS (17) order-0
      pages on top of the linear part).
    - BIG TCP now makes skbs larger than 64KB common.
    - The following patch makes tun_get_user() dissect IFF_TAP frames
      before eth_type_trans() pulls the Ethernet header, so a GSO frame
      carrying a 65522..65535 byte L3 packet will be dissected with
      skb->len in [65536, 65549].
    
    Compare as u32 instead. If the resulting offset cannot be represented
    in the u16 key_control->thoff, cap it to U16_MAX and report the
    dissection as failed rather than silently returning a wrong transport
    offset. thoff is still set on failure, as some callers (such as
    eth_get_headlen()) use it regardless of the return value.
    
    Fixes: d0c081b49137 ("flow_dissector: properly cap thoff field")
    Signed-off-by: Eric Dumazet <[email protected]>
    Reviewed-by: Willem de Bruijn <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
fs: don't let a migrating task hide its reference from do_umount() [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 23 14:27:59 2026 +0200

    fs: don't let a migrating task hide its reference from do_umount()
    
    [ Upstream commit 7eb84d54fac5002bd975d1de8fd61d57e89172ab ]
    
    propagate_mount_busy() uses mnt_get_count() via do_refcount_check() to
    figure out whether a synchronous umount may proceed or not by summing
    the per-CPU mnt_count counter under mount_lock.
    
    The fastpath for mntget() and mntput() doesn't require that lock. A task
    that already holds a reference and takes another one on a cpu the loop
    has summed can get migrated and drops that reference again on another
    cpu. The loop might not have reached that cpu yet. That ends up
    undercounting. The original reference of the task is missed and umount()
    ends up succeeding with the file still open. The mount is destroyed
    later when the task mntput()s so it degrades to a lazy umount.
    
    That's basically the umount(2) variant of commit 9ea0a46ca2c3 ("fix
    mntput/mntput race") closed for the final mntput(). The same
    cpu-migration caused a UAF.
    
    Luckily this isn't a UAF. It's just a hidden reference pinning the
    mount but it's wrong nonetheless.
    
    Like the other race it's a narrow window but I can reproduce it reliably
    with some patching. The debug patch below prints the sum the loop
    computed next to an immediate re-sum of the same counters. It reports
    who drops the last reference to that mount later:
    
    #  --- a/fs/namespace.c
    #  +++ b/fs/namespace.c
    #  @@ -34,6 +34,8 @@
    #   #include <linux/mnt_idmapping.h>
    #   #include <linux/pidfs.h>
    #   #include <linux/nstree.h>
    #  +#include <linux/debugfs.h>
    #  +#include <linux/delay.h>
    #
    #   #include "pnode.h"
    #   #include "internal.h"
    #  @@ -263,17 +265,48 @@
    #   #endif
    #   }
    #
    #  +static u32 mnt_get_count_delay_ms;
    #  +static int mnt_get_count_debug_id;
    #  +
    #  +static int __init mnt_get_count_debug_init(void)
    #  +{
    #  +    debugfs_create_u32("mnt_get_count_delay_ms", 0600, NULL,
    #  +                       &mnt_get_count_delay_ms);
    #  +    return 0;
    #  +}
    #  +late_initcall(mnt_get_count_debug_init);
    #  +
    #   /*
    #    * vfsmount lock must be held for write
    #    */
    #   int mnt_get_count(struct mount *mnt)
    #   {
    #   #ifdef CONFIG_SMP
    #  -    int count = 0;
    #  +    static int seen[NR_CPUS];
    #  +    bool slow = mnt_get_count_delay_ms &&
    #  +                !(mnt->mnt.mnt_flags & MNT_UMOUNT);
    #  +    int count = 0, again = 0;
    #       int cpu;
    #
    #       for_each_possible_cpu(cpu) {
    #  -            count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
    #  +            seen[cpu] = per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
    #  +            count += seen[cpu];
    #  +            if (slow)
    #  +                    mdelay(mnt_get_count_delay_ms);
    #  +    }
    #  +    if (slow) {
    #  +            for_each_possible_cpu(cpu) {
    #  +                    int now;
    #  +
    #  +                    now = per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
    #  +                    again += now;
    #  +                    pr_err("mount %d: cpu%d read %d, now %d\n",
    #  +                           mnt->mnt_id, cpu, seen[cpu], now);
    #  +            }
    #  +            mnt_get_count_debug_id = mnt->mnt_id;
    #  +            pr_err("mount %d: sum %d, re-sum %d, %ps\n",
    #  +                   mnt->mnt_id, count, again,
    #  +                   __builtin_return_address(0));
    #       }
    #
    #       return count;
    #  @@ -1350,6 +1383,9 @@
    #       smp_mb();
    #       mnt_add_count(mnt, -1);
    #       count = mnt_get_count(mnt);
    #  +    if (count == 0 && mnt->mnt_id == mnt_get_count_debug_id)
    #  +            pr_err("mount %d: last put by %s (%d)\n", mnt->mnt_id,
    #  +                   current->comm, task_pid_nr(current));
    #       if (count != 0) {
    #               WARN_ON(count < 0);
    #               rcu_read_unlock();
    
    A task holds open a directory fd on a tmpfs. A synchronous rumount() of
    the tmpfs sums up. Concurrently a task calls fchdir() on that fd on
    CPU 0 and fchdir()s back to / on CPU 3. This will cause a path_get() and
    a path_put() with a migration in between without mount_lock held.
    
    Adding a delay per CPU makes the count loop miss the get in a cpu it
    already visited but count the put in one it hasn't.
    
    The reproducer, run as root with debugfs mounted:
    
      /*
       * gcc -static -o umount-torn umount-torn.c
       */
      #define _GNU_SOURCE
      #include <errno.h>
      #include <fcntl.h>
      #include <sched.h>
      #include <stdio.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/mount.h>
      #include <sys/stat.h>
      #include <sys/wait.h>
    
      #define KNOB "/sys/kernel/debug/mnt_get_count_delay_ms"
      #define MNT "/mnt/x"
    
      static int kmsg;
    
      static void pin(int cpu)
      {
            cpu_set_t s;
    
            CPU_ZERO(&s);
            CPU_SET(cpu, &s);
            sched_setaffinity(0, sizeof(s), &s);
      }
    
      static void knob(const char *v)
      {
            int fd = open(KNOB, O_WRONLY);
    
            write(fd, v, strlen(v));
            close(fd);
      }
    
      int main(void)
      {
            int last = sysconf(_SC_NPROCESSORS_ONLN) - 1;
            int p[2], fd, ret;
            pid_t pid;
            char c;
    
            kmsg = open("/dev/kmsg", O_WRONLY);
            mkdir(MNT, 0755);
            mount("none", MNT, "tmpfs", 0, NULL);
            fd = open(MNT "/f", O_WRONLY | O_CREAT, 0644);
            write(fd, "still here\n", 11);
            close(fd);
    
            pipe(p);
            pid = fork();
            if (pid == 0) {
                    int dirfd = open(MNT, O_RDONLY | O_DIRECTORY);
                    int rootfd = open("/", O_RDONLY | O_DIRECTORY);
                    struct stat st;
                    char buf[16];
    
                    /* one get/put pair while the umount is summing */
                    usleep(150000);
                    pin(0);
                    fchdir(dirfd);          /* mntget() */
                    dprintf(kmsg, "holder %d: get on cpu %d\n", getpid(),
                            sched_getcpu());
                    pin(last);
                    fchdir(rootfd);         /* mntput() */
                    dprintf(kmsg, "holder %d: put on cpu %d\n", getpid(),
                            sched_getcpu());
    
                    /* the umount has returned, is the fd still good? */
                    read(p[0], &c, 1);
                    fd = openat(dirfd, "f", O_RDONLY);
                    ret = read(fd, buf, sizeof(buf));
                    dprintf(kmsg, "holder %d: fstat %d openat %d read %d\n",
                            getpid(), fstat(dirfd, &st), fd, ret);
                    _exit(0);
            }
    
            pin(1);
            knob("100");
            ret = umount2(MNT, 0);
            knob("0");
            if (ret)
                    dprintf(kmsg, "umount: %s\n", strerror(errno));
            else
                    dprintf(kmsg, "umount: 0\n");
            write(p[1], "x", 1);
            waitpid(pid, NULL, 0);
            return 0;
      }
    
    The log shows the busy check summing 2 and when read right after it
    reads 3. The loop read CPU 0 before the get landed there and CPU 3
    after the put did. The umount succeeds while there's still someone
    with an fd. The mount is then dropped when the fd goes:
    
      [    2.511944] holder 90: get on cpu 0
      [    2.512023] holder 90: put on cpu 3
      [    2.671388] mount 28: cpu0 read 1, now 2
      [    2.671398] mount 28: cpu1 read 2, now 2
      [    2.671401] mount 28: cpu2 read 0, now 0
      [    2.671404] mount 28: cpu3 read -1, now -1
      [    2.671407] mount 28: sum 2, re-sum 3, propagate_mount_busy
      [    2.671773] umount: 0
      [    2.672963] holder 90: fstat 0 openat 8 read 11
      [    2.673663] mount 28: last put by umount-torn (90)
    
    Easy fix would be to order mntget() against the loop that sums up. But
    that's a full barrier and a flag test in mntget() afaict. No bueno...
    That would cost every path_get().
    
    So learn from SRCU. Keep gets and puts in separate per-cpu counters and
    make mnt_get_count() sum all puts first and all gets second with a full
    barrier in between.
    
    A put is always after its own get (hopefully...) independent of the cpu
    the task is on. So a put the first pass counted must have its get
    visible to the second pass. Ergo, we can't undercount.
    
    This is the two pass sum srcu_readers_active_idx_check() does for
    srcu_locks and srcu_unlocks. mntget() keeps a single
    this_cpu_inc(). mntput() gains an smp_wmb() before its increment, a
    compiler barrier on x86 and a store fence on the weakly ordered
    architectures, since the two counters are two words and a put stored
    after a get could otherwise become visible before it. The counters
    are unsigned so the difference stays right after they wrap.
    
    The count can still come out high when a get is counted whose put
    the first pass did not see. We don't care. A task can only take a new
    reference if:
    
    (1) it holds one already
    (2) through __legitimize_mnt() which the seqcount orders
        against the write side
    
    So a get in this window means someone has a reference and -EBUSY is
    correct. The final mntput() is unchanged. Once ->mnt_ns is NULL every
    put takes the slow path under mount_lock and so no put is in flight
    while it counts. Here's an attempted proof for that crap:
    
    (i) A put never becomes visible before its get. Within one task the
        smp_wmb() in mntput_no_expire() orders every earlier store before the
        increment of the puts.
    
        Any task that migrated in between had its stores flushed by the
        scheduler. When that reference is handed to another task that's
        trivially true.
    
    (ii) The double count in mnt_get_count() is ordered via smp_mb(). That
         keeps every read of the puts counter before every read of the gets
         counter.
    
    (iii) We never undercount by (ii).
    
    (iv) There are no spurious counts/differences. A get is counted only if
         it happened and a put is left out only if it hasn't happened when
         the counter was read. With (iii) this means it's equivalent to the
         old count whenever nothing is taken or dropped during the loop.
    
    (v) do_umount() holds a reference and mount_lock hence. New references
        come from: (v.a) __legitimize_mnt() managed by the seqcount. Either
        it's smp_mb() made the get visible to the loop or it takes the lock
        and waits for the loop. By (iii) a mount with a additional
        references is refused. By (iv) refusing the umount just means that
        any additional reference existed, same as the old counter.
    
    (vi) mntput_no_expire_slowpath() runs with ->mnt_ns already NULL. Hence,
         every other put must take the slowpath as well and hangs on mount_lock.
    
        The grace period in namespace_unlock() will make every fast path do
        a put that still saw ->mnt_ns.
    
        No put is in flight during the loop.
    
        A get that is in flight comes from a task holding another reference.
        That must be included by the count or from __legitimize_mnt() as in
        (v).
    
        Ergo, zero means the last reference and non-zero means a reference
        is live.
    
    (vii) may_umount() uses propagate_mount_busy() as well and
          may_umount_tree() sums mnt_get_count() itself.
    
    With this patch the race is dead:
    
      [    3.066786] mount 28: sum 3, re-sum 3, propagate_mount_busy
      [    3.105867] umount: Device or resource busy
      [    3.106047] holder 90: fstat 0 openat 8 read 11
    
    Link: https://patch.msgid.link/[email protected]
    Fixes: b3e19d924b6e ("fs: scale mntget/mntput")
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

fs: don't silently unmount busy mounts [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 23 14:27:57 2026 +0200

    fs: don't silently unmount busy mounts
    
    commit 6857e209015f95be7a8f19a9cd5dac345b9b9859 upstream.
    
    The propagate_mount_busy() helper exists to decide whether a synchronous
    can suceed. It does that by looking at the copies of the victims in the
    mounts its parent propagates to. One of those functions from propagation
    hell.
    
    It skips a copy that has child mounts except for the case of a single
    child mount covering the copy's root. That algorithm used to be exact.
    It isn't anymore.
    
    Originally only childless copies were unmounted during propagation.
    And 1064f874abc0 ("mnt: Tuck mounts under others instead of creating
    shadow/side mounts.") ended up adding covered mounts to both sides in
    one go.
    
    Along came 99b19d16471e ("mnt: In propgate_umount handle visiting mounts
    in any order") and that started to unmount more than before:
    
    [1]: A copy of a mount is unmounted when each of its children is either
         its overmount or a copy of the victim itself. In the former case
         the overmount gets reparented. In the latter case the copy of the
         victim will end up being unmounted.
    
    So propagate_umount() ended up being rewritten without adjusting
    propagate_mount_busy(). And currently propagate_mount_busy() doesn't
    look at copies of the victim that have two or more children nor a single
    child that is not the overmount.
    
    So any such copy in [1] is not checked for
    references. The result is that a synchronous unmount succeeds, pulling
    out a mount that is still in use.
    
    A container can run into this with its own mounts. The host shares a
    tree with the container and the host has a mount in that tree:
    
      mount -t tmpfs none /mnt
      mount --make-shared /mnt
      mount -t tmpfs none /mnt/a
    
    The container's /mnt is a slave copy of the host mount. The container
    now takes a detached copy of the tree and mounts that copy beneath its
    propagated copy of /mnt/a and keeps the file descriptor to the tree
    open:
    
      unshare -m --propagation unchanged
      mount --make-rslave /
      fd = open_tree(AT_FDCWD, "/mnt", OPEN_TREE_CLONE | AT_RECURSIVE)
      move_mount(fd, "", AT_FDCWD, "/mnt/a", MOVE_MOUNT_BENEATH)
    
      grep /mnt /proc/self/mountinfo
      775 355 ... /mnt ...     master:646
      777 775 ... /mnt/a ...   master:646
      776 777 ... /mnt/a ...   master:647
      778 777 ... /mnt/a/a ... master:647
    
    The now attached tree (777) is now mounted beneath the container's copy
    of /mnt/a. That's also where the host mount sits (as seen from the host
    mount namespace). So the propagated copy (776) of the host's mount is on
    top of its root and the copy of that (778) is inside it. Now the host
    runs:
    
      umount /mnt/a
    
    and it succeeds. The moved tree tree and the copy inside of it are gone
    from the container. Now only the propagated copy is left and it got
    reparented to where it was before:
    
      grep /mnt /proc/self/mountinfo
      775 355 ... /mnt ... master:646
      776 775 ... /mnt/a ...
    
    But the file descriptor still refers to the moved tree. So a synchronous
    umount detached a mount that is still in use.
    
    Teach propagate_mount_busy() the same checks that propagate_umount()
    does. It now checks for a single victim mount without children
    for which it can assume that MNT_LOCKED is cleared on every copy like
    propagate_umount() does. The copies form chains. IOW, when a copy itself
    receives propagation from the victim's parent then the mount at the same
    mountpoint inside that copy is a copy as well. Whether a mount receives
    propagation from the victim's can simply be checked by walking its
    masters. Walk each chain once from its top so we are sure that nested
    copies stay linear. Check every reference once of every copy that gets
    unmounted.
    
    Link: https://patch.msgid.link/[email protected]
    Fixes: 99b19d16471e ("mnt: In propgate_umount handle visiting mounts in any order")
    Cc: [email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

fs: Free any excess xarray nodes in clear_inode() [+ + +]
Author: Matthew Wilcox (Oracle) <[email protected]>
Date:   Tue Jun 23 20:28:48 2026 +0100

    fs: Free any excess xarray nodes in clear_inode()
    
    [ Upstream commit ee3f011250104129893d8e9599147e457d4d7280 ]
    
    For many years we've had a hard to hit leak of xarray nodes.  Hugh
    documented it well in commit 786b31121a2c.  Recently people and
    syzbot have found ways to force it to happen with madvise.  Rather
    than fix the leaks where they happen, just call xa_destroy() which
    has the side-effect of cycling the i_pages lock.
    
    Cc: Rik van Riel <[email protected]>
    Cc: Zi Yan <[email protected]>
    Cc: Jinjiang Tu <[email protected]>
    Cc: Dave Jones <[email protected]>
    Link: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Reviewed-by: Rik van Riel <[email protected]>
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

fs: refuse fspick() on internal superblocks [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:29 2026 +0200

    fs: refuse fspick() on internal superblocks
    
    commit 02587a4af82adccaef8e3b3624b4e7f1c401632d upstream.
    
    There's a few instances where a internal superblock is reachable by
    fspick(). Block that. graft_tree() and fsmount() already refuse them.
    fanotify refuses mount and superblock marks on them for the same reason.
    
    Fixes: cf3cba4a429b ("vfs: syscall: Add fspick() to select a superblock for reconfiguration")
    Cc: [email protected] # v5.2+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
fsverity: RCU-delay the freeing of struct fsverity_info [+ + +]
Author: Eric Biggers <[email protected]>
Date:   Thu Oct 1 10:13:49 2026 -0700

    fsverity: RCU-delay the freeing of struct fsverity_info
    
    commit e58c3805ed325fe2d4ae2dd467c0486cc860b733 upstream.
    
    __fsverity_get_info() calls rhashtable_lookup_fast(), which just uses
    rcu_read_lock() and doesn't directly synchronize with
    fsverity_remove_info().
    
    For the same inode this isn't a problem: its fsverity_info is removed
    only at inode eviction time or upon failure to enable verity, when the
    inode no longer needs its fsverity_info and it will no longer be
    accessed via that inode.
    
    However, this is broken and can cause a use-after-free for concurrent
    __fsverity_get_info() for *different* inodes.  Those rely on following
    fsverity_info::rhash_head in the rhashtable under rcu_read_lock() only.
    They also use fsverity_info::inode to do the key comparison.
    
    Fix this by RCU-delaying the freeing of 'struct fsverity_info' after
    it's been removed from the rhashtable.
    
    Fixes: f77f281b6118 ("fsverity: use a hashtable to find the fsverity_info")
    Cc: [email protected]
    Reviewed-by: Christoph Hellwig <[email protected]>
    Reviewed-by: Sandeep Dhavale <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Eric Biggers <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
gpio: exar: initialize the ID before registering its cleanup [+ + +]
Author: Sang-Hoon Choi <[email protected]>
Date:   Wed Sep 30 02:37:31 2026 +0900

    gpio: exar: initialize the ID before registering its cleanup
    
    [ Upstream commit 4d69e74034b208588636ecc177e0dd43a7696af3 ]
    
    devm_add_action_or_reset() invokes the cleanup action immediately when
    registering the action fails.  gpio_exar_probe() currently stores the
    allocated ID in exar_gpio only after registering the action, so that
    failure makes exar_devm_ida_free() release ID 0.  If the allocated ID is
    nonzero, this leaks that ID and can free ID 0 belonging to another device.
    
    Store the ID before registering the cleanup action so both the immediate
    failure path and normal device teardown release the correct allocation.
    
    Fixes: 5300ebb695fa ("gpio: exar: use devm action for freeing the IDA and drop remove()")
    Reported-by: Changyul Lee <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Sang-Hoon Choi <[email protected]>
    Reviewed-by: Linus Walleij <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Bartosz Golaszewski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

gpio: mpsse: fix race when arming the IRQ poll worker [+ + +]
Author: Fan Wu <[email protected]>
Date:   Tue Sep 29 09:36:46 2026 +0000

    gpio: mpsse: fix race when arming the IRQ poll worker
    
    commit 7efa1a1953cd6b20b23a3524d5b4b81789c6ef25 upstream.
    
    gpio_mpsse_irq_enable() arms the poll worker before publishing it:
    schedule_work() runs before the worker is added to priv->workers. If
    gpio_mpsse_disconnect() walks the list in that window it misses the
    worker, and once disconnect returns, the USB core frees mpsse_priv
    while the orphaned gpio_mpsse_poll() work keeps accessing it, causing
    a use-after-free.
    
    Fix this by publishing and arming the worker in one irq_spin
    critical section. Teardown walks the same list under irq_spin, so a
    worker found on the list is guaranteed to be armed, and
    cancel_work_sync() handles it whether it is queued or running.
    
    A worker armed after the disconnect walk would still be missed, so
    also set a new priv->dying flag under irq_spin before the teardown
    walk, and check it in the same critical section, freeing it via
    kfree_rcu() instead when the device is going away, since kfree()
    would be called with the IRQ core's raw spinlock held and may sleep
    on PREEMPT_RT. schedule_work() is safe to call with irq_spin held,
    and the next probe gets a fresh mpsse_priv, so the flag never needs
    to be cleared.
    
    This issue was found by an in-house static analysis tool.
    
    Fixes: 179ef1127d7a ("gpio: mpsse: ensure worker is torn down")
    Cc: [email protected]
    Co-developed-by: Song Li <[email protected]>
    Signed-off-by: Song Li <[email protected]>
    Signed-off-by: Fan Wu <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Bartosz Golaszewski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

gpio: xilinx: fix runtime PM leak on request error path [+ + +]
Author: Ridham Khurana <[email protected]>
Date:   Wed Sep 23 11:39:02 2026 +0000

    gpio: xilinx: fix runtime PM leak on request error path
    
    commit ff82fc3a4a1d417dee1229681cc5285986edb1fa upstream.
    
    pm_runtime_get_sync() leaves the usage counter incremented even when it
    fails, and xgpio_request() returns the error without dropping it.
    
    gpiolib does not call ->free() when ->request() fails, so xgpio_free(),
    which holds the only matching pm_runtime_put(), never runs. The reference
    is leaked and the controller can no longer runtime-suspend, so its clock
    stays enabled.
    
    Switch to pm_runtime_resume_and_get(), which only increments the usage
    counter on success.
    
    Fixes: 26b04774621e ("gpio: gpio-xilinx: Add support for suspend and resume")
    Cc: [email protected]
    Signed-off-by: Ridham Khurana <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Bartosz Golaszewski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
gve: fix napi_disable deadlock when attempting to disable XSK pools [+ + +]
Author: Joshua Washington <[email protected]>
Date:   Wed Sep 30 14:47:35 2026 -0700

    gve: fix napi_disable deadlock when attempting to disable XSK pools
    
    commit 0cb6939a4dfefa822007b7a71986e06bc4f61f54 upstream.
    
    When disabling XSK pools, GVE calls the unlocked versions of
    napi_disable and napi_enable. However, the netdev lock has already been
    acquired before ndo_bpf is called because GVE supports queue management
    ops. Calling the unlocked versions of napi_disable/enable results in a
    deadlock when attempting to disable XSK pools, as the thread attempts to
    re-acquire a lock it already holds.
    
    Update the NAPI calls to use the locked versions.
    
    This issue was found in production.
    
    Fixes: 606048cbd834 ("net: designate XSK pool pointers in queues as "ops protected"")
    Cc: [email protected]
    Reviewed-by: Harshitha Ramamurthy <[email protected]>
    Reviewed-by: Jordan Rhee <[email protected]>
    Signed-off-by: Joshua Washington <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

gve: fix XSK buffer leak on error descriptor [+ + +]
Author: Joshua Washington <[email protected]>
Date:   Wed Sep 30 14:47:34 2026 -0700

    gve: fix XSK buffer leak on error descriptor
    
    commit 9fed6a8ab8a5bacba2c709cb19d2dd6d2fa9112e upstream.
    
    When the error bit is set in the RX completion descriptor, the buf_state
    and its attached buffer should be freed. In the case of AF_XDP ZC, the
    XSK buffer was not freed, leading to a leak.
    
    This issue was caught by LLM.
    
    Fixes: c1fffc5d66a7 ("gve: implement DQO RX datapath and control path for AF_XDP zero-copy")
    Cc: [email protected]
    Reviewed-by: Jordan Rhee <[email protected]>
    Reviewed-by: Tim Hostetler <[email protected]>
    Signed-off-by: Joshua Washington <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

gve: fix XSK buffer leak when rings are stopped [+ + +]
Author: Joshua Washington <[email protected]>
Date:   Wed Sep 30 14:47:33 2026 -0700

    gve: fix XSK buffer leak when rings are stopped
    
    commit 73670ddb91a4d22e1deb3efd962242de1ec48e90 upstream.
    
    GVE does not free XSK buffers when resetting ring state as a part of
    stopping queues. This causes all XSK buffers which are posted to the
    NIC to be leaked.
    
    Free XSK buffers attached to an allocated buf_state when stopping rings.
    
    This issue was hit in production.
    
    Fixes: c1fffc5d66a7 ("gve: implement DQO RX datapath and control path for AF_XDP zero-copy")
    Cc: [email protected]
    Reviewed-by: Tim Hostetler <[email protected]>
    Reviewed-by: Jordan Rhee <[email protected]>
    Signed-off-by: Joshua Washington <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
HID: steam: Clean up locking [+ + +]
Author: Vicki Pfau <[email protected]>
Date:   Tue Oct 13 09:11:35 2026 +0000

    HID: steam: Clean up locking
    
    [ Upstream commit de1d341b9b3ec9655f31fb8b44f784cca5e670ad ]
    
    This cleans up several issues with locking behavior, including RCU accesses
    not being guarded behind a lock.
    
    Signed-off-by: Vicki Pfau <[email protected]>
    Signed-off-by: Jiri Kosina <[email protected]>
    [Lee: Drop report_mutex from steam_get_serial() and
          steam_get_attributes() instead of steam_exchange_report_id() and
          omit coalesce_rumble_work and Ibex changes as 1d4549fd1115,
          fcfa7db89f7a and 0a80b4e8ec6a are not present]
    Signed-off-by: Lee Jones <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

HID: steam: Fully unregister controller when hidraw is opened [+ + +]
Author: Vicki Pfau <[email protected]>
Date:   Tue Oct 13 09:11:32 2026 +0000

    HID: steam: Fully unregister controller when hidraw is opened
    
    [ Upstream commit cd33a91d37eb4d7c6ce56aa7f4688066309808eb ]
    
    To avoid conflicts between anything touching the hidraw and the driver we
    had previously detached the evdev nodes when the hidraw is opened. However,
    this isn't sufficient to avoid FEATURE reports from conflicting, so we
    change to fully unregistering the controller internally, leaving only the
    hidraw active until it's closed.
    
    This also unifies the unregister and connect callbacks, as now the logic
    between these two callbacks is identical.
    
    Signed-off-by: Vicki Pfau <[email protected]>
    Signed-off-by: Jiri Kosina <[email protected]>
    [Lee: Omit coalesce_rumble_work cancellation as 1d4549fd1115 ("HID:
          steam: Coalesce rumble packets") is not present]
    Signed-off-by: Lee Jones <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

HID: steam: Rearrange teardown sequence [+ + +]
Author: Vicki Pfau <[email protected]>
Date:   Tue Oct 13 09:11:33 2026 +0000

    HID: steam: Rearrange teardown sequence
    
    [ Upstream commit ddce9641ce924ed91ec8304577e463823a29ffaf ]
    
    This fixes a narrow window during the teardown sequence where callbacks
    could still be scheduled during cleanup that would then have a dangling
    pointer to the now-freed steam struct.
    
    This also puts work canceling for rumble and mode switch in
    steam_unregister, as that shouldn't persist while the client hdev is open.
    
    Signed-off-by: Vicki Pfau <[email protected]>
    Signed-off-by: Jiri Kosina <[email protected]>
    [Lee: Omit coalesce_rumble_work cancellation as 1d4549fd1115 ("HID:
          steam: Coalesce rumble packets") is not present]
    Signed-off-by: Lee Jones <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

HID: steam: Refactor registration [+ + +]
Author: Vicki Pfau <[email protected]>
Date:   Tue Oct 13 09:11:34 2026 +0000

    HID: steam: Refactor registration
    
    [ Upstream commit 6f9b740c31ba7e061b2ebb330d9a3d63f1358f29 ]
    
    This refactors and simplifies the registration/unregistration flow. Since
    we now only perform registration when the client isn't opened anymore, the
    logic for handling that can be removed, and the rest of the function
    streamlined.
    
    We also remove the previous assumption that we have a serial number to show
    we're registered, replacing it with a single purpose boolean.
    
    In a previous refactor the code for unregistering a battery if later
    registration steps failed was accidentally left out. As a result, a
    lingering power_supply object could get left over after the steam object
    was torn down. This is also fixed here.
    
    Signed-off-by: Vicki Pfau <[email protected]>
    Signed-off-by: Jiri Kosina <[email protected]>
    [Lee: Omit coalesce_rumble_work cancellation as 1d4549fd1115 ("HID:
          steam: Coalesce rumble packets") is not present]
    Signed-off-by: Lee Jones <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
iavf: send MAC change request synchronously [+ + +]
Author: Jose Ignacio Tornos Martinez <[email protected]>
Date:   Mon Jun 22 15:58:24 2026 +0200

    iavf: send MAC change request synchronously
    
    commit 436729a56dd4dac611d10b569c5359d2cf705b19 upstream.
    
    After commit ad7c7b2172c3 ("net: hold netdev instance lock during sysfs
    operations"), iavf_set_mac() is called with the netdev instance lock
    already held.
    
    The function queues a MAC address change request via
    iavf_replace_primary_mac() and then waits for completion. However, in
    the current flow, the actual virtchnl message is sent by the watchdog
    task, which also needs to acquire the netdev lock to run. Additionally,
    the adminq_task which processes virtchnl responses also needs the netdev
    lock.
    
    This creates a deadlock scenario:
    1. iavf_set_mac() holds netdev lock and waits for MAC change
    2. Watchdog needs netdev lock to send the request -> blocked
    3. Even if request is sent, adminq_task needs netdev lock to process
       PF response -> blocked
    4. MAC change times out after 2.5 seconds
    5. iavf_set_mac() returns -EAGAIN
    
    This particularly affects VFs during bonding setup when multiple VFs are
    enslaved in quick succession.
    
    Fix by implementing a synchronous MAC change operation similar to the
    approach used in commit fdadbf6e84c4 ("iavf: fix incorrect reset handling
    in callbacks").
    
    The solution:
    1. Send the virtchnl ADD_ETH_ADDR message directly (not via watchdog)
    2. Poll the admin queue hardware directly for responses
    3. Process all received messages (including non-MAC messages)
    4. Return when MAC change completes or times out
    
    A new generic function iavf_poll_virtchnl_response() is introduced that
    can be reused for any future synchronous virtchnl operations. It takes a
    callback to check completion, allowing flexible condition checking.
    
    This allows the operation to complete synchronously while holding
    netdev_lock, without relying on watchdog or adminq_task. The function
    can sleep for up to 2.5 seconds polling hardware, but this is acceptable
    since netdev_lock is per-device and only serializes operations on the
    same interface.
    
    To support this, change iavf_add_ether_addrs() to return an error code
    instead of void, allowing callers to detect failures. Additionally,
    export iavf_mac_add_reject() to enable proper rollback on local failures
    (timeouts, send errors) - PF rejections are already handled automatically
    by iavf_virtchnl_completion().
    
    Remove vc_waitqueue entirely because iavf_set_mac was the only waiter on
    this waitqueue and after the changes it is not needed.
    
    Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations")
    cc: [email protected]
    Signed-off-by: Jose Ignacio Tornos Martinez <[email protected]>
    Reviewed-by: Przemek Kitszel <[email protected]>
    Tested-by: Rafal Romanowski <[email protected]>
    Signed-off-by: Tony Nguyen <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ibmveth: fix TX LTB and filter unwind on open-fail [+ + +]
Author: Mingming Cao <[email protected]>
Date:   Fri Sep 25 11:05:30 2026 -0700

    ibmveth: fix TX LTB and filter unwind on open-fail
    
    commit 84bec0bf035258a1073ffd6f6dc8ea61806aa7d4 upstream.
    
    out_free_buffer_pools reuses open()'s loop index for the TX LTB
    walk. After the pool unwind i is -1, so the TX buffers allocated
    earlier are leaked. request_irq() failure has the same leak.
    
    The TX-fail goto on that walk also skips dma_unmap of the filter
    list (pre-existing since the LTB was added). Rewrite the TX walk
    to real_num_tx_queues with a pointer check, and unmap the filter
    list before those frees.
    
    Fixes: d926793c1de9 ("ibmveth: Implement multi queue on xmit")
    Cc: [email protected]
    Signed-off-by: Mingming Cao <[email protected]>
    Reviewed-by: Dave Marquardt <[email protected]>
    Link: https://patch.msgid.link/d14314c2b10f125f5e578782484ba3cc50564d53.1790357373.git.mmc@linux.ibm.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ibmveth: h_free logical LAN on open-fail after register [+ + +]
Author: Mingming Cao <[email protected]>
Date:   Fri Sep 25 11:05:29 2026 -0700

    ibmveth: h_free logical LAN on open-fail after register
    
    commit af0524bf4ce1a4cbd2946aa81751582951cfcab5 upstream.
    
    ibmveth_open() registers the logical LAN, then allocates the RX
    buffer pools. A pool failure jumps to out_free_buffer_pools without
    h_free_logical_lan(), so PHYP still owns the buffer-list page when
    it is unmapped. request_irq() failure already issued the hypercall
    before taking the same label.
    
    Move that h_free to the shared post-register unwind so both paths
    deregister before the buffer list is unmapped.
    
    Fixes: d43732ce021f ("ibmveth: properly unwind on init errors")
    Cc: [email protected]
    Signed-off-by: Mingming Cao <[email protected]>
    Reviewed-by: Dave Marquardt <[email protected]>
    Link: https://patch.msgid.link/7a56fbfb9e0674f011f4e310fbd7dfd8e67c30aa.1790357373.git.mmc@linux.ibm.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ice: fix metadata_dst refcount handling on representor teardown [+ + +]
Author: Tristan Madani <[email protected]>
Date:   Mon Sep 28 16:04:25 2026 -0700

    ice: fix metadata_dst refcount handling on representor teardown
    
    commit 58858b8f14803a7eeac297b3ce20f3b21bf2ff66 upstream.
    
    ice_eswitch_release_repr() uses metadata_dst_free() to release the
    representor's metadata_dst.  metadata_dst_free() directly frees the
    underlying memory without checking the dst_entry refcount.
    
    When ice_eswitch_port_start_xmit() processes a packet, it takes a
    reference via dst_hold() and attaches the metadata_dst to the skb.
    If the representor is torn down while packets are still queued on
    the lower device (e.g. in a qdisc), the metadata_dst is freed while
    references are still held.
    
    Use dst_release() instead, which correctly decrements the refcount
    and only frees the object when all references are dropped.  The dst
    subsystem already handles metadata_dst cleanup in dst_destroy() when
    DST_METADATA is set.
    
    Other drivers sharing this pattern (nfp, airoha, bnxt) already use
    dst_release() for their metadata_dst lifecycle.
    
    Fixes: f5396b8a663f7 ("ice: switchdev slow path")
    Cc: [email protected]
    Signed-off-by: Tristan Madani <[email protected]>
    Reviewed-by: Simon Horman <[email protected]>
    Signed-off-by: Tony Nguyen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ice: fix use-after-free in dynamic port cleanup [+ + +]
Author: Xuanqiang Luo <[email protected]>
Date:   Mon Sep 28 16:04:23 2026 -0700

    ice: fix use-after-free in dynamic port cleanup
    
    commit 1402fc67d2f4e2e1fc7bf8ee0825b8ad994557ff upstream.
    
    ice_dealloc_dynamic_port() uses dyn_port->vsi->idx to erase the dynamic
    port from pf->dyn_ports. However, it frees the VSI before reading the
    index for the erase, resulting in a use-after-free.
    
    Follow the reverse of the allocation order in ice_alloc_dynamic_port()
    by erasing the xarray entry before freeing the VSI.
    
    Fixes: eda69d654c7e ("ice: add basic devlink subfunctions support")
    Cc: [email protected]
    Signed-off-by: Xuanqiang Luo <[email protected]>
    Reviewed-by: Marcin Szycik <[email protected]>
    Reviewed-by: Aleksandr Loktionov <[email protected]>
    Tested-by: Patryk Holda <[email protected]>
    Signed-off-by: Tony Nguyen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ice: Restore Ordered MMIO Writes for Tx Doorbells [+ + +]
Author: Bryan Fraschetti <[email protected]>
Date:   Mon Sep 28 16:04:24 2026 -0700

    ice: Restore Ordered MMIO Writes for Tx Doorbells
    
    [ Upstream commit 7a579dec8423bba7bec96fcfcb2e30838b0858ee ]
    
    The DQL accounting state which tracks the number of bytes queued for the
    NIC to transmit, namely dql->num_queued, is updated by the ICE driver
    when it invokes __netdev_tx_sent_queue(). Subsequently the driver
    updates the hardware queue tail allowing the NIC to begin processing the
    work queue. The queue accounting update should be ordered before the NIC
    begins transmitting descriptors.
    
    The transmit path currently updates the hardware doorbell using
    writel_relaxed(), which (on arm64) does not provide the same ordering
    guarantees between writes to normal memory and writes to MMIO registers
    that writel() does. This introduces a potential race where the NIC
    begins transmitting descriptors before the dql->num_queued update is
    globally visible. If the NIC finishes before the update is observed by
    dql_completed(), it detects an invalid state where more bytes have been
    completed than have been queued. When this happens the following BUG_ON
    is triggered.
    
      BUG_ON(count > num_queued - dql->num_completed);
    
    This has been observed and manifests as the following crash (note that
    the trace has been trimmed) in an environment with sustained network
    load that uses an Intel Corporation Ethernet Controller E810-XXV for SFP
    (rev 02) on an arm64 machine. Replacing writel_relaxed() with writel()
    in a test kernel eliminated the crash in the user's workload, which
    previously reproduced the issue reliably.
    
      kernel BUG at lib/dynamic_queue_limits.c:99
    
    Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
    pc : dql_completed+0x268/0x2a0
    lr : ice_clean_tx_irq+0x1d4/0x620 [ice]
    Call trace:
    dql_completed+0x268/0x2a0 (P)
    ice_napi_poll+0x94/0x520 [ice]
    __napi_poll+0x48/0x3f0
    net_rx_action+0x194/0x420
    
    This restores the behaviour prior to commit ccde82e90946 ("ice: add E830
    Earliest TxTime First Offload support"), which changed the notification
    mechanism from writel() to writel_relaxed().
    
    Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2161572
    Fixes: ccde82e90946 ("ice: add E830 Earliest TxTime First Offload support")
    Signed-off-by: Bryan Fraschetti <[email protected]>
    Tested-by: Alexander Nowlin <[email protected]>
    Signed-off-by: Tony Nguyen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
Input: ati_remote2 - fix type confusion in device attribute handlers [+ + +]
Author: Haotian Zhang <[email protected]>
Date:   Fri Oct 9 10:48:25 2026 -0700

    Input: ati_remote2 - fix type confusion in device attribute handlers
    
    commit f321cc430c49b6c1be0d53f2ef19d8342d8029cc upstream.
    
    Previously, the channel_mask and mode_mask attributes were registered on
    the parent usb_device via sysfs_create_group(). When commit b20d6bf8014b
    ("Input: ati-remote2 - use driver core to instantiate device
    attributes") converted the driver to let the driver core manage them via
    dev_groups in struct usb_driver, the attributes moved to the bound
    usb_interface devices, but the show and store callbacks were not updated
    accordingly.
    
    As a result, the callbacks still invoked to_usb_device() on a device
    pointer belonging to a struct usb_interface, producing an invalid
    usb_device pointer.
    
    Use to_usb_interface() directly in the attribute handlers to obtain the
    interface and its driver data.
    
    Fixes: b20d6bf8014b ("Input: ati-remote2 - use driver core to instantiate device attributes")
    Assisted-by: DeepSeek-V4.1-Flash
    Signed-off-by: Haotian Zhang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Dmitry Torokhov <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox [+ + +]
Author: Bihaan Sen <[email protected]>
Date:   Fri Sep 25 17:14:38 2026 +0530

    Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox
    
    commit 41363c27b8509bd4efcba244803edac9ba25d1b5 upstream.
    
    The 8BitDo Pro 2 Wired Controller for Xbox is already matched by the
    vendor-wide XPAD_XBOXONE_VENDOR(0x2dc8) entry, but a later hardware
    revision reports product ID 0x201e, which has no entry in the
    xpad_device table. The device therefore binds and functions but is
    exposed to userspace as "Generic X-Box pad".
    
    Add the VID/PID pair so the controller is named correctly, and set
    MAP_SHARE_BUTTON to expose the share button as KEY_RECORD.
    
    Signed-off-by: Bihaan Sen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Dmitry Torokhov <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

Input: xpad - add support for Corsair Novablade Pro [+ + +]
Author: Krzysztof Furman <[email protected]>
Date:   Fri Oct 9 15:47:10 2026 +0100

    Input: xpad - add support for Corsair Novablade Pro
    
    commit f9282b8aa85a8c97c50d656db75feb6d76fc7cbe upstream.
    
    Add device IDs for the Corsair Novablade Pro leverless fight controller
    in both wired (0x2b1f) and 2.4 GHz receiver (0x2b2b) modes, and add
    Corsair's vendor ID to the Xbox 360 vendor match list.
    
    Outside of its PS4/PS5 modes the controller uses the Xbox 360 protocol
    (vendor-specific class, subclass 93, protocol 1) on interface 0, which
    xpad does not currently bind, so no gamepad device is created. The
    PS4/PS5 modes present a standard HID gamepad and already work with
    hid-generic.
    
    Tested on 7.2.5 with the 2.4 GHz receiver and wired.
    
    Assisted-by: Claude Opus 5.5
    Signed-off-by: Krzysztof Furman <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Dmitry Torokhov <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
io_uring/kbuf: don't charge provided buffer rings to RLIMIT_MEMLOCK [+ + +]
Author: Jens Axboe <[email protected]>
Date:   Mon Oct 12 11:41:45 2026 -0400

    io_uring/kbuf: don't charge provided buffer rings to RLIMIT_MEMLOCK
    
    [ Upstream commit cde56daf4b93f474dc256dbcc5205035223ae6f5 ]
    
    Just like with the SQ and CQ rings, the provided buffer rings were also
    not charged against the memlock limit prior to the below mentioned
    commit. Restore that behavior.
    
    Fixes: ef62de3c4ad5 ("io_uring/kbuf: use region api for pbuf rings")
    Reported-by: Hengyu Liang <[email protected]>
    Cc: [email protected]
    Tested-by: Hengyu Liang <[email protected]>
    Signed-off-by: Jens Axboe <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
io_uring/memmap: account the pages a compound region really uses [+ + +]
Author: Ali Ahmet Memis <[email protected]>
Date:   Mon Oct 12 11:39:17 2026 -0400

    io_uring/memmap: account the pages a compound region really uses
    
    [ Upstream commit f12f0234cc14886bcfd53ffb7c8df4216dad51f1 ]
    
    io_mem_alloc_compound() allocates get_order(size) pages, which rounds a
    region size that is not a power of two up to the next order. The pages
    past the region are part of the same allocation and cannot be used for
    anything else, but io_create_region() accounts reg->size >> PAGE_SHIFT,
    so they are never charged against RLIMIT_MEMLOCK. For a ring with 4096
    SQ entries and the default CQ size the region is 37 pages while the
    allocation is 64.
    
    Account the tail pages together with the region, and fall back to the
    exact sized bulk allocation when they do not fit the limit, so a user
    close to their limit still gets the region rather than an error.
    io_free_region() gives the same amount back, the compound case being the
    one that set IO_REGION_F_SINGLE_REF.
    
    Counting how many 4096 entry rings an unprivileged user can create under
    a given RLIMIT_MEMLOCK, before and after:
    
            limit (pages)   before  after
            256             2       2
            300             2       2
            350             3       2
            400             3       3
            512             5       4
    
    Five rings under a 512 page limit really pin 640 pages.
    
    Fixes: dfbbfbf19187 ("io_uring: introduce concept of memory regions")
    Link: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Ali Ahmet Memis <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jens Axboe <[email protected]>
    Stable-dep-of: b59cabf9b4ac ("io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK")
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6 [+ + +]
Author: Natasha Klaus <[email protected]>
Date:   Fri Oct 9 16:38:07 2026 +0300

    io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6
    
    commit aa5d5f8e502318e783545ba5d04bb40130b83e20 upstream.
    
    io_connect_bpf_populate() fills connect.port and connect.v6_addr for
    AF_INET6 only when addr_len >= sizeof(struct sockaddr_in6), i.e. 28
    bytes.
    
    The IPv6 connect paths accept SIN6_LEN_RFC2133 (24 bytes), which
    already holds sin6_port and sin6_addr. io_connect() passes addr_len to
    the socket layer unchanged.
    
    At addr_len 24 the filter sees family AF_INET6 with port and address
    zero, while the kernel connects to the real destination. A filter that
    denies an IPv6 port or address is bypassed. Denying connect.port == P
    rejects [::1]:P with -EACCES at addr_len 28 but connects at addr_len 24.
    
    Use SIN6_LEN_RFC2133 as the threshold. sin6_scope_id stays zero when
    absent.
    
    The threshold mismatch was found by an AI coding assistant (Claude Code)
    comparing this hook against the net/ipv6 length checks on my
    instructions; it also drafted the reproducer and this patch. I verified
    the bypass and the fix in a VM on 7.3-rc6 and that 7.2 has the same
    code.
    
    Fixes: 899bea8248ce ("io_uring/net: allow filtering on IORING_OP_CONNECT")
    Cc: [email protected] # 7.2
    Signed-off-by: Natasha Klaus <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jens Axboe <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
io_uring/register: don't exempt disabled rings from task restrictions [+ + +]
Author: Eugene Gvozdetsky <[email protected]>
Date:   Fri Oct 9 01:08:49 2026 +0200

    io_uring/register: don't exempt disabled rings from task restrictions
    
    commit 6da8f402e362b2f546e2efb7167fc9597aef6faf upstream.
    
    A ring created with IORING_SETUP_R_DISABLED is exempt from its register
    restrictions until it is enabled. This lets the creator register the
    restrictions and then enable the ring with IORING_REGISTER_ENABLE_RINGS,
    whether or not that opcode is in the allowed set.
    
    Since commit ed82f35b926b ("io_uring: allow registration of per-task
    restrictions"), a ring also inherits restrictions from the task that
    creates it, and the same exemption applies to those. A task whose
    register opcodes are restricted can therefore create a disabled ring,
    issue any register opcode on it, and then enable it.
    
    Mark rings whose restrictions were inherited from the task, and keep
    checking register opcodes for them while the ring is disabled. Enabling
    such a ring now requires IORING_REGISTER_ENABLE_RINGS to be in the
    task's allowed set. Per-ring restrictions registered on a disabled ring
    work as before.
    
    Fixes: ed82f35b926b ("io_uring: allow registration of per-task restrictions")
    Cc: [email protected]
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: Eugene Gvozdetsky <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    [axboe: amend with inheritance flag fixup]
    Signed-off-by: Jens Axboe <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK [+ + +]
Author: Hengyu Liang <[email protected]>
Date:   Mon Oct 12 11:39:18 2026 -0400

    io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK
    
    [ Upstream commit b59cabf9b4acb65f3f9968087ca0e18010d85076 ]
    
    Commit 8078486e1d53 ("io_uring: use region api for SQ") and commit
    81a4058e0cd0 ("io_uring: use region api for CQ") made io_uring_setup()
    allocate the rings with io_create_region().
    
    However, io_create_region() charges the memory to RLIMIT_MEMLOCK, and
    the rings had been exempt from that limit since commit 26bfa89e25f4
    ("io_uring: place ring SQ/CQ arrays under memcg memory limits"). As of
    now, a user without CAP_IPC_LOCK gets ENOMEM from io_uring_setup() when
    their rings exceed the limit, which is 8 MiB by default. PostgreSQL
    developers have already hit this in their io_uring tests [1].
    
    The issue can be reproduced with a simple liburing program, run as an
    unprivileged user:
    
        #include <liburing.h>
        #include <stdio.h>
    
        int main(void)
        {
                static struct io_uring ring[64];
                int i;
    
                for (i = 0; i < 64; i++)
                        if (io_uring_queue_init(4096, &ring[i], 0) < 0)
                                break;
                printf("%d rings\n", i);
                return 0;
        }
    
    Before those commits (v6.13), it prints "64 rings". After those commits
    (v6.14), it prints "21 rings".
    
    This patch makes io_create_region() take the user to charge, and passes
    no user for the SQ/CQ rings.
    
    Link: https://www.postgresql.org/message-id/flat/[email protected] [1]
    Fixes: 8078486e1d53 ("io_uring: use region api for SQ")
    Fixes: 81a4058e0cd0 ("io_uring: use region api for CQ")
    Cc: [email protected]
    Signed-off-by: Hengyu Liang <[email protected]>
    Link: https://lore.kernel.org/io-uring/[email protected]/
    Signed-off-by: Jens Axboe <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys [+ + +]
Author: Peng Fan <[email protected]>
Date:   Wed Sep 16 23:23:33 2026 +0800

    iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys
    
    [ Upstream commit 057e5e07420c753f248f9ce148040ab6dcf8359f ]
    
    MMIO resources mapped via dma_map_resource() carry DMA_ATTR_MMIO. These
    never need swiotlb bounce buffering, but the current code enters the
    swiotlb path when the physical address is not page-aligned, then rejects
    the mapping because MMIO cannot be bounced.
    
    Move the DMA_ATTR_MMIO check before the swiotlb block so the entire bounce
    path is skipped for MMIO, falling through directly to __iommu_dma_map()
    which creates the IOVA mapping.
    
    Fixes: f9374de14c0e8 ("iommu/dma: implement DMA_ATTR_MMIO for iommu_dma_(un)map_phys()")
    Assisted-by: Claude:claude-opus-4-6
    Signed-off-by: Peng Fan <[email protected]>
    Acked-by: Robin Murphy <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Signed-off-by: Marek Szyprowski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
ip6_gre: remove obsolete ERSPAN PMTU update [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Fri Oct 2 12:30:58 2026 +0900

    ip6_gre: remove obsolete ERSPAN PMTU update
    
    commit 8bc60db48e8cba35488bbd6e1f94aa990afa275a upstream.
    
    A tc tunnel_key action can attach a METADATA_IP_TUNNEL dst to an skb,
    and mirred can redirect it to a native ip6erspan device. The legacy PMTU
    update in ip6erspan_tunnel_xmit() treats that metadata dst as a route.
    Since it has no output device, dst_dev(dst)->mtu dereferences NULL.
    
    On v7.2 with KASAN, an initial UID/GID 65534 process with CapEff 0 used
    self-created user and network namespaces to trigger:
    
      KASAN: null-ptr-deref
      RIP: ip6erspan_tunnel_xmit+0x10fc/0x2cc0
      Kernel panic - not syncing: Fatal exception in interrupt
    
    The update is obsolete. Commit fe1a4ca0a2b7 ("ip6_gre: process toobig
    in a better way") changed IPv6 GRE Too Big handling to update the
    underlay route and removed the equivalent block from __gre6_xmit().
    ip6_tnl_xmit() then propagates the underlay PMTU to the overlay route.
    
    Remove the stale ERSPAN copy and its now-unused dst variable. This
    eliminates the metadata-dst dereference and keeps ERSPAN aligned with
    IPv6 GRE PMTU handling.
    
    Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
    Cc: [email protected]
    Suggested-by: Ido Schimmel <[email protected]>
    Signed-off-by: Daehyeon Ko <[email protected]>
    Reviewed-by: Ido Schimmel <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ipv4: do not warn on route notification size race [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Thu Oct 8 14:29:22 2026 +0900

    ipv4: do not warn on route notification size race
    
    commit e02a5b6588161673ef75a4bc5cdfb62bd493374d upstream.
    
    Commit 680aea08e78c ("net: ipv4: Emit notification when fib hardware
    flags are changed") added asynchronous route notifications for hardware
    flag changes.
    
    fib_alias_hw_flags_set() sizes the skb with fib_nlmsg_size() and later
    fills it with fib_dump_info() while holding only RCU.  With nexthop
    compatibility mode enabled, a concurrent replacement can grow the group
    between these independent snapshots.  fib_dump_info() can then
    legitimately return -EMSGSIZE, so the warning does not prove a sizing bug.
    
    Remove the warning.  The existing error path still frees the skb and
    reports the error to listeners.
    
    Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
    Reported-by: Ido Schimmel <[email protected]>
    Link: https://lore.kernel.org/netdev/20261004082043.GB92032@shredder/
    Suggested-by: Ido Schimmel <[email protected]>
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Link: https://patch.msgid.link/b7e203fc5867651cb67ef84aa03e082f0f76008e.1791423190.git.4ncienth@gmail.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ipv4: stop exception dump when nexthop group shrinks [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Fri Oct 2 13:50:59 2026 +0900

    ipv4: stop exception dump when nexthop group shrinks
    
    commit 4f4afc07dcb2edd4f9afa36595373f8cdb9b58c2 upstream.
    
    Commit 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU
    protection") allowed IPv4 FIB dumps to run concurrently with nexthop
    replacement.
    
    fib_dump_info_fnhe() uses fib_info_num_path() as the loop bound,
    then fib_info_nhc() independently reloads nh->nh_grp. If
    RTM_NEWNEXTHOP replaces a group with fewer paths between those loads,
    fib_info_nhc() returns NULL and the dump dereferences it through
    nhc_flags.
    
    Stop the walk when the indexed path is absent. Nexthop groups are
    dense, so the current snapshot has no later path.
    
    Fixes: 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection")
    Reported-by: Ido Schimmel <[email protected]>
    Link: https://lore.kernel.org/netdev/20261001170513.GA1657889@shredder/
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Reviewed-by: Ido Schimmel <[email protected]>
    Link: https://patch.msgid.link/5bb7bd97411eb9db454464bf449107395e760f26.1790915964.git.4ncienth@gmail.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ipv4: stop PMTU walk when nexthop group shrinks [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Fri Oct 2 13:50:58 2026 +0900

    ipv4: stop PMTU walk when nexthop group shrinks
    
    commit 6619e01855e65ef35723685a557e3eb106f4ecf5 upstream.
    
    Commit 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if
    multipath enabled") made __ip_rt_update_pmtu() update every path.
    
    For nexthop objects, fib_info_num_path() and fib_info_nhc()
    independently load nh->nh_grp.  RCU protects each group's lifetime but
    does not make the loads observe the same group.  If replacement shrinks
    the group after the loop accepts an index, fib_info_nhc() returns NULL
    and update_or_create_fnhe() dereferences it.
    
    A deterministic probe only widened the existing window between the real
    operations.  On v7.2, an RTM_NEWNEXTHOP replacement published a
    one-member group after the PMTU reader accepted index 1 from a two-member
    group, producing:
    
      KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
      RIP: update_or_create_fnhe+0x45/0x15b0
    
    Stop when the indexed path is absent.  Groups are dense, so no later
    index exists in that snapshot.  The same real-writer window completed
    114,423 PMTU iterations without an oops with this check.  A reproducer
    is available on request.
    
    Replacement requires CAP_NET_ADMIN in the network namespace.  Where
    unprivileged user namespaces are permitted, a local user can obtain it
    in a new user and network namespace.
    
    Fixes: 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if multipath enabled")
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Reviewed-by: Ido Schimmel <[email protected]>
    Link: https://patch.msgid.link/4fb87ed994dfc067178fc845cdd8bc9b5446b039.1790915964.git.4ncienth@gmail.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ipv4: stop route notification sizing when nexthop group shrinks [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Fri Oct 2 13:51:00 2026 +0900

    ipv4: stop route notification sizing when nexthop group shrinks
    
    commit d3daa33c7af92e38f2274bbd2576f58bfbaf89e6 upstream.
    
    Commit 680aea08e78c ("net: ipv4: Emit notification when fib
    hardware flags are changed") added an RCU-only fib_nlmsg_size() call
    for asynchronous hardware flag notifications.
    
    fib_nlmsg_size() checks fib_info_num_path() before each iteration,
    then fib_info_nhc() independently reloads nh->nh_grp. If
    RTM_NEWNEXTHOP replaces a group with fewer paths between those loads,
    fib_info_nhc() returns NULL and fib_nexthop_nlmsg_size() dereferences
    it.
    
    Stop sizing when the indexed path is absent. Nexthop groups are
    dense, so the current snapshot has no later path.
    
    Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Reviewed-by: Ido Schimmel <[email protected]>
    Link: https://patch.msgid.link/1054fa46165bba1b473782fa41367804aa908e86.1790915964.git.4ncienth@gmail.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ipv4: udp: Create exceptions before socket matching [+ + +]
Author: Ido Schimmel <[email protected]>
Date:   Fri Aug 28 22:23:42 2026 +0300

    ipv4: udp: Create exceptions before socket matching
    
    [ Upstream commit 4c3499f79f8c7e8561266bcc220a18538cec0458 ]
    
    Currently, when ICMP Fragmentation Needed and Redirect Message packets
    are locally delivered and quote a UDP packet, a FIB nexthop exception
    (FNHE) is only created if the kernel can match the UDP packet to an
    existing socket.
    
    This behavior allows off-path attackers to conduct a side-channel attack
    on the FNHE cache in order to discover the ephemeral port used by a
    connected UDP socket.
    
    Commit 6457378fe796 ("ipv4: use siphash instead of Jenkins in
    fnhe_hashfun()") and commit 67d6d681e15b ("ipv4: make exception cache
    less predictible") tried to mitigate such attacks by making it harder
    for attackers to discover hash collisions in the FNHE cache and by
    randomizing the number of exceptions a hash bucket can hold,
    respectively. Unfortunately, both of the mitigations can be bypassed.
    
    Instead, mitigate such attacks by always creating a FNHE, even before
    trying to find a matching socket. Do that by calling ipv4_update_pmtu()
    and ipv4_redirect(), the helpers used when the quoted packet did not
    originate from a socket.
    
    This means that guesses (right or wrong) from an off-path attacker will
    always result in a FNHE being created or updated in the cache that the
    attacker can observe.
    
    Pass an oif of 0, in a similar fashion to icmp_err(). This is also the
    oif used by the socket path for sockets that are not bound to a device.
    
    Note that this does not allow attackers to create FNHEs that they could
    not create before, as both helpers can already be reached with little to
    no validation. For example, by sending an ICMP error that quotes an ICMP
    Echo Reply or one that quotes a UDP source port that matches a wildcard
    socket.
    
    Also note that in the good case (matched socket) the above scheme comes
    at the cost of an extra route lookup, as the no socket helpers perform
    their own lookup before the one performed by ipv4_sk_update_pmtu() /
    ipv4_sk_redirect(). When the two resolve to different nexthops, it also
    results in two exceptions being created for the same destination IP. One
    in the FNHE cache of the nexthop resolved by the no socket helpers and
    another in the FNHE cache of the nexthop used by the socket.
    
    Fixes: 4895c771c7f0 ("ipv4: Add FIB nexthop exceptions.")
    Cc: [email protected]
    Reported-by: Amit Klein <[email protected]>
    Reported-by: Noam Caspi <[email protected]>
    Signed-off-by: Ido Schimmel <[email protected]>
    Reviewed-by: David Ahern <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

ipv4: validate checksum_start before completing checksum [+ + +]
Author: Michael S. Tsirkin <[email protected]>
Date:   Wed Oct 7 18:42:49 2026 -0400

    ipv4: validate checksum_start before completing checksum
    
    commit 6785011f8b16abf40b1e9d8b2e332232b3e68822 upstream.
    
    If a packet with bad checksum metadata gets into the ipv4 stack,
    skb_checksum_help can corrupt the network header and cause a bunch of
    mischief.
    
    This was discovered and reported by Paulos, and has been reporoduced
    by others independently since.
    
    We really shouldn't allow such packets in, but as a defence
    in depth measure, let's also check before we complete the checksum.
    
    A more complete validation at input is forthcoming, but needs more work.
    
    Cc: [email protected]
    Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr")
    Fixes: bfd5f4a3d605 ("packet: Add GSO/csum offload support.")
    Reported-by: Paulos Yibelo <[email protected]>
    Closes: https://lore.kernel.org/netdev/[email protected]/
    Signed-off-by: Michael S. Tsirkin <[email protected]>
    Reviewed-by: Willem de Bruijn <[email protected]>
    Link: https://patch.msgid.link/0a012b4923e189c4c593ef4f471e5ff0edbe9030.1791412497.git.mst@redhat.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ipv6: do not warn on route notification size race [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Thu Oct 8 14:29:23 2026 +0900

    ipv6: do not warn on route notification size race
    
    commit c97426ec649d99596d8969e1a052c16b14b7b485 upstream.
    
    fib6_info_hw_flags_set() sizes the skb with rt6_nlmsg_size() and later
    fills it with rt6_fill_node().  With nexthop compatibility mode enabled,
    a concurrent replacement can grow the group between these independent
    snapshots.  rt6_fill_node() can then legitimately return -EMSGSIZE, so
    the warning does not prove a sizing bug.
    
    Remove the warning.  The existing error path still frees the skb and
    reports the error to listeners.
    
    Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed")
    Reported-by: Ido Schimmel <[email protected]>
    Link: https://lore.kernel.org/netdev/20261007114003.GA1011260@shredder/
    Suggested-by: Ido Schimmel <[email protected]>
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Link: https://patch.msgid.link/4012604727e5ba80b69ccd4d08796511397ddaef.1791423190.git.4ncienth@gmail.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

ipv6: Fix redirect exception creation for UDP/RAW sockets [+ + +]
Author: Ido Schimmel <[email protected]>
Date:   Fri Aug 28 22:23:41 2026 +0300

    ipv6: Fix redirect exception creation for UDP/RAW sockets
    
    [ Upstream commit cd51b74bdd0b75aedf255dc67306a16dd057f7ee ]
    
    When an ICMP Redirect Message is matched to a socket, both IPv4 and IPv6
    verify that the source IP of the ICMP packet is the current gateway for
    the quoted packet. Both also pass the socket's bound device as the
    expected nexthop device.
    
    The difference is that IPv4 treats "oif=0" as "any", whereas IPv6 always
    requires an exact match (see ip6_redirect_nh_match()), since the gateway
    address is usually a link-local address.
    
    Therefore, when an IPv6 UDP/RAW socket is not bound to a device, the
    above verification fails and an exception is not created. This also
    happens when the socket is bound to a VRF, as l3mdev_update_flow()
    resets the oif to 0.
    
    Fix this by passing the ifindex of the ingress device as the expected
    nexthop device. This is consistent with the existing callers of
    ip6_redirect(). Note that for ICMPv6 Redirect Message packets the VRF
    driver does not reset skb->dev to the VRF device, so skb->dev is
    correct, even when it is a VRF port.
    
    Fixes: b55b76b22144 ("ipv6:introduce function to find route for redirect")
    Cc: [email protected]
    Reviewed-by: Eric Dumazet <[email protected]>
    Reviewed-by: David Ahern <[email protected]>
    Signed-off-by: Ido Schimmel <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

ipv6: udp: Create exceptions before socket matching [+ + +]
Author: Ido Schimmel <[email protected]>
Date:   Fri Aug 28 22:23:43 2026 +0300

    ipv6: udp: Create exceptions before socket matching
    
    [ Upstream commit ac76cab50e899a7346408b8d3c3a4192c2eefb9f ]
    
    Currently, when ICMPv6 Packet Too Big and Redirect Message packets are
    locally delivered and quote a UDP packet, an exception is only created
    in the IPv6 exception cache if the kernel can match the UDP packet to an
    existing socket.
    
    This behavior allows off-path attackers to conduct a side-channel attack
    on the exception cache in order to discover the ephemeral port used by a
    connected UDP socket.
    
    Commit 4785305c05b2 ("ipv6: use siphash in rt6_exception_hash()") and
    commit a00df2caffed ("ipv6: make exception cache less predictible") tried
    to mitigate such attacks by making it harder for attackers to discover
    hash collisions in the exception cache and by randomizing the number of
    exceptions a hash bucket can hold, respectively. Unfortunately, both of
    the mitigations can be bypassed.
    
    Instead, mitigate such attacks by always creating an exception, even
    before trying to find a matching socket. Do that by calling
    ip6_update_pmtu() and ip6_redirect(), the helpers used when the quoted
    packet did not originate from a socket.
    
    This means that guesses (right or wrong) from an off-path attacker will
    always result in an exception being created or updated in the cache that
    the attacker can observe.
    
    Pass the ifindex of the ingress device and the default uid, in a similar
    fashion to icmpv6_err(). Unlike IPv4, an oif of 0 would not match any
    nexthop in ip6_redirect_nh_match() and no exception would be created in
    response to a Redirect Message.
    
    Note that this does not allow attackers to create exceptions that they
    could not create before, as both helpers can already be reached with
    little to no validation. For example, by sending an ICMPv6 error that
    quotes an ICMPv6 Echo Reply or one that quotes a UDP source port that
    matches a wildcard socket.
    
    Also note that in the good case (matched socket) the above scheme comes
    at the cost of an extra route lookup, as the no socket helpers perform
    their own lookup before the one performed by ip6_sk_update_pmtu() /
    ip6_sk_redirect(). When the two resolve to different nexthops, it also
    results in two exceptions being created for the same destination IP. One
    in the exception cache of the nexthop resolved by the no socket helpers
    and another in the exception cache of the nexthop used by the socket.
    
    Fixes: 2b760fcf5cfb ("ipv6: hook up exception table to store dst cache")
    Cc: [email protected]
    Reported-by: Amit Klein <[email protected]>
    Reported-by: Noam Caspi <[email protected]>
    Signed-off-by: Ido Schimmel <[email protected]>
    Reviewed-by: David Ahern <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
keys: finalize persistent keyring timeout after link attempt [+ + +]
Author: Karl Mehltretter <[email protected]>
Date:   Sat Sep 12 11:54:40 2026 +0200

    keys: finalize persistent keyring timeout after link attempt
    
    commit 25bf14f817168079f731975b8998fc2af380f29e upstream.
    
    When no keyring exists for the requested UID, KEYCTL_GET_PERSISTENT
    creates and registers one before linking it to the requested destination.
    The configured timeout is set only after the destination link succeeds.
    
    A destination restricted with KEYCTL_RESTRICT_KEYRING makes that link fail
    with -EPERM. With persistent_keyring_expiry set to 60 seconds, /proc/keys
    still reports the registered keyring's expiry as "perm".
    The failed call therefore leaves a quota-exempt keyring in the namespace's
    hidden register, where it may remain until namespace teardown.
    
    Rename the write-locked helper to key_get_or_create_persistent() and return
    the key reference through a result parameter. Return 0 when it creates a
    keyring and 1 when the retry finds an existing one. Return a negative error
    on failure. Another caller may create the keyring between the initial
    read-locked lookup and the retry under the write lock.
    
    Set the timeout after permission checking and linking. Do this on success,
    or on failure if the call allocated the keyring. This leaves a new keyring
    collectible after failure without starting its timeout while linking is
    still in progress.
    
    Cc: [email protected] # v5.10+
    Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
    Assisted-by: LLM
    Signed-off-by: Karl Mehltretter <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Reviewed-by: Jarkko Sakkinen <[email protected]>
    Signed-off-by: Jarkko Sakkinen <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
KEYS: Fix add_key() race with keyring restriction [+ + +]
Author: 성병찬 <[email protected]>
Date:   Wed Sep 30 13:18:01 2026 +0900

    KEYS: Fix add_key() race with keyring restriction
    
    commit dd3ea3fcba7c75493760cdbccd35f029597e8d5e upstream.
    
    __key_create_or_update() snapshots keyring->restrict_link before taking
    the destination keyring's semaphore.  keyring_restrict() installs a
    restriction while holding that semaphore.
    
    This allows a writer to observe no restriction, wait for the keyring
    owner to install a reject-all restriction and return successfully, and
    then link a key using the stale NULL snapshot.  The writer only needs
    write permission on the destination keyring.
    
    Move the restrict_link read after __key_link_lock() and
    __key_link_begin().  The read and the subsequent restriction check are
    then serialized with restriction installation by keyring->sem.
    
    The race was reproduced on v7.2.8 in 19 executions where restriction
    installation returned before the link completed.  All 19 linked the key
    despite the reject-all restriction.  With this change, 312 executions
    reached the same ordering and every add_key() call failed with -EPERM.
    
    The issue was found by manual concurrency analysis assisted by AI-based
    analysis and independently verified with a QEMU reproducer and kernel
    instrumentation.
    
    Fixes: 5ac7eace2d00 ("KEYS: Add a facility to restrict new links into a keyring")
    Cc: [email protected]
    Signed-off-by: 성병찬 <[email protected]>
    Reviewed-by: Jarkko Sakkinen <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Signed-off-by: Jarkko Sakkinen <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
lib/dim: fix 32-bit overflow in dim_calc_stats() rates [+ + +]
Author: Shashank Mohan Jain <[email protected]>
Date:   Sun Sep 27 10:47:42 2026 +0530

    lib/dim: fix 32-bit overflow in dim_calc_stats() rates
    
    [ Upstream commit 0843b23890642a02ff85c36406224e8874e30664 ]
    
    dim_calc_stats() computes the per-millisecond rates as
    
            DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us)
    
    where nbytes is a u32 and USEC_PER_MSEC is 1000L. On 64-bit the product
    is done in 64-bit long arithmetic, but on 32-bit architectures long is
    32 bits wide and the product wraps as soon as a measurement window
    carries more than 4294967 bytes (about 4.3 MB). The same applies to the
    packet and completion counts, although those need more than 4.29
    million packets or completions per window.
    
    A DIM window spans DIM_NEVENTS (64) events. Drivers count events per
    interrupt or per NAPI poll, so under sustained load a window can easily
    carry more than 4.3 MB: 64 full NAPI polls of 64 MTU-sized frames are
    already 6.2 MB, and drivers such as mtk_eth_soc count one event per
    interrupt while NAPI keeps polling with the interrupt masked. On 32-bit
    users of the library (for example mtk_eth_soc on MT7621, bcmgenet and
    bcmsysport on 32-bit ARM, or virtio_net in a 32-bit guest) bpms then
    becomes the product modulo 2^32 divided by the window length, and
    net_dim_stats_compare() makes its BETTER/WORSE decisions on a value
    that has little to do with the real throughput.
    
    For example, a 1 Gbit/s link at line rate that moves 5 MB in a 40 ms
    window gives bpms = 125000 on 64-bit but 17626 on 32-bit, and 5 million
    packets in 2 s gives ppms = 353 instead of 2500.
    
    Widen the products to 64 bits and divide with DIV_ROUND_UP_ULL(). The
    results are unchanged on 64-bit.
    
    Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
    Fixes: 4c4dbb4a7363 ("net/mlx5e: Move dynamic interrupt coalescing code to include/linux")
    Assisted-by: LLM
    Signed-off-by: Shashank Mohan Jain <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
Linux: Linux 7.2.11 [+ + +]
Author: Greg Kroah-Hartman <[email protected]>
Date:   Thu Oct 15 12:00:08 2026 +0200

    Linux 7.2.11
    
    Link: https://lore.kernel.org/r/[email protected]
    Tested-by: Ronald Warsow <[email protected]>
    Tested-by: Miguel Ojeda <[email protected]>
    Tested-by: Florian Fainelli <[email protected]>
    Tested-by: Salvatore Bonaccorso <[email protected]>
    Tested-by: Peter Schneider <[email protected]>
    Tested-by: Shuah Khan <[email protected]>
    Tested-by: Justin M. Forbes <[email protected]>
    Tested-by: Brett A C Sheffield <[email protected]>
    Link: https://lore.kernel.org/r/[email protected]
    Tested-by: Brett A C Sheffield <[email protected]>
    Tested-by: Ronald Warsow <[email protected]>
    Tested-by: Peter Schneider <[email protected]>
    Tested-by: Pavel Machek (CIP) <[email protected]>
    Tested-by: Florian Fainelli <[email protected]>
    Tested-by: SJ Park <[email protected]>
    Tested-by: Ron Economos <[email protected]>
    Tested-by: Miguel Ojeda <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
memstick: core: wait for request completion before freeing card [+ + +]
Author: Raj Ojha <[email protected]>
Date:   Fri Sep 25 00:59:55 2026 +0530

    memstick: core: wait for request completion before freeing card
    
    commit aa0a37b5024d921e96ac4f8f487c8bfbf1f1a582 upstream.
    
    In memstick_alloc_card() and memstick_set_rw_addr(),
    wait_for_completion_timeout() is used to wait for device identification
    and address configuration requests to complete.
    
    The memstick subsystem does not provide an abort or cancellation
    callback in struct memstick_host for in-flight requests. If
    wait_for_completion_timeout() expires (for instance, when a USB transfer
    or command retry is delayed), memstick_alloc_card() returns an error and
    frees the memstick_dev structure via kfree(card).
    
    However, the host controller driver (such as rtsx_usb_ms) is still
    running the request asynchronously in worker context. When the transfer
    eventually finishes, the driver writes into host->req->data, which
    points to memory inside the already freed card structure. This leads to
    a KASAN slab-use-after-free write:
    
      BUG: KASAN: slab-use-after-free in ms_read_bytes+0x8fe/0x990
      Write of size 1 at addr ffff88813c188079 by task kworker/1:5/5239
      Workqueue: events rtsx_usb_ms_handle_req
      Call Trace:
       ms_read_bytes+0x8fe/0x990 drivers/memstick/host/rtsx_usb_ms.c:450
       rtsx_usb_ms_issue_cmd drivers/memstick/host/rtsx_usb_ms.c:477 [inline]
       rtsx_usb_ms_handle_req+0x557/0x1a00 drivers/memstick/host/rtsx_usb_ms.c:531
       process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
       worker_thread+0x5ef/0xe50 kernel/workqueue.c:3560
       kthread+0x373/0x450 kernel/kthread.c:436
    
      Allocated by task 1662:
       memstick_alloc_card drivers/memstick/core/memstick.c:383 [inline]
       memstick_check+0x2c1/0x10d0 drivers/memstick/core/memstick.c:452
       process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
    
      Freed by task 1662:
       kfree+0x20c/0x650 mm/slub.c:6792
       memstick_alloc_card drivers/memstick/core/memstick.c:420 [inline]
       memstick_check+0x72b/0x10d0 drivers/memstick/core/memstick.c:452
       process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
    
    Host controller drivers (rtsx_usb_ms, jmb38x_ms, tifm_ms, r592) already
    implement their own hardware and bus timeouts, and callers in
    mspro_block and ms_block already rely on wait_for_completion()
    unconditionally.
    
    Replace wait_for_completion_timeout() with wait_for_completion() in
    memstick_set_rw_addr() and memstick_alloc_card() so that the card
    structure is never freed while an asynchronous request is in flight.
    
    Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support")
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=ccffdf05833ebdaeae70
    Cc: [email protected]
    Signed-off-by: Raj Ojha <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

memstick: rtsx_usb_ms: complete requests after eject instead of dropping them [+ + +]
Author: Nguyen Ngoc Thang <[email protected]>
Date:   Wed Sep 30 21:07:48 2026 +0700

    memstick: rtsx_usb_ms: complete requests after eject instead of dropping them
    
    commit c96ca94425b076dc398d929366e378d1e22ec794 upstream.
    
    memstick_check() can pass its host->removing check just before
    rtsx_usb_ms_drv_remove() sets eject/removing. Its next request is then
    silently dropped: rtsx_usb_ms_request() skips schedule_work() once eject
    is set, and drv_remove's cancel_work_sync() can also cancel a queued
    handle_req before it picks the request up. Nobody completes
    card->mrq_complete.
    
    Once memstick core waits for requests without a timeout ("memstick: core:
    wait for request completion before freeing card"), this hangs removal:
    memstick_check() never returns and memstick_remove_host() blocks in
    flush_workqueue():
    
      INFO: task kworker/u10:3:65 blocked for more than 20 seconds.
      Workqueue: kmemstick memstick_check
       __wait_for_common
       memstick_check
    
      INFO: task kworker/1:1:33 blocked for more than 20 seconds.
      Workqueue: usb_hub_wq hub_event
       __flush_workqueue
       memstick_remove_host
       rtsx_usb_ms_drv_remove
    
    Never drop a request. rtsx_usb_ms_request() always schedules handle_req,
    and handle_req fails requests with -ENOMEDIUM once eject is set, without
    touching the device. drv_remove flushes handle_req instead of cancelling
    it, and cancels it only after memstick_remove_host(), when no new
    request can arrive, so it cannot run on a freed host.
    
    The host_mutex drain in drv_remove is removed: handle_req always leaves
    host->req NULL when it finishes, so the drain never had anything to do,
    and it would now race with handle_req.
    
    Fixes: 99451dceeb5f ("memstick: Add realtek USB memstick host driver")
    Cc: [email protected]
    Link: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Nguyen Ngoc Thang <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
mlxsw: spectrum_flower: Fix port range register leak in tmplt_create() [+ + +]
Author: Petr Machata <[email protected]>
Date:   Tue Oct 6 16:21:28 2026 +0200

    mlxsw: spectrum_flower: Fix port range register leak in tmplt_create()
    
    [ Upstream commit 7ea07afb230f1342ab0f9365edd0aae137f425d3 ]
    
    mlxsw_sp_flower_tmplt_create() parses a flow_cls_offload template
    into a stack-local struct mlxsw_sp_acl_rule_info purely to compute
    rulei.values.elusage. Parsing can acquire port range registers via
    mlxsw_sp_flower_parse_ports_range(), but since this rulei never goes
    through mlxsw_sp_acl_rulei_destroy(), those registers were never
    released, including through chain template deletion.
    
    Factor out of mlxsw_sp_acl_rulei_destroy() the code to actually
    release the necessary resources and call from
    mlxsw_sp_flower_tmplt_create() to plug the leak.
    
    The issue was found during a review of Wentao Liang's patch referenced
    below.
    
    Fixes: fe22f7410527 ("mlxsw: spectrum_flower: Add ability to match on port ranges")
    Reported-by: Wentao Liang <[email protected]>
    Closes: https://lore.kernel.org/netdev/[email protected]/
    Reviewed-by: Ido Schimmel <[email protected]>
    Signed-off-by: Petr Machata <[email protected]>
    Reviewed-by: Jacob Keller <[email protected]>
    Link: https://patch.msgid.link/95339cf970ce78e1a74aa86ffcc104ecf7c7762c.1791294384.git.petrm@nvidia.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP [+ + +]
Author: Lorenzo Stoakes (ARM) <[email protected]>
Date:   Wed Sep 30 19:47:10 2026 +0100

    mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP
    
    commit 597e4b9ab48a3f841080f627722064853d3f650e upstream.
    
    The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
    operations that keep the original VMA in place.
    
    Historically this has led to a lot of bugs where non-obvious interactions
    occur between existing mremap() operations and the original VMA.
    
    Fix another of these - partial copies.
    
    The long-standing mremap() partial VMA logic has the baked-in assumption
    that the originating VMA is unmapped and thus moved.
    
    However MREMAP_DONTUNMAP defeats this by performing a partial copy
    instead since it keeps the source VMA around.
    
    An mremap(..., MREMAP_DONTUNMAP) operation disallows resizing of the VMA,
    but the operation can be performed partially:
    
                               |-----------------|
                               |                 |
                               |                 v
                            <------>          <------>
                            .new_sz.           new_sz
                         |--.------.--|       |------|
                         |  .source.  |       | dest |
                         |--.------.--|       |------|
                         <------------>
                             old_sz
    
    The page tables in the specified range are moved, but the original VMA is
    kept intact.
    
    This interacts poorly with mlock()'d VMAs, as the VMA_LOCKED_BIT flag is
    cleared for the entire source VMA and set for the entire destination VMA.
    
    This results in an mm->locked_vm leak as the change is therefore not
    accounted correctly.
    
    The clear solution here is to make the portion of the source VMA which is
    mremap()'d distinct from the rest of it, a.k.a. split it.
    
    Therefore resolve this issue by splitting it ahead of the rest of the
    mremap() operation if the VMA is mlock()'d.
    
    This is valid, as the source VMA will lose its VMA_LOCKED_BIT flag, so if a
    partial remap it will become distinct from the rest of the VMA.
    
    In order to make this change re-expose split_vma() in vma.h for
    CONFIG_MMU (nommu doesn't compile mremap.c and uses a static helper
    instead).
    
    Finally, update the sys_map_count check to account for this case.
    
    Note that the early check does not use needs_pre_split() - this is because
    the VMA has not been looked up by this point, so be conservative and assume
    that the VMA is mlock()'d in this case for the purposes of the
    sys_map_count check.
    
    Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-2-f388985a0f0a@kernel.org
    Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
    Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Reviewed-by: Pedro Falcato <[email protected]>
    Acked-by: Kiryl Shutsemau (Meta) <[email protected]>
    Reviewed-by: Jose A. Perez de Azpillaga <[email protected]>
    Tested-by: Anirudh Srinivasan <[email protected]>
    Cc: Liam R. Howlett <[email protected]>
    Cc: Vlastimil Babka <[email protected]>
    Cc: Jann Horn <[email protected]>
    Cc: Brian Geffon <[email protected]>
    Cc: Minchan Kim <[email protected]>
    Cc: <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge [+ + +]
Author: Lorenzo Stoakes (ARM) <[email protected]>
Date:   Mon Oct 12 14:46:28 2026 -0400

    mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge
    
    [ Upstream commit 838bb60dc21553e32df90f2f3bac5b905376e7aa ]
    
    Patch series "mm/mremap: fix two issues with MREMAP_DONTUNMAP", v2.
    
    The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
    operations that keep the original VMA in place.
    
    Historically this has led to a lot of bugs where non-obvious interactions
    occur between existing mremap() operations and the original VMA.
    
    Commit 397432cab17b ("mm/mremap: account mm->locked_vm correctly for
    MREMAP_DONTUNMAP") fixed an accidentally introduced bug around
    mm->locked_vm accounting, but this wasn't the only issue.
    
    And thus history repeats itself, as it turns out that mm->locked_vm
    accounting is broken by MREMAP_DONTUNMAP yet again by two further cases,
    and has been broken ever since the feature was introduced.
    
    Both relate to the fact that VMA_LOCKED_BIT is cleared on the source VMA
    (it has to be as all page tables are moved):
    
    1. If an unfaulted VMA_LOCKONFAULT_BIT anonymous VMA self-merges it
       clears the VMA_LOCKED_BIT flag and permanently leaks mm->locked_vm
       pages.
    
    2. If a partial mremap() is performed on a locked VMA there is a leak equal
       to the number of pages not copied.
    
    (Both for MREMAP_DONTUNMAP operations only)
    
    Both issues can be fixed by treating the source range as distinct from the
    destination range, which is the definition of what MREMAP_DONTUNMAP does
    so is appropriate.
    
    In case 1, simply disallow the self-merge, keeping adjacent source and
    destination VMAs distinct.
    
    In case 2, split the source range ahead of time if the VMA is mlock()'d,
    so accounting is always correct.
    
    Both changes were tested locally and confirmed to fix the issues.
    
    For the purposes of a backport, the fixes are kept distinct, a follow-up
    series can add self-tests.
    
    This patch (of 2):
    
    The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
    operations that keep the original VMA in place.
    
    Historically this has led to a lot of bugs where non-obvious interactions
    occur between existing mremap() operations and the original VMA.
    
    Fix another of these - self-merge.
    
    Self-merge occurs when a VMA is moved in front of or behind itself and the
    attributes of the VMA permit such a merge.
    
    Practically this can only happen for unfaulted anonymous VMAs due to the
    page offset equality requirement for merge:
    
                               |------------|
                               |            |
                               |            v
            |...........||-----------||...........|
            |           || unfaulted ||           |
            |...........||-----------||...........|
                  ^            |
                  |            |
                  |------------|
    
    This becomes problematic if the VMA is configured by the user to
    mlock-on-fault, i.e. the VMA_LOCKED_BIT, VMA_LOCKONFAULT_BIT VMA flags are
    set.
    
    MREMAP_DONTUNMAP clears mlock flags for the source VMA and maintains them
    for the destination VMA.
    
    Self-merge makes this impossible (there is only one VMA) and incorrectly
    clears the destination VMA's mlock flags.
    
    This causes a leak in mm->locked_vm as clearing this flag does not
    decrement the counter and the VMA no longer has VMA_LOCKED_BIT set so it
    is not decremented on unmap.
    
    Resolve this by simply disallowing a self-merge in this case - the source
    and destination VMAs are kept distinct and then are able to have distinct
    mlock() flags.
    
    Update dontunmap_complete() to make the now-redundant self-merge check a
    VM_WARN_ON_ONCE() instead to guard against future regressions.
    
    Also update the VMA userland tests to reflect the change.
    
    Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-0-f388985a0f0a@kernel.org
    Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-1-f388985a0f0a@kernel.org
    Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
    Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Reviewed-by: Pedro Falcato <[email protected]>
    Acked-by: Kiryl Shutsemau (Meta) <[email protected]>
    Reviewed-by: Jose A. Perez de Azpillaga <[email protected]>
    Tested-by: Anirudh Srinivasan <[email protected]>
    Cc: Liam R. Howlett <[email protected]>
    Cc: Vlastimil Babka <[email protected]>
    Cc: Jann Horn <[email protected]>
    Cc: Brian Geffon <[email protected]>
    Cc: Minchan Kim <[email protected]>
    Cc: <[email protected]>
    [ sashal: Adapted can_self_merge logic to the inverse faulted_in_anon_vma flag. ]
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
mm: don't schedule deferred kernel page table freeing while booting [+ + +]
Author: Mikhail Gavrilov <[email protected]>
Date:   Fri Sep 25 10:06:47 2026 +0500

    mm: don't schedule deferred kernel page table freeing while booting
    
    commit 2fb552b0bee70c24c092720028ab4620f5eb2646 upstream.
    
    Booting with a boot-time function tracer and a filter, for example
    
      ftrace=function ftrace_filter=pud_free_pmd_page
    
    panics on 7.3-rc4 as soon as the tracer starts:
    
      [   23.531178] Starting tracer 'function'
      [   23.675800] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000038: 0000 [#1] SMP KASAN NOPTI
      [   23.819917] KASAN: null-ptr-deref in range [0x00000000000001c0-0x00000000000001c7]
      [   23.964025] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 7.3.0-rc4-fe2ec83746e5-with-fixes-v2+ #195 PREEMPT(undef)
      [   24.252248] RIP: 0010:__queue_work+0xab/0xf00
      [   25.981629] Call Trace:
      [   26.125727]  <TASK>
      [   26.413912]  ? pagetable_free_kernel+0x20/0x120
      [   26.990283]  queue_work_on+0x97/0xf0
      [   27.134382]  __cpa_collapse_large_pages+0x501/0x6f0
      [   27.566662]  cpa_flush+0x394/0x620
      [   27.998953]  change_page_attr_set_clr+0x321/0x4a0
      [   29.151729]  set_memory_rox+0xa2/0xf0
      [   29.584018]  create_trampoline+0x431/0x6f0
      ...
      [   44.343347] Kernel panic - not syncing: Attempted to kill the idle task!
    
    The boot-time tracer is started from early_trace_init(), which runs
    before workqueue_init_early().  Making its trampoline read-only splits a
    large page, and CPA collapses it again right away.  The split table has
    been a kernel page table since commit 9e4a3ec3411b
    ("x86/mm/pat: Allocate split page tables as kernel page tables"), so the
    collapse frees it through pagetable_free_kernel(), which queues work on
    system_percpu_wq - still NULL at that point.  That commit is correct in
    itself; it only lets CPA reach pagetable_free_kernel() before the
    workqueue that function relies on exists.
    
    Keep putting the table on the list, but don't schedule the work while
    the system is still booting.  A core_initcall schedules it once to free
    whatever was queued by then.
    
    Link: https://lore.kernel.org/[email protected]
    Link: https://lore.kernel.org/[email protected]
    Fixes: 9e4a3ec3411b ("x86/mm/pat: Allocate split page tables as kernel page tables")
    Signed-off-by: Mikhail Gavrilov <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Suggested-by: David Hildenbrand (Arm) <[email protected]>
    Suggested-by: Lorenzo Stoakes (ARM) <[email protected]>
    Reviewed-by: Andrew Morton <[email protected]>
    Reviewed-by: David Hildenbrand (Arm) <[email protected]>
    Reviewed-by: Lorenzo Stoakes (ARM) <[email protected]>
    Reviewed-by: Jose A. Perez de Azpillaga <[email protected]>
    Tested-by: Jose A. Perez de Azpillaga <[email protected]>
    Cc: Dave Hansen <[email protected]>
    Cc: Liam R. Howlett <[email protected]>
    Cc: Vlastimil Babka <[email protected]>
    Cc: Mike Rapoport <[email protected]>
    Cc: Suren Baghdasaryan <[email protected]>
    Cc: Michal Hocko <[email protected]>
    Cc: Vishal Moola (Oracle) <[email protected]>
    Cc: Ingo Molnar <[email protected]>
    Cc: Lu Baolu <[email protected]>
    Cc: Jason Gunthorpe <[email protected]>
    Cc: Steven Rostedt <[email protected]>
    Cc: <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
mmc: cavium-octeon: destroy slot platform devices on remove [+ + +]
Author: Guangshuo Li <[email protected]>
Date:   Tue Sep 15 23:57:24 2026 +0800

    mmc: cavium-octeon: destroy slot platform devices on remove
    
    commit 0f4d4424fc1d651ec3fa63a0a8060ba9087eb0ec upstream.
    
    octeon_mmc_probe() creates host->slot_pdev[i] with
    of_platform_device_create(), while octeon_mmc_remove() does not destroy
    the child platform devices.
    
    The probe failure path removes each MMC slot and destroys its associated
    platform device, but the normal remove path only removes the MMC slot.
    As a result, the child platform devices remain registered after the
    Octeon MMC controller is removed.
    
    Destroy each slot platform device during removal after cleaning up the
    corresponding MMC slot, matching the probe failure cleanup path.
    
    This issue was found by manual code inspection.
    
    Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.")
    Cc: [email protected]
    Signed-off-by: Guangshuo Li <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

mmc: cavium-thunderx: destroy slot platform devices on remove [+ + +]
Author: Guangshuo Li <[email protected]>
Date:   Wed Sep 16 00:13:10 2026 +0800

    mmc: cavium-thunderx: destroy slot platform devices on remove
    
    commit 29ee8cf18a21b02cd0b2e35f741b61cd1fe3e14e upstream.
    
    thunder_mmc_probe() creates host->slot_pdev[i] with
    of_platform_device_create(), while thunder_mmc_remove() does not destroy
    the child platform devices.
    
    The probe failure path removes each MMC slot and destroys its associated
    platform device, but the normal remove path only removes the MMC slot.
    As a result, the child platform devices remain registered after the
    ThunderX MMC controller is removed.
    
    Destroy each slot platform device during removal after cleaning up the
    corresponding MMC slot, matching the probe failure cleanup path. Keep an
    extra device reference around of_platform_device_destroy() as done in
    the existing error path.
    
    This issue was found by manual code inspection.
    
    Fixes: 166bac38c3c56 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs")
    Cc: [email protected]
    Signed-off-by: Guangshuo Li <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

mmc: mtk-sd: Cancel request timeout work on remove [+ + +]
Author: Yibo Tan <[email protected]>
Date:   Tue Sep 15 22:44:57 2026 +0800

    mmc: mtk-sd: Cancel request timeout work on remove
    
    commit b38af5386a74416e898955443f2e26547b358cb2 upstream.
    
    The driver queues req_timeout while a request is active.
    msdc_request_done() uses cancel_delayed_work(), which does not wait for
    a timeout callback that has already started.
    
    The timeout callback calls mmc_request_done(), which wakes the request
    waiter, and then continues to use host->dev_comp and check the SDIO IRQ.
    During unbind, msdc_drv_remove() can return and the managed mmc_host can
    be freed before the callback finishes.
    
    KASAN reported use-after-free accesses in msdc_request_done() and
    msdc_recheck_sdio_irq() in each of three unbind tests.  The same tests
    completed without a kernel diagnostic after this change.
    
    Call cancel_delayed_work_sync() after mmc_remove_host() has stopped new
    requests and before the driver releases the host resources.
    
    Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver")
    Cc: [email protected]
    Assisted-by: Codex:GPT-5
    Signed-off-by: Yibo Tan <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

mmc: sdhci-sprd: disable runtime PM on remove [+ + +]
Author: Guangshuo Li <[email protected]>
Date:   Wed Sep 16 00:19:47 2026 +0800

    mmc: sdhci-sprd: disable runtime PM on remove
    
    commit e1c6c10a6a70a69e29b04fcc1ebe4b9bcbc7a49a upstream.
    
    sdhci_sprd_probe() enables runtime PM, while sdhci_sprd_remove() does
    not perform the corresponding runtime PM cleanup.
    
    The probe failure path disables runtime PM before disabling the clocks,
    but the normal remove path directly disables clocks that are also
    managed by the runtime PM callbacks. If the device is runtime
    suspended, those clocks may already be disabled.
    
    Resume the device before removal, disable runtime PM and drop the
    temporary runtime PM reference before disabling the clocks.
    
    This issue was found by manual code inspection.
    
    Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
    Cc: [email protected]
    Signed-off-by: Guangshuo Li <[email protected]>
    Reviewed-by: Baolin Wang <[email protected]>
    Acked-by: Adrian Hunter <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
mount: keep a copied mount unbindable [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 23 14:27:53 2026 +0200

    mount: keep a copied mount unbindable
    
    commit 1ab8904ae61b076d1242e1f48537698c77074b5c upstream.
    
    It's groundhog day.
    
    MNT_UNBINDABLE used to be set in in mnt->mnt.mnt_flags and was not part
    of MNT_INTERNAL_FLAGS. clone_mnt() copied it with all the other flags to
    the new mount. This guaranteed that the copy of an unbindable mount
    became unbindable as well. Unbindable copies that ended up as shared
    lost the unbindable property.
    
    But then commit 406fea799925 ("mount: separate the flags accessed only
    under namespace_sem") moved MNT_UNBINDABLE from mnt->mnt.mnt_flags into
    mnt->mnt_t_flags as T_UNBINDABLE.
    
    clone_mnt() doesn't copy from mnt_t_flags and specifically doesn't copy
    T_UNBINDABLE. The only place a mount gets marked unbindable is in
    change_mnt_propagation() for MS_UNBINDABLE.
    
    This reintroduced an earlier bug we had already fixed. It resurfaces in
    copy_mnt_ns() which clones unbindable mounts via CL_COPY_UNBINDABLE. So
    since v6.17 a mount namespace created via clone(CLONE_NEWNS) or
    unshare(CLONE_NEWNS) contain private and bindable copies of every
    unbindable mount. The following snippet:
    
      mount --make-unbindable /mnt
      unshare -m --propagation unchanged
      mount --bind /mnt /tmp/x
    
    succeeds. This used to fail with EINVAL. This also applies to
    recursively binding a tree that contains an unbindable the mount. Such
    subtrees used to be pruned when they were moved onto a shared mount.
    
    And Documentation/filesystems/sharedsubtree.rst still says that the copy
    of an unbindable mount is unbindable.
    
    So once again let's fix this. Copy T_UNBINDABLE in clone_mnt(). Let
    set_mnt_shared() mask it off whenever a mount is made shared.
    This restores what the old MNT_INTERNAL_FLAGS mask did.
    
    Link: https://patch.msgid.link/[email protected]
    Fixes: 406fea799925 ("mount: separate the flags accessed only under namespace_sem")
    Cc: [email protected] # v6.17+
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 23 14:27:55 2026 +0200

    mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount
    
    [ Upstream commit a2b42babc912e4fb428cbb42adb4f6e1e067113d ]
    
    do_set_group() only accepts mounts as targets that are neither shared
    nor a slave. That encompasses undindable mounts.
    
    If the source mount is a slave mount the target mount will end up with
    source's master as its master. It keeps T_UNBINDABLE. That means we get
    a mount that is both unbindable and a slave:
    
      mount --bind /tmp/src /tmp/src
      mount --make-shared /tmp/src
      mount --bind /tmp/src /tmp/b
      mount --make-slave /tmp/b
      mount --bind /tmp/src /tmp/c
      mount --make-unbindable /tmp/c
      move_mount(b, "", c, "", MOVE_MOUNT_SET_GROUP)
      grep /tmp/c /proc/self/mountinfo
      ... /tmp/c ... master:646 unbindable ...
    
    This property cannot be produced any other way. change_mnt_propagation()
    drops the master when it makes a mount unbindable (iow, it becomes
    private) and doesn't touch an unbindable mount when it is supposed to
    turned into a slave mount.
    
    End-result is that the unbindable-slave mount receives everything
    propagated from its master's peer group while it can't be bind mounted
    itself. Not sure what that's supposed to do.
    
    On the other side: if the source mount is shared, the target mount drops
    T_UNBINDABLE because because set_mnt_shared() clears T_SHARED_MASK.
    
    So teach do_set_group() to refuse an unbindable target mount the same
    way a shared or slave target mount is refused.
    
    The main user of MOVE_MOUNT_SET_GROUP is CRIU which restores sharing
    first and applies MS_UNBINDABLE afterwards. It never hits this.
    
    Link: https://patch.msgid.link/[email protected]
    Fixes: 9ffb14ef61ba ("move_mount: allow to add a mount into an existing group")
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
namei: don't reveal overmounted entries in refwalk [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:33 2026 +0200

    namei: don't reveal overmounted entries in refwalk
    
    commit 8189ab688f5a2c745dc90b63374da02f213d6994 upstream.
    
    In rcuwalk the dentry is validated before it is accepted. step_into()
    step_into() rechecks d_seq and __follow_mount_rcu() rechecks mount_lock.
    An entry that gets unlinked in between causes the lookup to retry and
    miss.
    
    A refwalk doesn't do this. lookup_fast() takes a reference on the hashed
    dentry and simply accepts it. So an unlink that happens after the
    reference was taken isn't seen by refwalk. That's fine for a simple
    file. We just happened to open it before it was unlinked, no problem.
    
    For a mountpoint and specifically a locked mountpoint it very much
    isn't. The unlink detaches all mounts and then removes the name. Any
    refwalk that hasn't traversed the mounts yet simply reveals the
    underlying entry. It's a very narrow window but it can be hit:
    
      reads of a covered file in 60 s, 3 walkers, ~15000 unlinks
        no widening            27
        that step + 200 us   3741
    
    See the appended patch for a more reliable reproducer.
    
    So check the entry after step_into(). unlink(), rmdir() and rename()
    mark the dentry with dont_mount() before they detach the mounts and
    remove the dentry.
    
    So a dentry that is marked with DCACHE_CANT_MOUNT and is unhashed by the
    time its mounts were looked at is a name that was unlinked under the
    refwalk. DCACHE_CANT_MOUNT is read after the mounts were looked up and
    it is set before they are detached by detach_mounts(). A refwalk that
    missed the mounts will see DCACHE_CANT_MOUNT.
    
    Plain d_unlinked() is fine. A rename takes the dentry off its hash chain
    but ___d_drop() leaves d_hash.pprev set. So only __d_drop() and a rename
    over the dentry unhash it. The only move that flips IS_ROOT splices in a
    disconnected alias. That doesn't have DCACHE_CANT_MOUNT set.
    
    Add the to step_into_slowpath(). ".." and LOOKUP_DOWN may legitimately
    land on an unhashed directory. A refwalk that crossed onto a mount has
    path.mnt different from nd->path.mnt. A dentry that a filesystem dropped
    on its own (d_invalidate(), d_drop()) doesn't have the flag set and is
    treated as before.
    
      // SPDX-License-Identifier: GPL-2.0
      /*
       * unlink_covered: unlink a file that is a mountpoint in a detached copy of
       * its mount, against walkers that open it through that copy.
       *
       * A is a tmpfs with the file f1 (content SECRET_F) and the plain file
       * MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
       * on A'/f1, held through an O_PATH fd on its root once the tree fd is
       * closed. Walkers open f1 through that fd while the driver unlinks A/f1,
       * where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
       * A read of SECRET_F is a hit: the name was found after its mount was
       * gone. The lockless walks use openat2(RESOLVE_CACHED).
       *
       * usage: unlink_covered [-t seconds] [-w walkers]
       */
      #ifndef _GNU_SOURCE
      #define _GNU_SOURCE
      #endif
      #include <errno.h>
      #include <fcntl.h>
      #include <pthread.h>
      #include <stdatomic.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/mount.h>
      #include <sys/stat.h>
      #include <sys/syscall.h>
      #include <linux/openat2.h>
    
      #ifndef __NR_open_tree
      #define __NR_open_tree 428
      #endif
      #ifndef __NR_move_mount
      #define __NR_move_mount 429
      #endif
      #ifndef __NR_openat2
      #define __NR_openat2 437
      #endif
      #ifndef OPEN_TREE_CLONE
      #define OPEN_TREE_CLONE 1
      #endif
      #ifndef OPEN_TREE_CLOEXEC
      #define OPEN_TREE_CLOEXEC O_CLOEXEC
      #endif
      #ifndef MOVE_MOUNT_F_EMPTY_PATH
      #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
      #endif
    
      #define WORK "/tmp/uc"
      #define ADIR WORK "/A"
    
      static int duration = 60, nwalkers = 3;
      static atomic_int stop, writer_waiting;
      static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER;
      static int cur_fd = -1;               /* the root of A', -1 while there is none */
      static atomic_long n_unlink, n_walk, n_mark, n_enoent, n_other, n_secret,
                       n_secret_cached;
    
      static void die(const char *what)
      {
            fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
            exit(2);
      }
    
      static void put_file(int dfd, const char *name, const char *content)
      {
            int fd = openat(dfd, name, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
                            0644);
    
            if (fd < 0 || write(fd, content, strlen(content)) < 0)
                    die(name);
            close(fd);
      }
    
      /* "plain/../" @n times, then f1: a longer walk that checks nothing on its way */
      static char *longpath(int n)
      {
            char *p = malloc(n * 9 + 3), *q = p;
    
            for (int i = 0; i < n; i++, q += 9)
                    memcpy(q, "plain/../", 9);
            strcpy(q, "f1");
            return p;
      }
    
      static void try_read(int dfd, const char *path, int cached)
      {
            struct open_how how = { .flags = O_RDONLY | O_CLOEXEC,
                                    .resolve = RESOLVE_CACHED };
            char buf[32] = "";
            long n;
            int fd;
    
            if (cached)
                    fd = syscall(__NR_openat2, dfd, path, &how, sizeof(how));
            else
                    fd = openat(dfd, path, O_RDONLY | O_CLOEXEC);
            atomic_fetch_add(&n_walk, 1);
            if (fd < 0) {
                    if (errno == ENOENT)
                            atomic_fetch_add(&n_enoent, 1);
                    else if (!cached || errno != EAGAIN)
                            atomic_fetch_add(&n_other, 1);
                    return;
            }
            n = read(fd, buf, sizeof(buf) - 1);
            close(fd);
            if (n >= 6 && !strncmp(buf, "SECRET", 6)) {
                    if (cached)
                            atomic_fetch_add(&n_secret_cached, 1);
                    if (!atomic_fetch_add(&n_secret, 1))
                            printf("HIT: read \"%s\" through %s (%s walk)\n", buf,
                                   path, cached ? "lockless" : "any");
            } else {
                    atomic_fetch_add(&n_mark, 1);
            }
      }
    
      static void *walker(void *arg)
      {
            unsigned int r = (long)arg * 2654435761u;
    
            while (!atomic_load(&stop)) {
                    char *p_long, *p_short;
                    int dfd;
    
                    while (atomic_load(&writer_waiting) && !atomic_load(&stop))
                            usleep(20);
                    pthread_rwlock_rdlock(&cur_lock);
                    dfd = cur_fd;
                    if (dfd < 0) {
                            pthread_rwlock_unlock(&cur_lock);
                            usleep(100);
                            continue;
                    }
                    r = r * 1103515245u + 12345u;
                    p_long = longpath(1 + (r >> 8) % 400);
                    p_short = longpath(0);
                    try_read(dfd, p_long, 0);
                    try_read(dfd, p_short, 0);
                    try_read(dfd, p_long, 1);
                    pthread_rwlock_unlock(&cur_lock);
                    free(p_long);
                    free(p_short);
            }
            return NULL;
      }
    
      /* hand the walkers a new A' (or none), close the old one */
      static void publish(int fd)
      {
            int old;
    
            atomic_fetch_add(&writer_waiting, 1);
            pthread_rwlock_wrlock(&cur_lock);
            old = cur_fd;
            cur_fd = fd;
            pthread_rwlock_unlock(&cur_lock);
            atomic_fetch_sub(&writer_waiting, 1);
            if (old >= 0)
                    close(old);
      }
    
      static void *driver(void *arg __attribute__((unused)))
      {
            int a;
    
            if (mkdir(ADIR, 0755) && errno != EEXIST)
                    die("mkdir A");
            if (mount("A", ADIR, "tmpfs", 0, "size=4M"))
                    die("mount A");
            a = open(ADIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
            if (a < 0 || mkdirat(a, "plain", 0755))
                    die("A/plain");
            put_file(a, "MARK_A", "MARK_A");
            while (!atomic_load(&stop)) {
                    int t, m, fd_a;
    
                    put_file(a, "f1", "SECRET_F");
                    t = syscall(__NR_open_tree, a, "",
                                OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
                    if (t < 0)
                            die("open_tree A");
                    m = syscall(__NR_open_tree, a, "MARK_A",
                                OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
                    if (m < 0)
                            die("open_tree MARK_A");
                    if (syscall(__NR_move_mount, m, "", t, "f1",
                                MOVE_MOUNT_F_EMPTY_PATH))
                            die("move_mount");
                    close(m);
                    fd_a = openat(t, ".", O_PATH | O_DIRECTORY | O_CLOEXEC);
                    if (fd_a < 0)
                            die("open A'");
                    publish(fd_a);
                    usleep(200 + rand() % 1000);
                    close(t);                       /* A' is unmounted, fd_a holds it */
                    usleep(200 + rand() % 1000);
                    if (unlinkat(a, "f1", 0))       /* through A, a plain file there */
                            die("unlink f1");
                    atomic_fetch_add(&n_unlink, 1);
                    usleep(rand() % 300);
                    publish(-1);
            }
            close(a);
            umount2(ADIR, MNT_DETACH);
            return NULL;
      }
    
      int main(int argc, char **argv)
      {
            pthread_t d, *w;
            int c, i;
    
            setvbuf(stdout, NULL, _IOLBF, 0);
            while ((c = getopt(argc, argv, "t:w:")) != -1) {
                    switch (c) {
                    case 't':
                            duration = atoi(optarg);
                            break;
                    case 'w':
                            nwalkers = atoi(optarg);
                            break;
                    default:
                            fprintf(stderr, "usage: unlink_covered [-t seconds] [-w walkers]\n");
                            return 2;
                    }
            }
            if (unshare(CLONE_NEWNS) ||
                mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
                    die("unshare");
            if (mkdir(WORK, 0755) && errno != EEXIST)
                    die("mkdir");
            w = calloc(nwalkers, sizeof(*w));
            for (i = 0; i < nwalkers; i++)
                    if (pthread_create(&w[i], NULL, walker, (void *)(long)i))
                            die("pthread_create");
            if (pthread_create(&d, NULL, driver, NULL))
                    die("pthread_create");
            sleep(duration);
            atomic_store(&stop, 1);
            pthread_join(d, NULL);
            for (i = 0; i < nwalkers; i++)
                    pthread_join(w[i], NULL);
            printf("unlink_covered: %d s, %d walkers: unlinks %ld walks %ld mark %ld enoent %ld other %ld SECRET %ld (lockless %ld)\n",
                   duration, nwalkers, atomic_load(&n_unlink), atomic_load(&n_walk),
                   atomic_load(&n_mark), atomic_load(&n_enoent),
                   atomic_load(&n_other), atomic_load(&n_secret),
                   atomic_load(&n_secret_cached));
            return atomic_load(&n_secret) ? 1 : 0;
      }
    
    #  diff --git a/fs/namei.c b/fs/namei.c
    #  --- a/fs/namei.c
    #  +++ b/fs/namei.c
    #  @@ -35,6 +35,7 @@
    #   #include <linux/fcntl.h>
    #   #include <linux/device_cgroup.h>
    #   #include <linux/fs_struct.h>
    #  +#include <linux/delay.h>
    #   #include <linux/posix_acl.h>
    #   #include <linux/hash.h>
    #   #include <linux/bitops.h>
    #  @@ -1205,9 +1206,26 @@ static int sysctl_protected_symlinks __read_mostly;
    #   static int sysctl_protected_hardlinks __read_mostly;
    #   static int sysctl_protected_fifos __read_mostly;
    #   static int sysctl_protected_regular __read_mostly;
    #  +/* debug: widen the two windows of the detach_mounts() race */
    #  +static int sysctl_detach_race_walk_us __read_mostly;
    #  +static int sysctl_detach_race_unlink_us __read_mostly;
    #
    #   #ifdef CONFIG_SYSCTL
    #   static const struct ctl_table namei_sysctls[] = {
    #  +    {
    #  +            .procname       = "detach_race_walk_us",
    #  +            .data           = &sysctl_detach_race_walk_us,
    #  +            .maxlen         = sizeof(int),
    #  +            .mode           = 0644,
    #  +            .proc_handler   = proc_dointvec,
    #  +    },
    #  +    {
    #  +            .procname       = "detach_race_unlink_us",
    #  +            .data           = &sysctl_detach_race_unlink_us,
    #  +            .maxlen         = sizeof(int),
    #  +            .mode           = 0644,
    #  +            .proc_handler   = proc_dointvec,
    #  +    },
    #       {
    #               .procname       = "protected_symlinks",
    #               .data           = &sysctl_protected_symlinks,
    #  @@ -1878,6 +1896,10 @@ static struct dentry *lookup_fast(struct nameidata *nd)
    #               dentry = __d_lookup(parent, &nd->last);
    #               if (unlikely(!dentry))
    #                       return NULL;
    #  +            /* debug: between finding a mountpoint and crossing its mounts */
    #  +            if (unlikely(sysctl_detach_race_walk_us) && d_mountpoint(dentry))
    #  +                    usleep_range(sysctl_detach_race_walk_us,
    #  +                                 sysctl_detach_race_walk_us + 10);
    #               status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
    #       }
    #       if (unlikely(status <= 0)) {
    #  @@ -5693,6 +5715,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
    #                       if (!error) {
    #                               dont_mount(dentry);
    #                               detach_mounts(dentry);
    #  +                            /* debug: the mounts are gone, d_delete() is still to come */
    #  +                            if (unlikely(sysctl_detach_race_unlink_us))
    #  +                                    usleep_range(sysctl_detach_race_unlink_us,
    #  +                                                 sysctl_detach_race_unlink_us + 10);
    #                       }
    #               }
    #       }
    
    Fixes: 8ed936b5671b ("vfs: Lazily remove mounts on unlinked files and directories.")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
namespace: check a recursive bind mount for mount namespace loops [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:31:56 2026 +0200

    namespace: check a recursive bind mount for mount namespace loops
    
    commit c640a01a78e42302879006ed7b7d5a9a943ba815 upstream.
    
    do_loopback() refuses to bind mount the file of a mount namespace that
    is as old as the caller's or older because a mount namespace that holds
    a mount of its own file, or of an ancestor's, would cause a cycle. But
    it only checks the dentry the bind mount starts from. With MS_REC
    everything below it is copied and do_loopback() passes
    CL_COPY_MNT_NS_FILE so mount namespace files below the source are
    copied.
    
    That's fine for a source in the caller's own mount namespace. Every
    mount namespace file in there passed the same check when it was
    bind-mounted. It isn't fine for a source in another mount namespace.
    may_copy_tree() accepts a bind mount of any nsfs or pidfs file no matter
    what mount namespace it lives in so that /proc/<pid>/ns/<ns> and pidfds
    can be bind mounted. If we create a bind-mount stack of mount namespaces
    file descriptors the kernel will copy them irrespective of their
    ancestoral relationship to the mount namespace in question:
    
      151 146 0:7 net:[4026531833] /tmp/nrc/y rw - nsfs nsfs rw
      152 151 0:7 mnt:[4026532293] /tmp/nrc/y rw - nsfs nsfs rw
    
    Mount 152 is a mount of the mount namespace file of mount namespace
    4026532293 inside mount namespace 4026532293. That namespace and every
    mount in it are leaked... All it takes is a process in an older mount
    namespace that stacks the file and repeating it leaks without limit:
    
      after control: Shmem:               380 kB
      child: mount(/proc/self/fd/6, MS_BIND|MS_REC): ok
      after cycle: Shmem:             65916 kB
    
    do_move_mount() runs check_for_nsfs_mounts() over a detached tree for
    exactly that reason. Do the same for the copy before it is grafted.
    
    Fixes: e149ed2b805f ("take the targets of /proc/*/ns/* symlinks to separate fs")
    Fixes: ef4144ac2dec ("pidfs: allow bind-mounts")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: check a submount for references right before unmounting it [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:31:54 2026 +0200

    namespace: check a submount for references right before unmounting it
    
    commit 32bf92416614a1e3ff3524fc6b780259c7aad3ef upstream.
    
    shrink_submounts() and mark_mounts_for_expiry() first collect all the
    mounts they are allowed to unmount and then unmount them.
    
    Whether a mount is busy is decided by propagate_mount_busy() on the
    tree. But unmounting the first mount changes the tree that the second
    one propagates into. propagate_umount()
    moves a surviving overmount off a copy it unmounts and mounts it where
    the copy was mounted. If that's where the propagated copy of the second
    victim is looked up the overmount becomes a candidate of the second
    umount_tree(). It's childless and so trim_one() commits it without
    looking at its reference count.
    
    So a synchronous umount pulls out a busy mount that is in use somewhere
    else and marks it MNT_SYNC_UMOUNT while it has users:
    
      umount2(/tmp/plshrink/p1, 0) = 0 errno 0
      cwd is (unreachable)
    
    The same two umounts requested one after the other fail with EBUSY.
    This needs a mount with MNT_SHRINKABLE, i.e., automounted submounts of
    NFS, AFS and CIFS or the tracefs mount below debugfs. Bind mounts
    inherit the flag.
    
    Check each mount right before it is unmounted under the same hold of
    namespace_sem and mount_lock as the umount itself. Make sure that the
    algorithm stays linear.
    
    Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: check the mounts before reading their parents in pivot_root() [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:02 2026 +0200

    namespace: check the mounts before reading their parents in pivot_root()
    
    commit 6b7c001eb5857fa09041f47673666060a2e5fc1c upstream.
    
    path_pivot_root() reads the parents of new_root and of the caller's root
    and checks whether they are shared before it checks that either mount is
    in the caller's mount namespace. Only namespace_sem is held. That's fine
    for a mount that is in the caller's mount namespace.
    
    But new_root can be a file descriptor to a mount that has been unmounted
    and that only the file descriptor keeps alive. If that mount stayed
    attached to its parent when it was unmounted nothing pins the parent for
    it. The final mntput() of the parent unhooks the children under
    mount_lock alone and frees the parent afterwards:
    
      pivot_root()                     close(fd), last ref on the parent
      ------------                     ---------------------------------
      ex_parent = new_mnt->mnt_parent
                                       mntput_no_expire_slowpath()
                                         __umount_mnt(new_mnt)
                                       cleanup_mnt()
                                         call_rcu()
      IS_MNT_SHARED(ex_parent)
    
      BUG: KASAN: slab-use-after-free in path_pivot_root+0xf1a/0x1840
      Read of size 4 at addr ffff8881047382f8 by task pivot_widen/157
       path_pivot_root+0xf1a/0x1840
       __x64_sys_pivot_root+0x165/0x190
    
    The same goes for the caller's root via chroot(). Both outcomes of the
    check end in EINVAL so nothing but the read itself goes wrong. It's the
    same thing commit bb4609405752 ("statmount: read the parent of an
    unmounted mount under mount_lock") fixed for statmount().
    
    Check that both mounts are in the caller's namespace before their
    parents are read. Every path returns EINVAL either way.
    
    Fixes: e0c9c0afd2fc ("mnt: Update detach_mounts to leave mounts connected")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: check the target before walking it in do_mount_setattr() [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:28 2026 +0200

    namespace: check the target before walking it in do_mount_setattr()
    
    commit 08f4288a37ef4b3d19b4a9599ec3048219cac828 upstream.
    
    When mount_setattr() changes the propagation type to MS_SHARED
    do_mount_setattr() takes namespace_sem and calls invent_group_ids()
    which walks the whole target tree with next_mnt() and allocates a peer
    group id for every mount that doesn't have one.
    
    Whether the caller may touch the target at all is only checked
    afterwards under mount_lock. If it may not, cleanup_group_ids() walks
    the tree a second time on the way out to free the ids again.
    
    A detached tree that a file descriptor keeps alive, a mount in another
    mount namespace or a mount below the root of an anonymous mount
    namespace does a bunch of allocation work that is completely useless
    because it will fail and revert right after.
    
    Do the right thing and check the target right after taking namespace_sem
    instead. A mount leaves its namespace only under namespace_sem so the
    mount stays stable. The check under mount_lock stays for the case where
    no propagation change is requested and namespace_sem isn't taken.
    Callers get the same EINVAL as before.
    
    Fixes: 2a1867219c7b ("fs: add mount_setattr()")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: don't copy an unmounted mount tree [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:27 2026 +0200

    namespace: don't copy an unmounted mount tree
    
    commit 8bacbf6be959973b28b691713a872c12eae69eec upstream.
    
    may_copy_tree() accepts a mount whose root is an nsfs or pidfs file
    before it checks whether that mount is mounted. This exception exists
    for nsfs and pidfs mounts. They are part of no mount namespace so
    neither check_mnt() nor is_mounted() would let them through and
    bind-mounting a nsfsfd or a pidfd wouldn't work.
    
    Problem is that exception also admits a bind mount of such a file when
    it was lazily unmounted and is only kept alive by a file descriptor:
    
      mount --bind /proc/self/ns/net /tmp/x
      exec 3< /tmp/x
      umount -l /tmp/x
      mount --rbind /proc/self/fd/3 /tmp/y
    
    With MS_REC or AT_RECURSIVE copy_tree() doesn't stop at the unmounted
    mount. It copies every mount that stayed attached to it as well. So if
    you have a bunch of overmounts over the nsfsfd or the pidfd the whole
    unmounted stack is copied. That's a bug.
    
    So refuse to walk an unmounted tree. Copying its root alone stays
    possible. So a bind mount of a namespace that is gone can still be
    recreated from a file descriptor on the old one. The file descriptor
    pins that mount and its root and __has_locked_children() only reads the
    direct children which don't leave the parent's list without
    namespace_sem. The internal mounts carry MNT_NS_INTERNAL instead of NULL
    and are still walked. Copying an unmounted tree recursively fails with
    EINVAL.
    
    Fixes: e149ed2b805f ("take the targets of /proc/*/ns/* symlinks to separate fs")
    Fixes: ef4144ac2dec ("pidfs: allow bind-mounts")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: don't inherit MNT_UMOUNT in clone_mnt() [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:26 2026 +0200

    namespace: don't inherit MNT_UMOUNT in clone_mnt()
    
    commit e2c6d326216642011da318b9edfd5d57ebd5a56f upstream.
    
    MNT_UMOUNT gets raised on a mount that umount_tree() or umount_one() has
    taken out of its namespace. It's never cleared. __detach_mounts()
    unhooks a mount that carries it instead of unmounting it.
    
    disconnect_mount() lets an unmounted child stay attached only if its
    parent carries it. propagate_umount() takes it as the sign that a mount
    is going to be unmounted when it decides what else can be unmounted,
    where a chain of locked mounts ends and where a for reparenting an
    overmount.
    
    clone_mnt() copies the flags of the source and only masks
    MNT_INTERNAL_FLAGS which doesn't include MNT_UMOUNT. A mount that was
    lazily unmounted but is kept alive by a file descriptor can still be
    copied when its root is an nsfs or pidfs file because may_copy_tree()
    accepts those before checking whether the source is mounted at all:
    
      mount --bind /proc/self/ns/net /tmp/x
      exec 3< /tmp/x
      umount -l /tmp/x
      mount --bind /proc/self/fd/3 /tmp/y
    
    The mount on /tmp/y is attached to the caller's namespace with
    MNT_UMOUNT already set and every copy of it inherits the flag again.
    
    That causes a number of bugs:
    
    - Unlink its mountpoint from a mount namespace where it isn't one.
      __detach_mounts() takes it for a mount that was unmounted earlier,
      unhooks it from its parent and drops the reference the namespace
      holds on it. It stays in the namespace with one reference too few
      and as its own parent, so it can't be unmounted through the file
      descriptor anymore and the namespace never finds it again. When the
      namespace goes away it's leaked and points to a freed struct
      mnt_namespace that may_change_propagation() and anon_ns_root() read
      on the next propagation change or mount_setattr() through the file
      descriptor.
    
    - Make it shared and unmount a peer. trace_transfers() follows the
      flag from the peer into it and strips it from its peer group.
    
    - Let a propagated umount reach it. gather_candidates() marks it with
      T_UMOUNT_CANDIDATE but never puts it on the candidate list, so the
      mark is never cleared and every later propagated umount skips it. If
      it's the parent of a locked mount handle_locked() takes it as the
      cutoff and commits the locked child that should have stayed and
      disconnect_mount() leaves that child attached to it, unmounted under
      a mounted parent, which is what disconnect_mount() exists to
      prevent. When the namespace goes away umount_tree() visits the child
      a second time. And once __detach_mounts() has made it its own parent
      reparent() never finds the end of the chain of unmounted parents.
    
    A clone is a new mount that has never been unmounted. Add MNT_UMOUNT
    to MNT_INTERNAL_FLAGS so clone_mnt() never copies it. And warn when
    umount_tree() reaches a mount that already has it set.
    
    Fixes: 590ce4bcbfb4 ("mnt: Add MNT_UMOUNT flag")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: don't let a pseudo dentry become the root of a mount [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:09 2026 +0200

    namespace: don't let a pseudo dentry become the root of a mount
    
    commit b138e16fb1e81376cea89f727dda7bfccd140de4 upstream.
    
    d_alloc_pseudo() hands out dentries for pipes, sockets and other files
    that are never anyone's child or parent. They carry DCACHE_NORCU and
    dentry_free() frees them right away because no lockless path walk can
    ever reach them. That holds as long as such a dentry isn't the root of
    a mount. But bind mounting /proc/self/fd/<fd> of such a file does
    exactly that.
    
    Most callers of alloc_file_pseudo() put their files on kernel-internal
    mounts and may_copy_tree() refuses those. bpf_token_create() doesn't. It
    places the token file on the bpffs mount the caller handed it and that
    mount is in the caller's mount namespace so the clone goes through:
    
      mount --bind /proc/self/fd/<token> <file>
      open_tree(tokfd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE) + move_mount()
    
    __follow_mount_rcu() then loads ->mnt_root of that mount, reads d_seq
    and d_flags of the dentry and only then checks mount_lock. The dentry
    can be gone by then. The final mntput() of an unmounted parent unhooks
    a child that stayed attached to it under mount_lock alone. When the
    child's holder does the final put right after that the root is dput()
    and freed immediately while a walker that found the mount hashed still
    looks at it.
    
    Refuse to clone a mount with a DCACHE_NORCU dentry as its root. Nothing
    sensible can be done with a bind mount of a bpf token anyway.
    
    Fixes: 35f96de04127 ("bpf: Introduce BPF token object")
    Cc: [email protected] # v6.9+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: don't reconfigure internal superblocks via remount and umount [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:03 2026 +0200

    namespace: don't reconfigure internal superblocks via remount and umount
    
    commit d791606bb915a8f27e36657696fd1d9a216c5c08 upstream.
    
    Commit 02587a4af82a ("fs: refuse fspick() on internal superblocks")
    blocked fspick() on SB_NOUSER superblocks. But that's not the only way
    to reconfigure_super(). mount(MS_REMOUNT) and umount() of the caller's
    root without MNT_DETACH. The root of an empty mount namespace is a
    nullfs mount and all mount namespaces share that superblock:
    
      nullfs: fspick: FAIL errno=22 (Invalid argument)
      nullfs: mount(MS_REMOUNT|MS_RDONLY): ok(0)
      nullfs after remount: statfs(/): magic=0x4e554c4c flags=0x21 RDONLY
      nullfs: umount2("/", 0): ok(0)
    
    Refuse both like fspick() does. Only root in the initial user namespace
    can do this and nullfs is empty and immutable so the flags don't buy
    anything. But they show up in statfs() for the root of every mount
    namespace on the host.
    
    Fixes: 9d4e752a24f7 ("namespace: allow creating empty mount namespaces")
    Cc: [email protected] # v7.1+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: handle mount locking for automounts correctly [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:37 2026 +0200

    namespace: handle mount locking for automounts correctly
    
    commit 33aadc7c72055fca93cb5a3691d836ebf8b31c9b upstream.
    
    If mounts are propagated across user namespaces, attach_recursive_mnt()
    locks every copy of the source mount to protect overmounts from
    vanishing and revealing the underlying files or directories.
    
    The user namespace is taken from the caller's mount namespaces since
    this is where the mounts end up. Except, that's not always true.
    Automounts may legitimately get popped in by tasks located in a
    different mount and user namespace during path lookup.
    
    Then check doesn't make sense at that point. The copy in the namespace
    of the parent - which may be the host's - is now locked and the host
    cannot change the flags of its own mounts anymore.
    
    Here's the reproducer:
    
    - host has debugfs mounted nosuid,nodev,noexec and shared
    - tracefs automount below it is not yet active
    - hand a child process a directory descriptor on that mount
    - child process enters auser and mount namespace
    - child process' namespace now holds a locked copy of the host's debugfs
      mount that receives propagation from it
    - child process stats "tracing/." through the descriptor
    - lookup runs on the host's mount so the automount lands below the host's mount
    - propagation puts a copy below the child's copy
    - both try to clear the flags on the mount they got, with a bind remount:
    
        host, on its own automount:            MS_REMOUNT|MS_BIND = EPERM
        child, on the copy in its namespace:   MS_REMOUNT|MS_BIND = 0
    
    So the lock landed on the host's mount instead of the child's copy.
    Congrats. So we need to compare with the owner of the namespace the
    mount actually gets mounted on. For all regular cases that is the
    caller's mount namespace and so nothing changes.
    
    Detached trees in anonymous mount namespaces by be handed over via
    SCM_RIGHTS or inherited in other ways on purpose so the attaching task's
    mount namespace is authoritative, not the creator of the detached tree.
    
    Fixes: 132c94e31b8b ("vfs: Carefully propogate mounts across user namespaces")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:31:58 2026 +0200

    namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE
    
    commit 0febe278ec45b1ccdbe9bd5ff1ba365d8fd55e2a upstream.
    
    open_tree(OPEN_TREE_NAMESPACE) creates a new mount namespace from a
    copy of the tree at the given path. The caller needs to be privileged
    over its current user namespace because the new mount namespace will be
    owned by it. It doesn't need to be privileged over the mount namespace
    the tree is copied from. An unprivileged user just needs to create a
    user namespace first.
    
    The copy follows the rules of a detached bind mount. Without
    AT_RECURSIVE only the mount itself is cloned and its children are left
    out. With AT_RECURSIVE unbindable mounts are skipped. Both is fine when
    the caller has privileges over the source mount namespace because it
    could unmount those mounts anyway. Not so for an unprivileged user in
    that mount namespace. For them a mount namespace copy is what unshare()
    does. copy_mnt_ns() copies everything including unbindable mounts and
    lock_mnt_tree() makes sure nothing can be unmounted in the copy. Nothing
    that was covered gets revealed.
    
    create_new_namespace() only does the locking and so the covered content
    is right there in the new mount namespace:
    
      # mount -t tmpfs none /tmp/otn; mkdir /tmp/otn/covered
      # echo hidden > /tmp/otn/covered/under.txt
      # mount -t tmpfs none /tmp/otn/covered
    
      uid 1000, after unshare(CLONE_NEWUSER):
      fd = open_tree(AT_FDCWD, "/tmp/otn", OPEN_TREE_NAMESPACE);
      setns(fd, CLONE_NEWNS);
      open("/covered/under.txt", O_RDONLY)  -> "hidden"
    
    Covering paths with mounts is how container runtimes mask parts of
    /proc and /sys and how admins hide things.
    
    When the caller's user namespace doesn't own the source mount namespace
    copy the way unshare() does and refuse a non-recursive copy of a mount
    that has anything mounted below the requested directory and copy
    unbindable mounts in a recursive copy. A caller that is privileged over
    the source mount namespace sees no change.
    
    Fixes: 9b8a0ba68246 ("mount: add OPEN_TREE_NAMESPACE")
    Cc: [email protected] # v7.0+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: keep the lock on a mount that a propagated copy is moved beneath [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:40 2026 +0200

    namespace: keep the lock on a mount that a propagated copy is moved beneath
    
    commit d74d66aa708ccf2bc0b1e265a83fed0f2308d5c4 upstream.
    
    attach_recursive_mnt() transfers MNT_LOCKED from the top mount to the
    mount that is moved beneath it with MOVE_MOUNT_BENEATH. This allows the
    owner of a user namespace to replace its locked /proc or its root. The
    mount beneath takes on the job of covering the underlying mountpoint
    allowing the top mount to be unmounted.
    
    Consider two mount namespaces:
    
    (H) The host H has a shared mount P with a secret in P/d
    (Z) Z is a user namespace made from M. Its copy of P receives
        propagation from the host's P and its copy of M's cover on P/d is
        locked Z's owner must not get to see P/d.
    
    Now (H) mounts X on P/d. This propagates into (Z). The copy of X lands
    beneath (Z)'s locked cover. The locked property is transfered from (Z)'s
    cover to the copy of X propagated beneath it. The cover is now unlocked.
    
    Now (H) unmounts X again. The copy of X in (Z) gets unmounted and the
    covering mount is left unlocked on top of P/d. (Z) can now unmount it:
    
        Z: umount2(P/d)             = EINVAL            /* the cover is locked */
        H: mount X on P/d, umount X                     /* both propagate into Z /*
        Z: umount2(P/d)             = 0                 /* the cover is now unlocked */
        Z: read P/d/secret          = "covered-by-root" /* secret revealed */
    
    So only transfer the locked property to the mount beneath for mounts the
    caller has placed. A propagated copy that lands beneath a locked mount
    is locked as well so that the mount at the bottom of the stack carries a
    lock the way every check expects. The mount on top of it remains locked
    to ensure that it keeps covering even if the propagated mount is
    unmounted again.
    
    Fixes: c62a4766937e ("move_mount: transfer MNT_LOCKED")
    Cc: [email protected] # v7.1+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: look at the topmost mount for a mount namespace file [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:00 2026 +0200

    namespace: look at the topmost mount for a mount namespace file
    
    commit 8714b44adac7b10506e1db3ef1710689751f0f10 upstream.
    
    attach_recursive_mnt() preallocates a mountpoint for the root of the
    topmost mount of the source so that a mount that already sits at the
    destination can be put on top of the source or on top of one of its
    propagated copies.
    
    The copies are made without CL_COPY_MNT_NS_FILE so their chain of
    overmounts is shorter than the source's. It ends below the first bind
    mount of a mount namespace file. So while the loop walks up the chain of
    the source it remembers the mountpoint of that mount in "shorter" and
    the existing mount is put there for the copies.
    
    But the loop ends at the topmost mount without ever looking at it. If
    the topmost mount is the only mount namespace file in the chain
    "shorter" stays NULL and mnt_change_mountpoint() attaches the existing
    mount of the copy below the root of the mount namespace file. That's a
    dentry of nsfs. No path walk in the copy's mount namespace ever gets
    there. The mount is gone until its parent goes and the copy that took
    its place can't be unmounted synchronously because it has a child:
    
      S      bind mount of a file
      N      bind mount of a mount namespace file on top of S
      A      shared mount, B a slave of A, Q mounted on B/file
    
      move_mount(S, A/file)
      cat B/file          -> the content of S instead of Q
      umount B/file       -> EBUSY
    
    Look at every mount of the chain including the topmost one.
    
    Fixes: 96f5d2e05165 ("attach_recursive_mnt(): unify the mnt_change_mountpoint() logics")
    Cc: [email protected] # v6.17+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: never expire a locked mount [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:39 2026 +0200

    namespace: never expire a locked mount
    
    commit f78ddcc872248c7aa1d7e904928441a0be4c6d5d upstream.
    
    Locked mounts are special. They protect the underlying files and
    directories from being revealed. do_umount() refuses to unmount locked
    mounts but shrink_submounts() doesn't.
    
    A shrinkable mount can become locked once the owner of a user namespace
    puts it beneath a locked mount with MOVE_MOUNT_BENEATH. The locked
    property now moves to the mount at the bottom making it possible to
    unmount the top mount.
    
    So umount() of an unlocked ancestor now expires the bottom mount first
    and the covered directory is revealed:
    
      move_mount(c -> x/hidden, MOVE_MOUNT_BENEATH) = 0
      the cover after the lock moved:  umount2(x/hidden) = 0
      the holder of the lock:          umount2(x/hidden) = EINVAL
      the root of the copy, busy:      umount2(x) = EBUSY
      reads x/hidden/secret: "covered-by-root"
    
    So leave a locked mount alone as it dies together with its parent. A
    plain umount() of an unlocked mount with a locked one below it is EBUSY
    from now on. It's the same for any other locked child. A lazy umount
    still takes the whole tree.
    
    mark_mounts_for_expiry() never sees a locked mount. lock_mnt_tree()
    leaves a mount on an expiry list alone and nothing else puts a locked
    one on such a list. Add an assert for this.
    
    Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
    Fixes: c62a4766937e ("move_mount: transfer MNT_LOCKED")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: queue a mount only once for mount notifications [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:31:53 2026 +0200

    namespace: queue a mount only once for mount notifications
    
    commit bd2feb7796b6585938a4241e7b7c4148a6f7b762 upstream.
    
    mnt_notify_add() puts a mount on notify_list. It doesn't check whether
    the mount is on the list already. That's fine as long as every mount is
    queued at most once per namespace_sem hold. It isn't.
    
    propagate_umount() moves a surviving overmount off a stack of mounts
    that are going away and queues it as moved. shrink_submounts() and
    mark_mounts_for_expiry() call umount_tree() for several mounts under a
    single namespace_sem hold. So the second umount_tree() can take down
    exactly the mount the first one reparented, reparent it once more and so
    end up queueing it a second time.
    
    The second list_add_tail() cuts the mounts queued in between out of the
    list while the head still points at the last of them. notify_mnt_list()
    then only visits that one mount and the others are freed after the grace
    period with notify_list still pointing at them. Every later mount
    operation on the host walks freed memory:
    
      BUG: KASAN: slab-use-after-free in __list_add_valid_or_report
      Read of size 8 at addr ffff8881003d57e0 by task notify_dq/162
       __list_add_valid_or_report+0x15c/0x1a0
       mnt_add_to_ns+0x322/0x890
       attach_recursive_mnt.isra.0+0xf2a/0x1a00
       path_mount+0x139c/0x1d40
    
    This needs a mount with MNT_SHRINKABLE to bind from. That's what
    finish_automount() creates (submounts of NFS, AFS and CIFS and the
    tracefs mount below debugfs). Bind mounts inherit the flag. A mount
    namespace with a FAN_MARK_MNTNS mark does the rest and root in a user
    namespace can have both.
    
    Initialize to_notify in alloc_vfsmnt() and leave a mount alone that is
    queued already. mnt_notify() looks at the state the mount has when the
    list is drained so a single entry per mount is enough. The move event
    for a mount that is unmounted under the same hold is lost. That's fine.
    The detach is what matters.
    
    Fixes: bf630c401641 ("vfs: add notifications for mount attach and detach")
    Cc: [email protected] # v6.15+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: refuse an automount below a mount that is in no namespace [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:36 2026 +0200

    namespace: refuse an automount below a mount that is in no namespace
    
    commit ba985ce08471c555af2a2fbe217c1bc2e72a6d8c upstream.
    
    It's possible to add autmounts even when the parent mount isn't in the
    mount namespace of the caller. The only requirement we have is that the
    parent mount namespace must not be NULL, i.e., unmounted.
    
    Problem is that clone_private_mount() has MNT_NS_INTERNAL which makes
    that trivially true. So that passes the test and attach_recursive_mnt()
    accepts that as a mount point and funny enough, count_mounts()
    dereferences MNT_NS_INTERNAL. The problem is it is an error pointer...
    
    So we can reach this in userspace via fanotify. A filesystem mark on the
    lower filesystem of an overlay reports paths on the layer clone and
    reading the event hands out a descriptor on it. For example with debugfs
    as the lower layer it goes kaboom:
    
      openat(evfd, "tracing", O_DIRECTORY)
    
      Oops: general protection fault
      KASAN: null-ptr-deref in range [0x1d0-0x1d7]
      RIP: 0010:count_mounts+0x35/0x200
       attach_recursive_mnt
       finish_automount
    
    And since that sleeping beauty happens under namespace_sem held for
    writing every mount operation on the system blocks from then on.
    Congrats.
    
    Use is_mounted() instead which rejects unmounted and internal mounts
    alike. The open fails with EINVAL just as it did before
    clone_private_mount() used MNT_NS_INTERNAL.
    
    Fixes: df820f8de4e4 ("ovl: make private mounts longterm")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: remove the fsnotify marks of a mount namespace in process context [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:05 2026 +0200

    namespace: remove the fsnotify marks of a mount namespace in process context
    
    commit 1a116222acdcc1bc1a8350727ae6f28907d44594 upstream.
    
    mnt_ns_release() drops the last passive reference of a mount namespace
    and removes its fanotify marks via fsnotify_mntns_delete(). That takes
    the mutex of every group with a mark on the namespace and the spinlock
    of the connector. Fine from process context. But mnt_ns_tree_remove()
    hands the reference the namespace was allocated with to call_rcu() and
    so the marks are removed from the RCU softirq:
    
      BUG: sleeping function called from invalid context at kernel/locking/mutex.c:623
      in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/3
       __mutex_lock+0x113/0x24b0
       fsnotify_destroy_marks+0x11b/0x3d0
       mnt_ns_release_rcu+0x57/0xa0
       rcu_core+0x6b6/0x1e40
    
    and lockdep complains about the connector lock being taken from softirq
    context. A fanotify group with a FAN_MARK_MNTNS mark on the mount
    namespace of another task is all that's needed. Root in a user
    namespace can do that for a mount namespace it owns. The task exits and
    the namespace is freed with the mark still on it.
    
    Remove the marks in free_mnt_ns() before the namespace is handed to RCU.
    That runs in process context once the last active reference is gone. A
    mark is added through a file descriptor to the namespace which holds an
    active reference so no mark can show up after that.
    
    Fixes: bf630c401641 ("vfs: add notifications for mount attach and detach")
    Cc: [email protected] # v6.15+
    Link: https://patch.msgid.link/[email protected]
    Reviewed-by: Amir Goldstein <[email protected]>
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: reset the old parent's ->overmount in mnt_change_mountpoint() [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:24 2026 +0200

    namespace: reset the old parent's ->overmount in mnt_change_mountpoint()
    
    commit 476ef286a7a5db8bda51325dc0c45887b4d99d9a upstream.
    
    __umount_mnt() resets ->overmount of the parent when it unmounts the
    mount that overmounts it. mnt_change_mountpoint() doesn't. It moves the
    mount to its new parent and leaves the old one pointing at it.
    
    For a mount that is moved beneath in attach_recursive_mnt() that doesn't
    matter. The new mount has already reset ->overmount of the old parent by
    the time the old top mount is moved onto it.
    
    It matters for reparent() though. propagate_umount() moves a surviving
    overmount onto the first ancestor that isn't going to be unmounted. The
    mount it was taken from is unmounted immediately afterwards. If a file
    descriptor keeps that unmounted mount alive ->overmount points at the
    moved mount. That's a dangling pointer and UAF as the moved mount is
    unmounted and freed.
    
    do_lock_mount() follows ->overmount from the target path under
    mount_lock. With a file descriptor on such a mount as the target of a
    mount beneath topmost_overmount() walks into the freed mount and
    do_lock_mount() takes references on whatever it finds there.
    
    So reset ->overmount of the old parent in mnt_change_mountpoint() the
    same way __umount_mnt() does. A mount's ->overmount is then always a
    mount that is attached to it.
    
    Fixes: ffdc52fbbd58 ("prevent mount hash conflicts")
    Cc: [email protected] # v6.17+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

namespace: unhash a dentry before detaching the mounts on it [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:32 2026 +0200

    namespace: unhash a dentry before detaching the mounts on it
    
    commit 528b383dc35d1e5caf64ddf5d35f983ae543b0d0 upstream.
    
    unlink(), rmdir() and rename() remove the entry from the filesystem,
    call detach_mounts() on the entry with the inode locked and then call
    d_delete() once the inode is unlocked.
    
    The thing is that between detach_mounts() and d_delete() the dentry is
    still hashed and positive. But after detach_mounts() nothing covers the
    dentry anymore. A lookup that finds this dentry in the dcache can
    uncover what the mounts hid.
    
    That's a problem when unlinking files or directories that are
    mountpoints in other mount namespaces. Everybody who had the underlying
    entry covered can race the detach_mount() call until d_delete() has run.
    
    The race window isn't all that small. It encompasses namespace_unlock()
    with a full synchronize_rcu_expedited() grace period and the
    inode_unlock() of the entry.
    
    In my experiments three walkers that kept trying read an overmounted
    file in 11938 of the 16140 unlinks that removed its mountpoint from a
    bind mount of the filesystem within a minute.
    
    Fun fact, d_invalidate() has the same ordering problem but gets it
    right. It unhashes the dentry first and detaches the mounts afterwards.
    Let's do the same in __detach_mounts():
    
    - A lookup that hasn't found the dentry yet misses it in the dcache and
      waits for the directory lock that the caller holds until the name is
      gone for good.
    
    - A lockless lookup that found it already fails the mount_lock check
      while the dentry still counts as a mountpoint and the d_seq check once
      it doesn't, and retries.
    
    This fixes the lockless path. We still need to fix the reference count
    lookup in a follow-up patch.
    
    So d_drop() the dentry. The dentry stays positive and held but can't be
    found anymore. Then proceed with the detach and unlink.
    
    Reproducer:
    
    The reads were counted with the program below, three walkers for 60 s
    in a VM with 4 CPUs. The race window is stretched with the debug patch
    pasted here. fs.detach_race_walk_us sleeps in lookup_fast() once it
    found a mountpoint dentry and before its mounts are crossed.
    fs.detach_race_unlink_us sleeps in vfs_unlink() between detach_mounts()
    and d_delete().
    
      // SPDX-License-Identifier: GPL-2.0
      /*
       * unlink_covered: unlink a file that is a mountpoint in a detached copy of
       * its mount, against lookups that open it through that copy.
       *
       * A is a tmpfs with the file f1 (content SECRET_F) and the plain file
       * MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
       * on A'/f1, held through an O_PATH fd on its root once the tree fd is
       * closed. Walkers open f1 through that fd while the driver unlinks A/f1,
       * where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
       * A read of SECRET_F is a hit: the name was found after its mount was
       * gone. The lockless walks use openat2(RESOLVE_CACHED).
       *
       * usage: unlink_covered [-t seconds] [-w walkers]
       */
      #ifndef _GNU_SOURCE
      #define _GNU_SOURCE
      #endif
      #include <errno.h>
      #include <fcntl.h>
      #include <pthread.h>
      #include <stdatomic.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/mount.h>
      #include <sys/stat.h>
      #include <sys/syscall.h>
      #include <linux/openat2.h>
    
      #ifndef __NR_open_tree
      #define __NR_open_tree 428
      #endif
      #ifndef __NR_move_mount
      #define __NR_move_mount 429
      #endif
      #ifndef __NR_openat2
      #define __NR_openat2 437
      #endif
      #ifndef OPEN_TREE_CLONE
      #define OPEN_TREE_CLONE 1
      #endif
      #ifndef OPEN_TREE_CLOEXEC
      #define OPEN_TREE_CLOEXEC O_CLOEXEC
      #endif
      #ifndef MOVE_MOUNT_F_EMPTY_PATH
      #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
      #endif
    
      #define WORK "/tmp/uc"
      #define ADIR WORK "/A"
    
      static int duration = 60, nwalkers = 3;
      static atomic_int stop, writer_waiting;
      static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER;
      static int cur_fd = -1;               /* the root of A', -1 while there is none */
      static atomic_long n_unlink, n_walk, n_mark, n_enoent, n_other, n_secret,
                       n_secret_cached;
    
      static void die(const char *what)
      {
            fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
            exit(2);
      }
    
      static void put_file(int dfd, const char *name, const char *content)
      {
            int fd = openat(dfd, name, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
                            0644);
    
            if (fd < 0 || write(fd, content, strlen(content)) < 0)
                    die(name);
            close(fd);
      }
    
      /* "plain/../" @n times, then f1: a longer walk that checks nothing on its way */
      static char *longpath(int n)
      {
            char *p = malloc(n * 9 + 3), *q = p;
    
            for (int i = 0; i < n; i++, q += 9)
                    memcpy(q, "plain/../", 9);
            strcpy(q, "f1");
            return p;
      }
    
      static void try_read(int dfd, const char *path, int cached)
      {
            struct open_how how = { .flags = O_RDONLY | O_CLOEXEC,
                                    .resolve = RESOLVE_CACHED };
            char buf[32] = "";
            long n;
            int fd;
    
            if (cached)
                    fd = syscall(__NR_openat2, dfd, path, &how, sizeof(how));
            else
                    fd = openat(dfd, path, O_RDONLY | O_CLOEXEC);
            atomic_fetch_add(&n_walk, 1);
            if (fd < 0) {
                    if (errno == ENOENT)
                            atomic_fetch_add(&n_enoent, 1);
                    else if (!cached || errno != EAGAIN)
                            atomic_fetch_add(&n_other, 1);
                    return;
            }
            n = read(fd, buf, sizeof(buf) - 1);
            close(fd);
            if (n >= 6 && !strncmp(buf, "SECRET", 6)) {
                    if (cached)
                            atomic_fetch_add(&n_secret_cached, 1);
                    if (!atomic_fetch_add(&n_secret, 1))
                            printf("HIT: read \"%s\" through %s (%s walk)\n", buf,
                                   path, cached ? "lockless" : "any");
            } else {
                    atomic_fetch_add(&n_mark, 1);
            }
      }
    
      static void *walker(void *arg)
      {
            unsigned int r = (long)arg * 2654435761u;
    
            while (!atomic_load(&stop)) {
                    char *p_long, *p_short;
                    int dfd;
    
                    while (atomic_load(&writer_waiting) && !atomic_load(&stop))
                            usleep(20);
                    pthread_rwlock_rdlock(&cur_lock);
                    dfd = cur_fd;
                    if (dfd < 0) {
                            pthread_rwlock_unlock(&cur_lock);
                            usleep(100);
                            continue;
                    }
                    r = r * 1103515245u + 12345u;
                    p_long = longpath(1 + (r >> 8) % 400);
                    p_short = longpath(0);
                    try_read(dfd, p_long, 0);
                    try_read(dfd, p_short, 0);
                    try_read(dfd, p_long, 1);
                    pthread_rwlock_unlock(&cur_lock);
                    free(p_long);
                    free(p_short);
            }
            return NULL;
      }
    
      /* hand the walkers a new A' (or none), close the old one */
      static void publish(int fd)
      {
            int old;
    
            atomic_fetch_add(&writer_waiting, 1);
            pthread_rwlock_wrlock(&cur_lock);
            old = cur_fd;
            cur_fd = fd;
            pthread_rwlock_unlock(&cur_lock);
            atomic_fetch_sub(&writer_waiting, 1);
            if (old >= 0)
                    close(old);
      }
    
      static void *driver(void *arg __attribute__((unused)))
      {
            int a;
    
            if (mkdir(ADIR, 0755) && errno != EEXIST)
                    die("mkdir A");
            if (mount("A", ADIR, "tmpfs", 0, "size=4M"))
                    die("mount A");
            a = open(ADIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
            if (a < 0 || mkdirat(a, "plain", 0755))
                    die("A/plain");
            put_file(a, "MARK_A", "MARK_A");
            while (!atomic_load(&stop)) {
                    int t, m, fd_a;
    
                    put_file(a, "f1", "SECRET_F");
                    t = syscall(__NR_open_tree, a, "",
                                OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
                    if (t < 0)
                            die("open_tree A");
                    m = syscall(__NR_open_tree, a, "MARK_A",
                                OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
                    if (m < 0)
                            die("open_tree MARK_A");
                    if (syscall(__NR_move_mount, m, "", t, "f1",
                                MOVE_MOUNT_F_EMPTY_PATH))
                            die("move_mount");
                    close(m);
                    fd_a = openat(t, ".", O_PATH | O_DIRECTORY | O_CLOEXEC);
                    if (fd_a < 0)
                            die("open A'");
                    publish(fd_a);
                    usleep(200 + rand() % 1000);
                    close(t);                       /* A' is unmounted, fd_a holds it */
                    usleep(200 + rand() % 1000);
                    if (unlinkat(a, "f1", 0))       /* through A, a plain file there */
                            die("unlink f1");
                    atomic_fetch_add(&n_unlink, 1);
                    usleep(rand() % 300);
                    publish(-1);
            }
            close(a);
            umount2(ADIR, MNT_DETACH);
            return NULL;
      }
    
      int main(int argc, char **argv)
      {
            pthread_t d, *w;
            int c, i;
    
            setvbuf(stdout, NULL, _IOLBF, 0);
            while ((c = getopt(argc, argv, "t:w:")) != -1) {
                    switch (c) {
                    case 't':
                            duration = atoi(optarg);
                            break;
                    case 'w':
                            nwalkers = atoi(optarg);
                            break;
                    default:
                            fprintf(stderr, "usage: unlink_covered [-t seconds] [-w walkers]\n");
                            return 2;
                    }
            }
            if (unshare(CLONE_NEWNS) ||
                mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
                    die("unshare");
            if (mkdir(WORK, 0755) && errno != EEXIST)
                    die("mkdir");
            w = calloc(nwalkers, sizeof(*w));
            for (i = 0; i < nwalkers; i++)
                    if (pthread_create(&w[i], NULL, walker, (void *)(long)i))
                            die("pthread_create");
            if (pthread_create(&d, NULL, driver, NULL))
                    die("pthread_create");
            sleep(duration);
            atomic_store(&stop, 1);
            pthread_join(d, NULL);
            for (i = 0; i < nwalkers; i++)
                    pthread_join(w[i], NULL);
            printf("unlink_covered: %d s, %d walkers: unlinks %ld walks %ld mark %ld enoent %ld other %ld SECRET %ld (lockless %ld)\n",
                   duration, nwalkers, atomic_load(&n_unlink), atomic_load(&n_walk),
                   atomic_load(&n_mark), atomic_load(&n_enoent),
                   atomic_load(&n_other), atomic_load(&n_secret),
                   atomic_load(&n_secret_cached));
            return atomic_load(&n_secret) ? 1 : 0;
      }
    
    #  diff --git a/fs/namei.c b/fs/namei.c
    #  --- a/fs/namei.c
    #  +++ b/fs/namei.c
    #  @@ -35,6 +35,7 @@
    #   #include <linux/fcntl.h>
    #   #include <linux/device_cgroup.h>
    #   #include <linux/fs_struct.h>
    #  +#include <linux/delay.h>
    #   #include <linux/posix_acl.h>
    #   #include <linux/hash.h>
    #   #include <linux/bitops.h>
    #  @@ -1205,9 +1206,26 @@ static int sysctl_protected_symlinks __read_mostly;
    #   static int sysctl_protected_hardlinks __read_mostly;
    #   static int sysctl_protected_fifos __read_mostly;
    #   static int sysctl_protected_regular __read_mostly;
    #  +/* debug: widen the two windows of the detach_mounts() race */
    #  +static int sysctl_detach_race_walk_us __read_mostly;
    #  +static int sysctl_detach_race_unlink_us __read_mostly;
    #
    #   #ifdef CONFIG_SYSCTL
    #   static const struct ctl_table namei_sysctls[] = {
    #  +    {
    #  +            .procname       = "detach_race_walk_us",
    #  +            .data           = &sysctl_detach_race_walk_us,
    #  +            .maxlen         = sizeof(int),
    #  +            .mode           = 0644,
    #  +            .proc_handler   = proc_dointvec,
    #  +    },
    #  +    {
    #  +            .procname       = "detach_race_unlink_us",
    #  +            .data           = &sysctl_detach_race_unlink_us,
    #  +            .maxlen         = sizeof(int),
    #  +            .mode           = 0644,
    #  +            .proc_handler   = proc_dointvec,
    #  +    },
    #       {
    #               .procname       = "protected_symlinks",
    #               .data           = &sysctl_protected_symlinks,
    #  @@ -1878,6 +1896,10 @@ static struct dentry *lookup_fast(struct nameidata *nd)
    #               dentry = __d_lookup(parent, &nd->last);
    #               if (unlikely(!dentry))
    #                       return NULL;
    #  +            /* debug: between finding a mountpoint and crossing its mounts */
    #  +            if (unlikely(sysctl_detach_race_walk_us) && d_mountpoint(dentry))
    #  +                    usleep_range(sysctl_detach_race_walk_us,
    #  +                                 sysctl_detach_race_walk_us + 10);
    #               status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
    #       }
    #       if (unlikely(status <= 0)) {
    #  @@ -5693,6 +5715,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
    #                       if (!error) {
    #                               dont_mount(dentry);
    #                               detach_mounts(dentry);
    #  +                            /* debug: the mounts are gone, d_delete() is still to come */
    #  +                            if (unlikely(sysctl_detach_race_unlink_us))
    #  +                                    usleep_range(sysctl_detach_race_unlink_us,
    #  +                                                 sysctl_detach_race_unlink_us + 10);
    #                       }
    #               }
    #       }
    
    Fixes: 8ed936b5671b ("vfs: Lazily remove mounts on unlinked files and directories.")
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
net/mlx5: Lag, split aggregate speed into oper and max helpers [+ + +]
Author: Or Har-Toov <[email protected]>
Date:   Wed Sep 30 20:04:06 2026 +0300

    net/mlx5: Lag, split aggregate speed into oper and max helpers
    
    [ Upstream commit fe4114221364899ab33c3f9574da6b108d3fa79e ]
    
    mlx5_lag_sum_devices_speed computes the LAG aggregate by summing oper
    speeds across all ports. This has two bugs.
    
    First, it relies on the assumption that a port whose carrier is down
    will report an oper speed of zero and therefore not contribute to the
    sum. This assumption does not always hold: when the link partner
    disconnects the port transitions to DOWN state but firmware may still
    report a non-zero oper speed, causing the aggregate to include a port
    that is not actively carrying traffic.
    
    Second, in active-backup mode only one port transmits at a time, so
    the aggregate should reflect a single port speed rather than the sum
    of all ports.
    
    Fix this by splitting mlx5_lag_sum_devices_speed into two helpers.
    mlx5_lag_get_devices_oper_speed reflects the speed currently available:
    it queries the vport state of each port and skips any port that is not
    UP, rather than relying on oper speed being zero.
    mlx5_lag_get_devices_max_speed is state-independent and returns the
    maximum achievable speed used as a fallback when speed is 0; for
    active-backup it takes the maximum single-port speed instead of the sum.
    
    The bugs were discovered during integration and reproduced on a
    back-to-back ConnectX-8 setup.
    
    The first bug (stale oper speed when link goes down) was observed: after
    the link partner disconnected, the aggregate TX speed reported to vports
    remained full speed because firmware still returned the last oper speed,
    causing vports to be rate-limited to the old aggregate speed.
    
    The second bug (active-backup summing all port speeds instead of the
    active port's speed) was also triggered: in active-backup mode the
    computed aggregate was double the expected value since both port speeds
    were summed even though only one port was active.
    
    Fixes: 28ea6036dad2 ("net/mlx5: Handle port and vport speed change events in MPESW")
    Signed-off-by: Or Har-Toov <[email protected]>
    Reviewed-by: Shay Drori <[email protected]>
    Reviewed-by: Mark Bloch <[email protected]>
    Signed-off-by: Tariq Toukan <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
net/mlx5e: Order ICOSQ cc update after CQ doorbell [+ + +]
Author: Li RongQing <[email protected]>
Date:   Tue Oct 6 13:58:20 2026 +0300

    net/mlx5e: Order ICOSQ cc update after CQ doorbell
    
    [ Upstream commit b056ca4d3742d0769f91137bb1ce3215428398f7 ]
    
    mlx5e_poll_ico_cq() requires sq->cc to be updated only after
    mlx5_cqwq_update_db_record(), otherwise a CQ overrun may occur.
    
    The current implementation updates sq->cc before the CQ doorbell
    record, violating this ordering requirement.
    
    Update the CQ doorbell record first and use dma_wmb() before updating
    sq->cc. This ensures that the CQ space is released to the device
    before the corresponding ICOSQ consumer index is updated by software.
    
    Fixes: fd9b4be8002c ("net/mlx5e: RX, Support multiple outstanding UMR posts")
    Signed-off-by: Li RongQing <[email protected]>
    Reviewed-by: Dragos Tatulea <[email protected]>
    Signed-off-by: Tariq Toukan <[email protected]>
    Reviewed-by: Daniel Machon <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net/mlx5e: Prevent stale XSK buffer release on MPWQE refill retry [+ + +]
Author: Jerome Tollet <[email protected]>
Date:   Mon Aug 24 16:16:45 2026 +0200

    net/mlx5e: Prevent stale XSK buffer release on MPWQE refill retry
    
    [ Upstream commit 63811edf512584c946e5e96b100e9e280703bbb5 ]
    
    With AF_XDP on a striding RQ, mlx5e defers releasing XSK buffers until
    an MPWQE is refilled. If XSK allocation then returns -ENOMEM,
    actual_wq_head is not advanced and a later NAPI poll retries the same
    WQE.
    
    mlx5e_free_rx_mpwqe() leaves each released slot marked as releasable. On
    retry it can therefore call xsk_buff_free() again through stale pointers
    after the frames have returned to the XSK pool and been reallocated.
    
    Set all skip_release_bitmap bits in the common error path of
    mlx5e_xsk_alloc_rx_mpwqe(). This matches mlx5e_alloc_rx_mpwqe(). A
    successful allocation already clears the bitmap after replacing every
    buffer, so retries become idempotent without changing the success path.
    
    Fault injection forced three consecutive failures for one selected MPWQE.
    Both an early allocation failure and a partial 8-of-16-buffer unwind
    released the original 16 XSK buffers only once. Each error left a full
    bitmap, the following NAPI retry skipped the release, and a later
    successful allocation cleared it. A 20-second AF_XDP zero-copy pressure
    run exercised 1,575,262 buffer allocation failures without invalid
    descriptors, WQE errors, or kernel warnings.
    
    Fixes: 4c2a13236807 ("net/mlx5e: RX, Defer page release in striding rq for better recycling")
    Cc: [email protected]
    Signed-off-by: Jerome Tollet <[email protected]>
    Reviewed-by: Dragos Tatulea <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net/mlx5e: Prevent stale XSK buffer release on refill retry [+ + +]
Author: Jerome Tollet <[email protected]>
Date:   Mon Aug 24 16:16:44 2026 +0200

    net/mlx5e: Prevent stale XSK buffer release on refill retry
    
    [ Upstream commit e01620844c5c88b6fcf819d171df8e3976a0e76f ]
    
    When an XDP redirect to an AF_XDP socket fails because its RX ring is
    full, the XSK core frees the buffer. During the subsequent batched refill
    of a legacy cyclic RQ, mlx5e also releases the WQE's XSK buffer before
    allocating a replacement. If that refill succeeds only partially, a WQE
    left without a replacement retains its old buffer pointer.
    
    The buffer can meanwhile be allocated to another WQE. A later refill
    retry can then free the live buffer through the stale pointer and publish
    the same UMEM frame twice.
    
    Mark the WQE as released immediately after the driver-side free. The flag
    is already cleared when a replacement buffer is assigned, so refill
    retries no longer release stale pointers.
    
    The failure is silent and produces no kernel warning or splat. A
    standalone legacy cyclic-RQ zero-copy libxsk reproducer, using 64-byte UDP
    traffic offered at 12 Mpps, detected it: stock stopped after 2,854,914
    packets in 4.094 seconds, with 4,542 xdp_rx_ring_full events and 64
    ownership/double-publication errors. With this change it processed
    356,904,225 packets in 30 seconds despite 571,405 xdp_rx_ring_full events,
    with no ownership or data errors.
    
    Fixes: 3f93f82988bc ("net/mlx5e: RX, Defer page release in legacy rq for better recycling")
    Cc: [email protected]
    Suggested-by: Daniel Borkmann <[email protected]>
    Reviewed-by: Dragos Tatulea <[email protected]>
    Signed-off-by: Jerome Tollet <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
net/packet: call packet_parse_headers after virtio_net_hdr_to_skb [+ + +]
Author: Willem de Bruijn <[email protected]>
Date:   Wed Oct 7 13:57:30 2026 -0400

    net/packet: call packet_parse_headers after virtio_net_hdr_to_skb
    
    [ Upstream commit 513e23857a3a64fa73a1deb36a385eecd4ad7690 ]
    
    SOCK_RAW packet sockets incorrectly drop VLAN-tagged GSO packets
    without VIRTIO_NET_HDR_F_NEEDS_CSUM.
    
    packet_parse_headers() sets skb->protocol to VLAN but advances
    skb->network_header past the VLAN tags. virtio_net_hdr_to_skb()
    then flow dissects these packets, which parses the network header as a
    VLAN tag, and fails.
    
    Call packet_parse_headers() after virtio_net_hdr_to_skb() instead.
    
    This matches tun_get_user() and tap_get_user() and thus simplifies
    overall complexity.
    
    Commit 01fdecc0480d ("net: packet: fix wrong transport_header when
    sending VLAN-tagged frame") fixed the same issue for the transport
    header probe in packet_parse_headers(). That probe is now skipped if
    virtio_net_hdr_to_skb() already set the transport header, avoiding a
    redundant dissection.
    
    Implementation details:
    - Do not set skb->protocol to the RX wildcard ETH_P_ALL. SOCK_RAW then
      derives it from the link layer header, as before. SOCK_DGRAM now
      leaves it 0, or derives it from gso_type for GSO with NEEDS_CSUM.
    - Keep virtio_net_hdr_set_proto() last, so that the link layer protocol
      takes priority over gso_type.
    
    Reported-by: Junnan Zhang <[email protected]>
    Closes: https://lore.kernel.org/netdev/[email protected]/
    Fixes: dfed913e8b55 ("net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO")
    Signed-off-by: Willem de Bruijn <[email protected]>
    Acked-by: Michael S. Tsirkin <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net/packet: guard the ll header push in packet_rcv_spkt() [+ + +]
Author: Quchaosheng <[email protected]>
Date:   Mon Sep 28 19:31:08 2026 +0800

    net/packet: guard the ll header push in packet_rcv_spkt()
    
    commit 28bc1ef699610ee09ce3d46a00552f5a0a0144bd upstream.
    
    packet_rcv_spkt() restores the link layer header with
    
            skb_push(skb, skb->data - skb_mac_header(skb));
    
    That subtraction is only meaningful when the device actually has a link
    layer header.  packet_rcv() and tpacket_rcv() both wrap it in
    dev_has_header(), which is also the predicate the block comment at the
    top of the file states the restore in terms of; packet_rcv_spkt() does
    not.  commit d549699048b4 ("net/packet: fix packet receive on L3
    devices without visible hard header") introduced the helper and changed
    the two call sites, and this one stayed behind.
    
    A device without a visible ll header can leave skb->mac_header at the
    0xFFFF sentinel that __alloc_skb() initialises it to.  A CAN skb does:
    init_can_skb() sets pkt_type and ip_summed but does not reset the
    headers, and commit 9f10374bb024 ("can: remove private CAN skb
    headroom infrastructure") dropped the skb_reset_*_header() calls that
    used to be there.  skb_mac_header() is then 0xFFFF, the length becomes
    a large negative number and skb_push() reports it through
    skb_under_panic() -- from softirq context, so it is a full system panic
    even with panic_on_oops=0:
    
      skbuff: skb_under_panic: text:ffffffff8bd21bc1 len:-65455 put:-65471 head:... data:... tail:0x50 end:0x180 dev:can0
      kernel BUG at net/core/skbuff.c:214!
      RIP: 0010:skb_panic+0x50/0x60
      Call Trace:
       <IRQ>
       skb_push+0x38/0x40
       packet_rcv_spkt+0xe1/0x170
       __netif_receive_skb_core.constprop.0+0x7e8/0xd30
       ...
      Kernel panic - not syncing: Fatal exception in interrupt
    
    The socket type is reachable: packet_create() accepts SOCK_PACKET
    alongside SOCK_RAW and SOCK_DGRAM behind the same CAP_NET_RAW check,
    and neither the socket length nor a capability check keeps it away
    from a CAN interface.
    
    The missing skb_reset_*_header() calls in init_can_skb() are a
    regression in their own right and are being fixed separately, but a
    packet socket should not turn a link layer that did not initialise its
    mac header into a kernel panic.  Guard the push the way the other two
    receive paths do.
    
    Tested on v7.3-rc5 under QEMU with a slcan device on a pty, which is
    the driver RX path: vcan does not reproduce it, because can_send()
    resets the headers on the way out.  One SOCK_PACKET socket bound to
    can0 and one frame written into the line discipline panics an
    unpatched kernel with the trace above; the same image with this patch
    prints no panic and powers off normally.  Both kernels are this tree,
    defconfig plus CONFIG_CAN_SLCAN=y, differing only in this hunk.
    
    Fixes: d549699048b4 ("net/packet: fix packet receive on L3 devices without visible hard header")
    Cc: [email protected]
    Signed-off-by: Quchaosheng <[email protected]>
    Reviewed-by: Willem de Bruijn <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
net/sched: cls_route: reject change with no routing attribute [+ + +]
Author: Victor Nogueira <[email protected]>
Date:   Thu Oct 1 12:32:00 2026 -0300

    net/sched: cls_route: reject change with no routing attribute
    
    [ Upstream commit b72e025ac556984766392001e74b7587e145bcd0 ]
    
    route4_change on a filter change that supplies no routing attribute
    at all (no to/from/iif) reaches route4_set_parms with fold set, so the
    handle-mismatch check -- which only fires when creating -- is skipped.
    nhandle is built as the all-wildcard bucket (0x8000 | 0xFFFF << 16) and
    the filter is rekeyed to 0xFFFF8000, so the handle userspace already
    stored no longer addresses the filter. (The netlink reply carries the
    new handle; what goes stale is the handle the caller holds.)
    
    The rekey actually misclassifies the packets. The new handle's from_hash
    is the wildcard chain (route4_hash_wild), whose filters route4_classify
    applies without any id/iif comparison, and its bucket (256) is reached
    by every packet through the h < 256 restart. A filter that matched only
    a specific realm therefore becomes an unconditional catch-all that applies
    its classid and actions to all otherwise-unmatched traffic.
    
    Reject a change that would rekey the filter this way, with the
    routing-attributes-required error. A change that names at least one of
    to/from/iif, and an in-place replace that keeps the routing identity via
    a supplied attribute, are unaffected. A change of a filter that already
    sits at the wildcard handle is a metadata-only update and remains valid,
    so only a change that actually moves the handle is rejected.
    
    This is a follow-up to commit 41e85e54e564 ("net/sched: cls_route: Fix
    in-place replace"); this patch closes the no-routing-attribute variant
    that the parent series did not address.
    
    Conditions to recreate the bug:
      tc qdisc add dev lo clsact
      tc filter add dev lo ingress protocol ip pref 100 route from 1 to 1
      tc filter change dev lo ingress protocol ip pref 100 handle 0x10001 \
          route classid 1:2
      tc filter show dev lo ingress   # handle became 0xffff8000; iproute2's
                                      # stored 0x10001 no longer addresses it
    
    A change of a filter already at the wildcard handle, e.g. one created by
    "tc filter add dev lo ingress protocol ip pref 100 route classid 1:1"
    (iproute2 defaults the handle to 0xffff8000), stays a valid metadata-only
    update.
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reported-by: Sashiko <[email protected]>
    Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/[email protected]
    Reviewed-by: Jamal Hadi Salim <[email protected]>
    Signed-off-by: Victor Nogueira <[email protected]>
    Reviewed-by: Simon Horman <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net/sched: em_text: reject unterminated algo before autoload [+ + +]
Author: Jamal Hadi Salim <[email protected]>
Date:   Wed Sep 30 03:31:02 2026 -0400

    net/sched: em_text: reject unterminated algo before autoload
    
    [ Upstream commit c9728fcf2e7fb4a7a8d08ebd9524c3b02ae1a021 ]
    
    This is a follow-up to commit 9c572a83037a ("net/sched: fix potential
    stack infoleak in em_text_dump()"), which zero-initialised the dump-side
    struct. Sashiko pointed at a pre-existing bug that exposed the change-side
    input-validation gap open.
    
    em_text_change() casts the raw netlink attribute payload to struct
    tcf_em_text and passes conf->algo, a 16-byte array with no enforced NUL
    terminator, to textsearch_prepare().  On the TS_AUTOLOAD retry
    textsearch_prepare() calls request_module("ts_%s", algo); vsnprintf()
    walks %s until it finds a NUL, so an algo[] with no NUL reads past the
    array into the adjacent struct fields and payload and feeds those bytes
    to the usermode helper command line.  This is an out-of-bounds read and
    a kernel memory disclosure.
    
    Reject the attribute when no NUL exists within TC_EM_TEXT_ALGOSIZ bytes,
    matching the check xt_string has had since 3ab720881b6e.
    
    Conditions to recreate the bug:
    - CAP_NET_ADMIN on the target netns (namespace-local via unshare -Urn
      is enough)
    - install clsact on an interface, then add a basic filter with one text
      ematch whose algo[] is 16 bytes with no NUL (e.g. "A"*16) and
      pattern_len at least 1
    - the add fails with -ENOENT and the kernel invokes modprobe with a
      module name made of "ts_" plus the 16 bytes and the adjacent payload
    
    Fixes: d675c989ed2d4 ("[PKT_SCHED]: Packet classification based on textsearch (ematch)")
    Reported-by: Sashiko (gemini) <[email protected]>
    Closes: https://sashiko.dev/#/patchset/20260918133953.12494-1-bernard.ladenthin%40gmail.com
    Signed-off-by: Jamal Hadi Salim <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
net/smc: protect clcsock lifetime in smc_getname [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Thu Oct 8 16:44:44 2026 +0800

    net/smc: protect clcsock lifetime in smc_getname
    
    commit 64a6b36b0e1855288080bc5f89769f27d6dc03c8 upstream.
    
    smc_getname() dereferences smc->clcsock without holding
    clcsock_release_lock. Link-group termination can release the CLC socket
    through smc_close_active_abort() while the SMC socket is still open,
    for example after shutdown(SHUT_WR).
    
    A getsockname() caller can load smc->clcsock, then the termination worker
    can clear the pointer and call sock_release() before the caller accesses
    clcsock->ops or invokes getname(). This causes a use-after-free; if the
    worker clears the pointer before the load, it causes a NULL dereference.
    The syscall's file reference keeps the SMC socket alive but does not
    prevent asynchronous release of its CLC socket.
    
    KASAN reported the following with test-only timing instrumentation:
    
      BUG: KASAN: slab-use-after-free in smc_getname+0x19e/0x1b0
      Read of size 8 at addr ffff888109abb4e0 by task poc/103
      Call Trace:
       smc_getname+0x19e/0x1b0
       do_getsockname+0xe5/0x170
       __sys_getsockname+0x8c/0x100
    
      Allocated by task 95:
       sock_alloc_inode+0x1e/0x280
       sock_alloc+0x3d/0x240
       __sock_create+0x7e/0x430
       smc_create+0x121/0x240
    
      Freed by task 0:
       kmem_cache_free+0xcc/0x340
       rcu_core+0x50a/0x1850
    
      Last potentially related work creation:
       evict+0x446/0x6c0
       smc_clcsock_release+0xa8/0xd0
       smc_close_active_abort+0x26a/0x3a0
       __smc_lgr_terminate.part.0+0x137/0x2e0
    
    Hold clcsock_release_lock across the pointer check and the getname()
    callback to serialize with smc_clcsock_release(). Return -EBADF if the
    CLC socket has already been released, preserving the existing peer
    state check and the callback's return value otherwise.
    
    Fixes: b03faa1fafc8 ("net/smc: postpone release of clcsock")
    Cc: [email protected]
    Signed-off-by: Chengfeng Ye <[email protected]>
    Reviewed-by: Mahanta Jambigi <[email protected]>
    Reviewed-by: Dust Li <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param() [+ + +]
Author: Leto Liu (刘涛) <[email protected]>
Date:   Wed Sep 30 08:58:48 2026 +0200

    net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param()
    
    [ Upstream commit 7e170da2edec9fb0717543571cc14b0aabee2b46 ]
    
    CPU accesses QDMA via the bus. When multiple modules are using the bus
    simultaneously, CPU access to QDMA may encounter bus timeouts and fails,
    resulting in QDMA configuration failures and potentially causing packet
    transmission issues. In order to mitigate the issue, introduce a retry
    mechanism to airoha_qdma_set_trtcm_param routine in order to ensure the
    configuration is correctly applied to the hardware.
    
    It's enough to try a second time for the TRTCM config to be actually
    applied to make sure we are not in the middle of bucket handling as it does
    operate on fixed time slot internally.
    
    Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
    Signed-off-by: Leto Liu (刘涛) <[email protected]>
    [ improve commit description, drop memory block, apply better loop logic]
    Signed-off-by: Christian Marangi <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: always dissect GSO packets in __virtio_net_hdr_to_skb() [+ + +]
Author: Eric Dumazet <[email protected]>
Date:   Thu Oct 1 19:11:39 2026 +0000

    net: always dissect GSO packets in __virtio_net_hdr_to_skb()
    
    [ Upstream commit 44378d02c5aaae24b60a75fbbb539b4aa4db503d ]
    
    Commit 9e8db5913264 ("net: avoid false positives in untrusted gso
    validation") added a '&& skb->network_header' check before flow-dissecting
    GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM in
    __virtio_net_hdr_to_skb(), because some callers (such as tun_get_user(),
    tun_xdp_one(), virtnet_receive_done(), and raw_verify_header()) called
    virtio_net_hdr_*_to_skb() before initializing skb->network_header and
    skb->dev.
    
    Because __alloc_skb() and __build_skb_around() zero-initialize
    skb->network_header to 0 (unlike mac_header and transport_header which
    are initialized to ~0U), those four callers always had
    skb->network_header == 0 and bypassed flow dissection in
    __virtio_net_hdr_to_skb(). More generally, skb->network_header is an
    offset from skb->head (where 0 is also a valid offset whenever
    skb_headroom(skb) is 0), not a boolean flag.
    
    Whenever the 'if (gso_type && skb->network_header)' branch was skipped,
    the fallback 'else if (gso_type)' only pulled nh_min_len + thlen (40 bytes
    for TCPv4) without dissecting the packet, without validating ip_proto or
    n_proto, and without setting skb->transport_header.
    
    If the packet has a malformed network header, it is not rejected and a
    subsequent skb_probe_transport_header() also fails, leaving
    skb->transport_header at ~0U (0xffff). Similarly, if an IPv4 packet
    carries IP options (ihl > 5) or an IPv6 packet carries extension headers,
    pulling only nh_min_len + thlen can leave the TCP header outside
    skb->head. In both cases, tcp_hdrlen(skb) in skb_gso_transport_seglen()
    reads out-of-bounds:
    
      BUG: KASAN: slab-out-of-bounds in skb_gso_transport_seglen
      Read of size 2 by task poc/133
      skb_gso_transport_seglen (net/core/gso.c:155)
      skb_gso_validate_mac_len (net/core/gso.c:270)
      tbf_enqueue (net/sched/sch_tbf.c:260)
      dev_qdisc_enqueue (net/core/dev.c:4227)
      __dev_queue_xmit (net/core/dev.c:4884)
    
    In addition, checking virtio_net_hdr_match_proto() only inside
    'if (!skb->protocol)' before flow dissection both skipped validation when
    skb->protocol was pre-set by the caller and rejected VLAN-tagged frames
    whose outer L2 protocol is ETH_P_8021Q or ETH_P_8021AD.
    
    Fix this by:
    1. Initializing skb->dev and skb->network_header (plus skb->protocol for
       IFF_TUN) before virtio_net_hdr_*_to_skb() in tun_get_user(),
       tun_xdp_one(), virtnet_receive_done(), and raw_verify_header(). In
       tun_get_user(), drop the redundant skb_reset_mac_header(skb) in the
       IFF_TUN case since __virtio_net_hdr_to_skb() unconditionally resets
       mac_header.
    2. Removing '&& skb->network_header' and the unvalidated
       'else if (gso_type)' fallback in __virtio_net_hdr_to_skb() so all GSO
       packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are flow-dissected, have
       their transport header pulled into linear data, and have
       skb->transport_header set.
    3. Moving the virtio_net_hdr_match_proto() check to after
       skb_flow_dissect_flow_keys_basic(), validating keys.basic.n_proto
       against hdr_gso_type.
    
    Fixes: 9e8db5913264 ("net: avoid false positives in untrusted gso validation")
    Fixes: d5be7f632bad ("net: validate untrusted gso packets without csum offload")
    Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
    Reported-by: Weiming Shi <[email protected]>
    Closes: https://lore.kernel.org/netdev/[email protected]/
    Signed-off-by: Eric Dumazet <[email protected]>
    Reviewed-by: Willem de Bruijn <[email protected]>
    Cc: Michael S. Tsirkin <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET [+ + +]
Author: Justin Chen <[email protected]>
Date:   Wed Sep 30 16:06:34 2026 -0700

    net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET
    
    [ Upstream commit 5857e5a196b069766a39ceb754736326a43bc6bc ]
    
    When the revised suspend/resume sequence was introduced this led to an edge
    case where the TX is left disabled in the following sequence.
    
    1. phy link is down, so UMAC is held in reset and then network interface
       is WoL enabled
    2. Enter suspend, bcmgenet_wol_power_down_cfg() enables UMAC_RX since MAC
       is in SW_RESET
    4. Enter resume, UMAC_RX is left enabled. Since we only enable UMAC_TX
       and UMAC_RX in SW_RESET. The UMAC_TX is never enabled again on link up.
    
    The issue was hit in production and I verified the sequence keeps
    the TX  disabled in my standalone test. I tested on an internal
    development board with bcm77122, but should be reproducible
    on any genet HW that supports power management.
    
    Fixes: 254f3239dd07 ("net: bcmgenet: revise suspend/resume")
    Signed-off-by: Justin Chen <[email protected]>
    Reviewed-by: Florian Fainelli <[email protected]>
    Reviewed-by: Nicolai Buchwitz <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: bridge: avoid recursive multicast port cleanup [+ + +]
Author: Zixuan Chai <[email protected]>
Date:   Sun Sep 27 01:04:39 2026 +0800

    net: bridge: avoid recursive multicast port cleanup
    
    commit 5158353121bae4f552cb677ce8c5c3ef52f93a0d upstream.
    
    br_multicast_sg_del_exclude_ports() removes automatically added STAR_EXCL
    port groups by calling br_multicast_del_pg(). For S,G entries, that
    deletion calls back into br_multicast_sg_del_exclude_ports(), so a large
    number of STAR_EXCL ports consumes one kernel stack frame per port and can
    hit the stack guard page.
    
    Keep the complete port-group deletion path for cleanup, but suppress the
    S,G exclude-port cleanup while that helper is already walking the same
    entry. Normal deletion callers retain the existing behavior.
    
    Fixes: 8266a0491e92 ("net: bridge: mcast: handle port group filter modes")
    Cc: [email protected]
    Reported-by: Vega <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Zixuan Chai <[email protected]>
    Signed-off-by: Ren Wei <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: dsa: microchip: fix KSZ8765 fiber detection [+ + +]
Author: Sebastien Royen <[email protected]>
Date:   Wed Oct 7 10:05:57 2026 +0200

    net: dsa: microchip: fix KSZ8765 fiber detection
    
    commit fc13ba44da197a186f2f4d77c5b7d73d0f99f053 upstream.
    
    The KSZ8765 is similar to the KSZ8795 but has two fiber ports.
    
    KSZ8_PORT_STATUS_0 is used to detect fiber mode. It is currently
    defined as 0x08, which is the Global Control 6 MIB Control register
    and has bit 7 defined as Flush Counter.
    
    Set KSZ8_PORT_STATUS_0 to 0x18, which is the Port 1 Status 0 register
    where bit 7 is the Fiber Mode bit.
    
    This issue was discovered when upgrading an embedded device from kernel
    5.10 to 6.16. The device was using a KSZ8765 device tree configuration
    and the corresponding hardware, but during boot the kernel incorrectly
    detected it as a KSZ8795. The relevant boot messages were:
    
      ksz-switch spi0.0: found switch: KSZ8795, rev 0
      ksz-switch spi0.0: Device tree specifies chip KSZ8765 but found KSZ8795, please fix it!
    
    Cc: [email protected]
    Fixes: 91a98917a883 ("net: dsa: microchip: move switch chip_id detection to ksz_common")
    Reviewed-by: Nicolai Buchwitz <[email protected]>
    Signed-off-by: Sebastien Royen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: make dev_xdp_sb_prog_count() see programs attached through a link [+ + +]
Author: Jakub Kicinski <[email protected]>
Date:   Wed Sep 30 18:25:59 2026 -0700

    net: make dev_xdp_sb_prog_count() see programs attached through a link
    
    [ Upstream commit d333c8bca6dc3c5e978f6698d39dd799f3b0dc8d ]
    
    ethtool refuses to enable tcp-data-split on a device running
    a single-buffer XDP program (which can't deal with the payload
    landing in a separate buffer). dev_xdp_sb_prog_count() only looks
    at xdp_state[].prog though, ignoring bpf_link integration.
    Get the prog pointer from dev_xdp_prog(), which will consult both.
    
    bpf_xdp_link_update() needs a bit of a touch-up, too, since
    ethtool calls dev_xdp_sb_prog_count() with just the instance
    lock (for ops-locked devices) - we now have to make sure the
    link updates happen under that lock.
    
    Spotted by AI while reviewing the XDP propagation series,
    verified and tested on netdevsim with a C test along these lines:
    
      link = bpf_program__attach_xdp(prog, ifindex);
      system("ethtool -G eth0 tcp-data-split on")
    
    Fixes: 197258f0ef68 ("net: ethtool: add hds_config member in ethtool_netdev_state")
    Acked-by: Stanislav Fomichev <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: openvswitch: validate transport header presence in set_ipv6_addr [+ + +]
Author: Fernando Fernandez Mancera <[email protected]>
Date:   Thu Oct 8 12:41:35 2026 +0200

    net: openvswitch: validate transport header presence in set_ipv6_addr
    
    [ Upstream commit 3c6a4b11330fe424557538a98fca9f0a4c5bf313 ]
    
    When executing IPv6 address rewrite actions on IPv6 fragments,
    set_ipv6_addr() calls update_ipv6_checksum(). If parse_ipv6hdr()
    processes a non-first IPv6 fragment, it sets key->ip.proto to
    NEXTHDR_FRAGMENT and returns early without calling
    skb_set_transport_header().
    
    update_ipv6_checksum() unconditionally evaluates skb_transport_offset()
    on entry before checking l4_proto.  Because skb->transport_header is
    uninitialized, this triggers a warning under CONFIG_DEBUG_NET=y although
    it is completely harmless.
    
    Fix this by returning early in update_ipv6_checksum() if l4_proto is
    NEXTHDR_FRAGMENT. This avoids reading the uninitialized transport offset
    for fragments while preserving the debug warning for any other protocol
    where the transport header is unexpectedly missing.
    
    See the syzbot trace:
    
    !skb_transport_header_was_set(skb)
    WARNING: ./include/linux/skbuff.h:3075 at skb_transport_header include/linux/skbuff.h:3075 [inline], CPU#1: syz-executor463/5635
    WARNING: ./include/linux/skbuff.h:3075 at skb_transport_offset include/linux/skbuff.h:3250 [inline], CPU#1: syz-executor463/5635
    WARNING: ./include/linux/skbuff.h:3075 at update_ipv6_checksum net/openvswitch/actions.c:361 [inline], CPU#1: syz-executor463/5635
    WARNING: ./include/linux/skbuff.h:3075 at set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399, CPU#1: syz-executor463/5635
    [...]
    RIP: 0010:skb_transport_header include/linux/skbuff.h:3075 [inline]
    RIP: 0010:skb_transport_offset include/linux/skbuff.h:3250 [inline]
    RIP: 0010:update_ipv6_checksum net/openvswitch/actions.c:361 [inline]
    RIP: 0010:set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399
    [...]
    Call Trace:
     <TASK>
     set_ipv6 net/openvswitch/actions.c:531 [inline]
     do_execute_actions+0x557e/0x8600 net/openvswitch/actions.c:1366
     ovs_execute_actions+0xde/0x520 net/openvswitch/actions.c:1592
     ovs_packet_cmd_execute+0xb4f/0xf10 net/openvswitch/datapath.c:705
     genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
     genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
     netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
     genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
     netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
     sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800
    
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=4cc63fcfb3845e149969
    Fixes: 3fdbd1ce11e5 ("openvswitch: add ipv6 'set' action")
    Signed-off-by: Fernando Fernandez Mancera <[email protected]>
    Reviewed-by: Ilya Maximets <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits() [+ + +]
Author: Josef Bacik <[email protected]>
Date:   Wed Oct 7 17:29:34 2026 +0000

    net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits()
    
    commit ab9414ed70bd783e902a85c350620dee269bcb2b upstream.
    
    When skb_copy_and_csum_bits() reaches unreadable frags it returns 0
    after copying only the linear part, and the rest of the caller's buffer
    is left as it was.  The callers copy into a buffer that is about to go
    out on the wire: an ICMP error quoting the offending packet, or a
    driver's TX bounce buffer in skb_copy_and_csum_dev().  Neither buffer
    is zeroed beforehand, so whatever was in memory there gets sent.
    
    Zero the part of the buffer we didn't fill.  The checksum usually
    won't match the data any more, so the receiver will usually drop the
    packet, but either way it no longer carries anything it shouldn't.
    Only zero for a positive @len, a negative one from a broken caller must
    not turn into a huge memset().
    
    Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
    Cc: [email protected]
    Signed-off-by: Josef Bacik <[email protected]>
    Reviewed-by: Mina Almasry <[email protected]>
    Link: https://patch.msgid.link/20261007-b4-skb-copy-csum-stale-bytes-v1-1-adbbde033fb3@toxicpanda.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: sparx5: free the matchall entry on destroy [+ + +]
Author: Daniel Machon <[email protected]>
Date:   Wed Oct 7 17:03:15 2026 +0200

    net: sparx5: free the matchall entry on destroy
    
    commit 2b82e16d6084cbc651e3c902198f1945408ee1a5 upstream.
    
    sparx5_tc_matchall_replace() allocates a struct sparx5_mall_entry for
    every offloaded matchall filter and adds it to sparx5->mall_entries.
    sparx5_tc_matchall_destroy() removes the entry from the list, but never
    frees it, so the entry of every deleted mirror and goto matchall filter
    is leaked.
    
    Free the entry after unlinking it.
    
    The leak was discovered by an AI code review agent, and reproduced with
    kmemleak on a lan969x EV board (EV23X71A) by repeatedly adding and
    deleting matchall mirror and goto filters. With the fix, kmemleak no
    longer reports the leak.
    
    Cc: [email protected]
    Fixes: 1ede4acf045c ("net: sparx5: add bookkeeping code for matchall rules")
    Signed-off-by: Daniel Machon <[email protected]>
    Link: https://patch.msgid.link/20261007-sparx5-matchall-kfree-net-v1-1-c8918685b337@microchip.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: sparx5: start the TOD counters on non-PTP lan969x variants [+ + +]
Author: Quentin Freimanis <[email protected]>
Date:   Sun Oct 4 22:28:26 2026 -0700

    net: sparx5: start the TOD counters on non-PTP lan969x variants
    
    [ Upstream commit ca5012757bf027df83d51593a07656cb8c80caee ]
    
    Currently the base non-PTP-capable lan969x variants don't forward any
    Ethernet frames:
    
      $ ip link set eth10 up
    
      $ ip addr add 10.0.0.54/24 dev eth10
    
      $ ping 10.0.0.1
      PING 10.0.0.1 (10.0.0.1): 56 data bytes
    
      --- 10.0.0.1 ping statistics ---
      7 packets transmitted, 0 packets received, 100% packet loss
    
      $ cat /proc/interrupts | grep fdma
        20:          0  GIC-0  120 Level     sparx5-fdma
    
      $ ip -s link show dev eth10
          RX:  bytes packets errors dropped  missed   mcast
               20828     102      0       0       0      72
          TX:  bytes packets errors dropped carrier collsns
                   0       0      0       0       0       0
    
    Testing showed that starting the domain 0 TOD counter gets networking
    working again, but start all three for consistency with the PTP variants.
    
    Fixes: 207966787b71 ("net: sparx5: add feature support")
    Suggested-by: Daniel Machon <[email protected]>
    Signed-off-by: Quentin Freimanis <[email protected]>
    Reviewed-by: Daniel Machon <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: stmmac: Disable S-Tag processing on dwmac4 [+ + +]
Author: Ovidiu Panait <[email protected]>
Date:   Mon Sep 28 20:34:41 2026 +0000

    net: stmmac: Disable S-Tag processing on dwmac4
    
    [ Upstream commit da17990421d79f1bfb4142f9d767fd33daecc3d8 ]
    
    Currently, hardware VLAN stripping is broken for 802.1ad tags. vlan_rx_hw()
    hardcodes ETH_P_8021Q when putting the hardware tag into the skb, rather
    than using the actual protocol from the packet. Because of this, packets
    that contain a 802.1ad outer tag are incorrectly passed up the stack as
    having an 802.1Q tag. This causes QinQ ping between two hosts to fail.
    
    vlan_rx_hw() is shared by dwxgmac2 and dwmac4: on dwxgmac2 the tag type
    is available in the RDES3 write-back descriptor (the ET_LT field), so the
    outer tag type can be determined based on that info. However, dwmac4
    doesn't seem to provide the tag type. The Length/Type field in RDES3 only
    indicates whether the packet is single or double-tagged, not which tag
    type was stripped.
    
    Since dwmac4 cannot report the stripped tag type, it cannot support
    hardware S-Tag stripping correctly. Therefore, restrict the
    NETIF_F_HW_VLAN_STAG_RX and NETIF_F_HW_VLAN_STAG_FILTER advertisement
    to dwxgmac2 only.
    
    With this, 802.1ad tags are left in place and handled by the software
    VLAN path.
    
    Fixes: 750011e239a5 ("net: stmmac: Add support for HW-accelerated VLAN stripping")
    Signed-off-by: Ovidiu Panait <[email protected]>
    Reviewed-by: Maxime Chevallier <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: stmmac: Do not advertise S-VLAN stripping when it is disabled [+ + +]
Author: Ovidiu Panait <[email protected]>
Date:   Mon Sep 28 20:34:40 2026 +0000

    net: stmmac: Do not advertise S-VLAN stripping when it is disabled
    
    [ Upstream commit c63ce7b9c7e7b68267899e4a0fc14b35d2c1dfcc ]
    
    C-VLAN and S-VLAN tag stripping are both controlled by the EVLS bit,
    so disabling rx-vlan-offload also disables S-VLAN tag stripping.
    However, rx-vlan-stag-hw-parse keeps being advertised as enabled:
    
    root@rzv2h-evk:~# ethtool -K end1 rx-vlan-offload off
    root@rzv2h-evk:~# ethtool -k end1 | grep -i vlan
    rx-vlan-offload: off
    tx-vlan-offload: off [fixed]
    rx-vlan-filter: on [fixed]
    vlan-challenged: off [fixed]
    tx-vlan-stag-hw-insert: off [fixed]
    rx-vlan-stag-hw-parse: on [fixed]
    rx-vlan-stag-filter: on [fixed]
    
    Fix this inconsistency by making NETIF_F_HW_VLAN_STAG_RX follow
    NETIF_F_HW_VLAN_CTAG_RX.
    
    Fixes: 750011e239a5 ("net: stmmac: Add support for HW-accelerated VLAN stripping")
    Signed-off-by: Ovidiu Panait <[email protected]>
    Reviewed-by: Maxime Chevallier <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: stmmac: propagate PTP addend and system time programming errors [+ + +]
Author: Lorenzo Bianconi <[email protected]>
Date:   Tue Sep 29 15:10:11 2026 +0200

    net: stmmac: propagate PTP addend and system time programming errors
    
    [ Upstream commit 232d49dd4b40a666283de9e722899f088ed581b2 ]
    
    stmmac_update_subsecond_increment() ignores the error returned by
    stmmac_config_addend(), and stmmac_init_tstamp_counter() discards the
    addend and system time programming errors, always returning success. A
    failure to program the addend (PTP_TCR_TSADDREG) or to initialize the
    system time counter (PTP_TCR_TSINIT) is therefore silently swallowed,
    leaving the hardware timestamp counter in a non-running or partially
    configured state while the driver keeps operating as if timestamping
    were up. This matters for TAPRIO/EST offloading, which derives the gate
    base time from the hardware timestamp counter.
    
    The same hooks are also called from the PHC callbacks: settime64 and
    adjfine drop the error and report success to clock_settime() and
    clock_adjtime(), so a dead PTP reference clock goes unnoticed by
    ptp4l/phc2sys.
    
    Return error codes from stmmac_update_subsecond_increment(),
    stmmac_init_tstamp_counter(), stmmac_dl_ts_coarse_set() and the
    settime64/adjfine callbacks instead of silently returning success. On
    failure, roll back the partially applied configuration so the hardware
    and the driver bookkeeping stay consistent, and report the reason
    through the devlink extack. Also guard against a zero sub-second
    increment, which would otherwise divide by zero when computing the
    addend.
    
    Reset the persistent timestamping state (hwts_tx_en, hwts_rx_en,
    tstamp_config, systime_flags and tsfupdt_coarse) when (re)initializing
    timestamping, so a failed init does not leave TX/RX timestamping
    enabled on a counter that never started.
    
    Fixes: cc4c9001ce31 ("net: stmmac: Switch stmmac_hwtimestamp to generic HW Interface Helpers")
    Signed-off-by: Lorenzo Bianconi <[email protected]>
    Reviewed-by: Maxime Chevallier <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

net: team: free skb when broadcast has no txable port [+ + +]
Author: Weiming Shi <[email protected]>
Date:   Fri Oct 2 02:23:26 2026 +0800

    net: team: free skb when broadcast has no txable port
    
    commit 489114c9ecae44e523361a4b3e610ee5ebd9189c upstream.
    
    bc_transmit() sends the original skb through the last txable port.
    When no port is txable, it returns false without consuming the skb, but
    team_xmit() still returns NETDEV_TX_OK. AF_PACKET sends then retain the
    skb and its socket write-memory charge.
    
    A TX-enabled, link-down port keeps the broadcast transmit op installed.
    Carrier can stay up through a second link-up, TX-disabled port or be
    forced on by userspace. Free the original skb on the no-port path while
    leaving the existing drop accounting intact.
    
    Discovered by Sashiko during review of previous commit.
    
    Cc: [email protected]
    Fixes: 5fc889911a99 ("team: add broadcast mode")
    Signed-off-by: Weiming Shi <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: team: stop reusing skb after queue override [+ + +]
Author: Weiming Shi <[email protected]>
Date:   Fri Oct 2 02:23:25 2026 +0800

    net: team: stop reusing skb after queue override
    
    commit b7454f1940c5e6d92e753853c476a769e452f30a upstream.
    
    A nonzero dev_queue_xmit() result does not return ownership of the skb.
    When an override port's qdisc drops it, the queue override helper used to
    try another port or the mode transmit op with the freed skb.
    
    Return the handoff decision separately from transmit success. Select only
    the first override port under RCU and stop after handing it the skb,
    regardless of the lower transmit result. Keep the existing success and
    drop accounting.
    
      BUG: KASAN: slab-use-after-free in sk_skb_reason_drop
      Write of size 4 by task poc/5040
      sk_skb_reason_drop (net/core/skbuff.c:1240)
      dev_kfree_skb_any_reason (net/core/dev.c:3470)
      ab_transmit (drivers/net/team/team_mode_activebackup.c:49)
      team_xmit (drivers/net/team/team_core.c:1849)
      __dev_direct_xmit (net/core/dev.c:4934)
      Freed by task 5040:
      __tcf_kfree_skb_list (net/sched/sch_generic.c:43)
      __dev_queue_xmit (net/core/dev.c:4831)
      team_xmit (drivers/net/team/team_core.c:1846)
      Kernel panic - not syncing: KASAN: panic_on_warn set ...
    
    Cc: [email protected]
    Fixes: 8ff5105a2b9d ("team: add support for queue override by setting queue_id for port")
    Reported-by: <[email protected]>
    Signed-off-by: Weiming Shi <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: usb: ax88179_178a: fix rx frame length for non-last packets [+ + +]
Author: Fredrik Nyberg <[email protected]>
Date:   Fri Oct 2 14:28:57 2026 +0200

    net: usb: ax88179_178a: fix rx frame length for non-last packets
    
    commit 9b6c20f788472d2042717a3c2f1bc60b2b77083e upstream.
    
    Commit 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about
    skb->truesize") replaced skb_clone() with a copy into a new skb for
    every packet of a bulk-in transfer except the last one. The copy skips
    the 2-byte IP alignment pseudo header but still copies pkt_len bytes,
    and pkt_len includes that header. Each of these frames is therefore
    delivered with two extra trailing bytes: the 0xeeee pseudo header of
    the next slot when the frame ends on an 8-byte boundary, or slot
    padding otherwise. The last packet is still trimmed to pkt_len - 2.
    
    IPv4 and IPv6 trim the extra bytes, so most traffic is unaffected.
    Anything that relies on the frame length is not. MACsec takes the ICV
    from the last 16 bytes and drops every such frame as InPktsNotValid. In
    our setup that was 0.2-1.2% of received MACsec frames, depending on how
    many frames shared a transfer, including service discovery multicast.
    
    Allocate and copy pkt_len - 2 bytes, like the last-packet path.
    
    Fixes: 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about skb->truesize")
    Cc: [email protected]
    Signed-off-by: Fredrik Nyberg <[email protected]>
    Reviewed-by: Simon Horman <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop [+ + +]
Author: Suraj Gupta <[email protected]>
Date:   Tue Sep 29 00:12:07 2026 +0530

    net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop
    
    commit bcf2573a68a808a5b54cadafa72b6672e662c2bf upstream.
    
    In the dmaengine path the driver pre-submits RX buffers and holds
    in-flight TX buffers whose SKBs are DMA-mapped by the driver and freed
    only in the completion callbacks. On ndo_stop() dmaengine_terminate_sync()
    aborts these descriptors without running their callbacks, and the driver
    then frees only the ring shells, leaking every SKB still owned by the
    engine and its DMA mapping on each ifdown. With 128 RX buffers pre-posted
    per channel, the mapping leak can eventually exhaust a limited IOMMU
    aperture.
    
    Clear the slot's skb in the TX and RX callbacks so a non-NULL skb marks a
    slot that still owns a live, DMA-mapped buffer, and on stop unmap and free
    every such buffer.
    
    axienet_dma_rx_cb() runs from the DMA tasklet and re-arms the RX ring on
    each completion, so it can race axienet_stop(): a completion may submit a
    fresh buffer after dmaengine_terminate_sync() has returned, leaving the
    channel armed with a buffer the teardown then frees while the engine may
    still write into it (dma_release_channel() does not stop it either). Add a
    lock that axienet_dma_rx_cb() holds across the @stopping check and the
    resubmit, and axienet_stop() holds to set @stopping before terminating.
    Once @stopping is set no callback can arm a new buffer, and any armed just
    before is aborted by the terminate, so teardown only frees buffers the
    engine no longer owns.
    
    Fixes: 6a91b846af85 ("net: axienet: Introduce dmaengine support")
    Cc: [email protected]
    Signed-off-by: Suraj Gupta <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
nullfs: don't update the access time [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Fri Oct 2 15:52:38 2026 +0200

    nullfs: don't update the access time
    
    commit caf16f9b4aa66e5092f95e98cda54f2bb7482ed2 upstream.
    
    There's no point in updating access times of the nullfs instance. Raise
    S_IMMUTABLE.
    
    Fixes: 9d4e752a24f7 ("namespace: allow creating empty mount namespaces")
    Cc: [email protected] # v7.1+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
nvme: fix swapped ZRASF zone state values for full and read only [+ + +]
Author: Karl Bonde Torp <[email protected]>
Date:   Tue Sep 29 16:25:00 2026 +0200

    nvme: fix swapped ZRASF zone state values for full and read only
    
    commit 564e46d9f6e87912effa03f123d37a511d520f09 upstream.
    
    The Zone Management Receive command Zone Receive Action Specific (ZRASF)
    reporting option values for the Full and Read Only zone states are swapped
    compared to the NVM Express Zoned Namespace Command Set Specification,
    Revision 1.5, Figure 35:
    
    - 5h lists the zones in the ZSF:Full state.
    - 6h lists the zones in the ZSRO:Read Only state.
    
    The nvmet ZNS backend uses these constants to map the ZRASF value received
    from the host to a block layer zone condition when filtering zones in
    Report Zones. Because of the swap, a host asking for full zones was given
    the read only zones, and a host asking for read only zones was given the
    full zones.
    
    Swap the values of NVME_ZRASF_ZONE_STATE_FULL and
    NVME_ZRASF_ZONE_STATE_READONLY to match the specification.
    
    Fixes: aaf2e048af27 ("nvmet: add ZBD over ZNS backend support")
    Cc: [email protected]
    Reviewed-by: Damien Le Moal <[email protected]>
    Signed-off-by: Karl Bonde Torp <[email protected]>
    Signed-off-by: Andreas Hindborg <[email protected]>
    Signed-off-by: Keith Busch <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
nvmet: return Invalid Field for invalid NSIDs feature 82h [+ + +]
Author: Guixin Liu <[email protected]>
Date:   Sun Sep 20 11:34:59 2026 +0800

    nvmet: return Invalid Field for invalid NSIDs feature 82h
    
    [ Upstream commit d99bc5b456fd63be46c8bda20dbf6ede93d2fc11 ]
    
    The Reservation Notification Mask feature (FID 82h) defines its own
    status code for namespaces that do not support reservations:
    
      "If a Set Features command or a Get Features command attempts to
      access the Reservation Notification Mask on a namespace that does
      not support reservations or is invalid, then that command is
      aborted with status code of Invalid Field in Command."
    
      -- NVMe Base Specification, section 5.2.26.1.33
    
    The Set Features handler routes the namespace lookup through
    nvmet_req_find_ns(), which returns Invalid Namespace or Format for an
    unknown NSID.  That is the correct status for the generic
    namespace-scoped admin commands, but not for this feature: a Set
    Features 82h naming a nonexistent NSID is aborted with Invalid
    Namespace or Format instead of Invalid Field in Command.
    
    Translate the lookup failure to Invalid Field in Command.  The
    broadcast NSID, the namespace-without-reservations case and everything
    else keep their current behavior.
    
    Fixes: 5a47c2080a73 ("nvmet: support reservation feature")
    Reviewed-by: Christoph Hellwig <[email protected]>
    Reviewed-by: Nilay Shroff <[email protected]>
    Signed-off-by: Guixin Liu <[email protected]>
    Signed-off-by: Keith Busch <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

nvmet: use the local P2P device on metadata allocation failure [+ + +]
Author: Sang-Hoon Choi <[email protected]>
Date:   Wed Sep 30 16:08:58 2026 +0900

    nvmet: use the local P2P device on metadata allocation failure
    
    [ Upstream commit 4aa9c0f377a4de5e8fddce76b34ee4529639a1ff ]
    
    nvmet_req_alloc_p2pmem_sgls() assigns req->p2p_dev only after the data
    and metadata SGL allocations succeed. If the data allocation succeeds
    but the metadata allocation fails, out_free_sg passes req->p2p_dev to
    pci_p2pmem_free_sgl() before that assignment has taken place.
    
    Pass the local p2p_dev argument instead, so cleanup uses the same PCI
    device as the successful data allocation.
    
    Fixes: bcd9a0797d73 ("nvmet: fix freeing unallocated p2pmem")
    Reported-by: Changyul Lee <[email protected]>
    Reviewed-by: Maurizio Lombardi <[email protected]>
    Signed-off-by: Sang-Hoon Choi <[email protected]>
    Signed-off-by: Keith Busch <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
openvswitch: fix soft lockup in the netlink flow dump [+ + +]
Author: Denis V. Lunev <[email protected]>
Date:   Tue Sep 29 09:25:19 2026 +0200

    openvswitch: fix soft lockup in the netlink flow dump
    
    commit aaaaf87ea99b8766c9a8aa0e71aa42e6bc8a5320 upstream.
    
    A production compute node carrying a few thousand datapath flows hit a
    soft lockup inside a single netlink flow dump and panicked.
    
    ovs_flow_cmd_dump() calls ovs_flow_stats_get() for every flow it
    emits, and that releases stats->lock with spin_unlock_bh() once per
    CPU that has touched the flow. Every release is a local_bh_enable(),
    and each one runs the pending softirq backlog in the dumping thread's
    own context.
    
    The skb bounds the flows one callback emits, but not the softirq work
    it absorbs. On a CPU that carries the box's packet load the backlog
    refills as fast as it drains, so the dumping thread becomes that CPU's
    softirq engine. It never sleeps and it has no reschedule point, so
    under voluntary preemption nothing can take the CPU away from it:
    neither the ksoftirqd the kernel woke to take the work over, nor the
    stopper thread the softlockup detector dispatches to refresh its
    timestamp.
    
    Hold BH off across the whole callback instead, the way
    ctnetlink_dump_table() does, so the nested spin_unlock_bh() stop
    draining softirqs. The loop already runs under rcu_read_lock() and
    cannot sleep. What it gives up is preemption under CONFIG_PREEMPT,
    since a BH-off region is not preemptible outside PREEMPT_RT. The
    region stays short: the skb caps the flows one callback emits, and
    empty buckets cost no skb space but are each visited once per dump, as
    the cursor only moves forward. The table grows on insert and shrinks
    only on flush, so the walk is bounded by the largest flow count the
    datapath has held. The softirq backlog the callback used to absorb has
    no bound at all.
    
    Fixes: 63e7959c4b9b ("openvswitch: Per NUMA node flow stats.")
    Cc: [email protected]
    Signed-off-by: Denis V. Lunev <[email protected]>
    Reviewed-by: Ilya Maximets <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
optee: register TEE devices only once fully initialized [+ + +]
Author: Shao-Fu Chen <[email protected]>
Date:   Fri Sep 18 18:10:46 2026 +0800

    optee: register TEE devices only once fully initialized
    
    commit c108feca0a096f8db25d1b69130035025e9e936d upstream.
    
    optee_probe() called tee_device_register() on both the client and the
    supplicant device before the rest of struct optee had been initialized.
    
    tee_device_register() calls cdev_device_add(), which does two things at
    once: it creates /dev/tee0 and /dev/teepriv0, and it links the device
    into the tee class so that class_find_device() can find it. From that
    moment on the device is reachable both from user space via tee_open()
    and from kernel space via tee_client_open_context(). The only gate in
    teedev_open() is tee_device_get(), which merely checks that
    teedev->desc is non-NULL, which was already set by tee_device_alloc().
    Therefore, there is effectively no gate at all.
    
    A context opened in that window can run against a struct optee where
    
      - optee->call_queue.mutex is not initialized by optee_cq_init()
      - optee->supp mutex and completions is not initialized by
        optee_supp_init()
      - optee->rpmb_dev_mutex is not initialized yet,
      - the message argument cache is not initialized by
        optee_shm_arg_cache_init()
      - optee->ctx is still NULL
    
    Any open session or invoke during this window takes uninitialized
    mutexes and dereferences a NULL pointer.
    
    Fix it by moving both tee_device_register() calls down to the point
    where all of struct optee is set up.
    
    Fixes: 4fb0a5eb364d ("tee: add OP-TEE driver")
    Cc: [email protected]
    Signed-off-by: Shao-Fu Chen <[email protected]>
    [JW: adding fixes and cc]
    Signed-off-by: Jens Wiklander <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
pfcp: make sure the SEID is linear before reading it [+ + +]
Author: Haishuang Yan <[email protected]>
Date:   Wed Sep 30 20:48:18 2026 +0800

    pfcp: make sure the SEID is linear before reading it
    
    [ Upstream commit 23609bce9e1de525d1d0e73fc68c6e7971d0b49e ]
    
    pfcp_encap_recv() only makes sure that the UDP header and the 4 byte
    PFCP header are in the linear area. When the S flag is set,
    pfcp_session_recv() then reads the 8 byte SEID that follows, which is
    not covered by the pskb_may_pull() check.
    
    A short PFCP packet with the S flag set, or one whose session header
    lies in a fragment, therefore makes pfcp_session_recv() read beyond the
    end of the packet data, and whatever it finds there is stored in the
    tunnel metadata that flower later classifies on.
    
    Pull up to the end of the SEID before reading it, and drop packets
    that are too short to contain it. Reload the header pointer afterwards
    since pskb_may_pull() may reallocate the skb head.
    
    Use offsetofend() rather than sizeof(struct pfcphdr_session): the
    structure is not packed, so its size is 16 bytes because of the
    alignment of the __be64 member, while the header on the wire is only 12
    bytes, and valid session messages would be dropped.
    
    Fixes: 6dd514f48110 ("pfcp: always set pfcp metadata")
    Signed-off-by: Haishuang Yan <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains [+ + +]
Author: Ming Qian <[email protected]>
Date:   Mon Sep 21 19:03:34 2026 +0900

    pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains
    
    commit 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d upstream.
    
    On i.MX8MP the VPU blk-ctrl exposes G1, G2 and VC8000E as three separate
    genpds, each serialized only by its own genpd lock, so their power_on and
    power_off callbacks can run concurrently on SMP.
    
    The sequences are not independent: they share the VPUMIX bus domain, the
    VPU_NOC and the ADB400 handshake. On power up the GPC cannot ack-verify
    the ADB400 handshake - the ack only completes once blk-ctrl sets the bus
    clk-en bit - so it just waits a fixed delay instead of polling hskack. A
    sibling transition landing inside another domain's reset window disturbs
    that shared clock and handshake timing, the victim's reset does not take
    effect, and its block registers read back all zeros: the decoder times
    out or the encoder fails its format check.
    
    Serialize the blk-ctrl reset sequence with a per-blk-ctrl mutex; the
    driver deliberately avoids a genpd hierarchy, so the genpd core gives no
    cross-sibling serialization.
    
    Fixes: a1a5f15f7f6c ("soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl")
    Signed-off-by: Ming Qian <[email protected]>
    Reviewed-by: Frank Li <[email protected]>
    Cc: [email protected]
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

pmdomain: rockchip: don't ignore clock lookup errors on attach [+ + +]
Author: Shawn Lin <[email protected]>
Date:   Mon Sep 21 14:52:52 2026 +0800

    pmdomain: rockchip: don't ignore clock lookup errors on attach
    
    commit 4c66c423593e26273ea0d644906ed007630c6f6d upstream.
    
    rockchip_pd_attach_dev() treated every of_clk_get() error as the end
    of the clock list, so a clock that exists but is not available yet
    (e.g. -EPROBE_DEFER) was silently skipped and the device ended up
    without pm_clk management.  Only -ENOENT means there are no more
    clocks.
    
    Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain driver")
    Signed-off-by: Shawn Lin <[email protected]>
    Reviewed-by: Sebastian Reichel <[email protected]>
    Cc: [email protected]
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

pmdomain: rockchip: fix clock leak on domain probe failure [+ + +]
Author: Shawn Lin <[email protected]>
Date:   Mon Sep 21 14:52:51 2026 +0800

    pmdomain: rockchip: fix clock leak on domain probe failure
    
    commit d8b3847770661b7109146e6479eeadcdab9cecf0 upstream.
    
    When of_clk_get() failed in the middle of the loop, the references of
    the clocks acquired so far were leaked instead of being released by
    the error path.
    
    Fixes: d909072d0521 ("soc: rockchip: power-domain: use clk_bulk APIs")
    Signed-off-by: Shawn Lin <[email protected]>
    Reviewed-by: Sebastian Reichel <[email protected]>
    Cc: [email protected]
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

pmdomain: rockchip: propagate subdomain add errors [+ + +]
Author: Shawn Lin <[email protected]>
Date:   Mon Sep 21 14:52:50 2026 +0800

    pmdomain: rockchip: propagate subdomain add errors
    
    commit 4c0d69d677cf5b0065ebbb3ceb8ba66fddbec630 upstream.
    
    rockchip_pm_add_subdomain() ignored the return value of its recursive
    call, so a failure deeper in the hierarchy was silently dropped and
    probe still succeeded with an incomplete domain tree.
    
    Fixes: 6be05b5ec161 ("soc: rockchip: power-domain: add support for sub-power domains")
    Signed-off-by: Shawn Lin <[email protected]>
    Reviewed-by: Sebastian Reichel <[email protected]>
    Cc: [email protected]
    Signed-off-by: Ulf Hansson <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all() [+ + +]
Author: Alexey Charkov <[email protected]>
Date:   Wed Sep 30 20:10:21 2026 +0400

    power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all()
    
    commit 0d6c5794fd633427f0d4ad8b51d94061295649da upstream.
    
    of_regulator_bulk_get_all() allocates the consumers array and hands it to
    the caller, who is expected to free it at an appropriate time.
    pwrseq-pcie-m2.c never did, leading to a memory leak.
    
    Add an explicit kfree() for the consumers array.
    
    Cc: [email protected]
    Fixes: 52e7b5bd62ba ("power: sequencing: Add the Power Sequencing driver for the PCIe M.2 connectors")
    Signed-off-by: Alexey Charkov <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Bartosz Golaszewski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
ptp: ocp: fix PCIe delay estimation calculation [+ + +]
Author: Vadim Fedorenko <[email protected]>
Date:   Wed Oct 7 20:33:59 2026 +0000

    ptp: ocp: fix PCIe delay estimation calculation
    
    [ Upstream commit f8c8bd159a9bf626dd4921b7746ff481fce8c758 ]
    
    The commit in fixes introduced a high cap for delayas U64_MAX value
    while ktime_t is actually s64. This is wrong cap as it becomes negative
    value and any comparison to a real delay will fail to update delay
    value. Use KTIME_MAX constant as correct max cap for PCIe delay.
    
    The issue was hit in production (a negative value is observed):
    
      # cat /sys/class/timecard/ocp0/ts_window_adjust
      -3
    
    Fixes: aa05fe67bcd64 ("ptp: ocp: Improve PCIe delay estimation")
    Signed-off-by: Vadim Fedorenko <[email protected]>
    Reviewed-by: Daniel Machon <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
regulator: ltc3676: don't read the write-only HRST and CLIRQ registers [+ + +]
Author: Abhishek Ojha <[email protected]>
Date:   Tue Sep 1 21:07:01 2026 -0400

    regulator: ltc3676: don't read the write-only HRST and CLIRQ registers
    
    commit 28c2388ee24cdbefbcc458fa41ef7bffaaa1cc83 upstream.
    
    HRST (0x1e) and CLIRQ (0x1f) are write-only command strobes. Writing HRST
    triggers a hard reset of the chip and writing CLIRQ clears the interrupt;
    reading them returns nothing useful, and the read itself fires the command.
    
    The result is that a plain register dump resets the board:
    
      cat /sys/kernel/debug/regmap/2-003c/registers
    
    walks every readable register, hits HRST, and the board reboots.
    
    Split the callback back in two so HRST and CLIRQ stay writable but are no
    longer readable. The readable range is left unchanged
    (LTC3676_BUCK1 ... LTC3676_IRQSTAT).
    
    Fixes: 37b918a034fe ("regulator: Add LTC3676 support")
    Cc: [email protected]
    Signed-off-by: Abhishek Ojha <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

regulator: of: fill in supply names in of_regulator_bulk_get_all() [+ + +]
Author: Alexey Charkov <[email protected]>
Date:   Wed Sep 30 20:13:03 2026 +0400

    regulator: of: fill in supply names in of_regulator_bulk_get_all()
    
    commit e2151c29cec73f6cc70abf1c7cbc7b9b202489f5 upstream.
    
    of_regulator_bulk_get_all() returns an array it allocated itself, and
    fills in only the consumer of each entry. Every other way of getting a
    bulk array has the supply name set, because the caller provides it, and
    the core expects it to be there: regulator_bulk_enable() prints it when
    a supply fails to enable, so a caller that hands such an array to it
    dereferences uninitialised memory on that path.
    
    Copy each name into the array's own allocation, right behind the
    entries, so that it shares the array's lifetime and callers still have
    nothing extra to free. That also retires the fixed 64 byte stack buffer
    the names were assembled in, which is_supply_name() never bounded the
    copy against.
    
    Cc: [email protected]
    Reported-by: Sashiko <[email protected]>
    Closes: https://sashiko.dev/#/patchset/[email protected]?part=3
    Fixes: 27b9ecc7a9ba ("regulator: Add of_regulator_bulk_get_all")
    Signed-off-by: Alexey Charkov <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4 [+ + +]
Author: Ridham Khurana <[email protected]>
Date:   Wed Sep 30 10:53:25 2026 +0000

    regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4
    
    commit 2f15518682c779b1014552cb2ccb4a2052f85f27 upstream.
    
    The TPS65224 BUCK2, BUCK3 and BUCK4 descriptors pass 4 as
    n_linear_ranges, but tps65224_bucks_2_3_4_ranges[] only has two
    entries, covering selectors 0x00-0x45.
    
    The linear range helpers loop over n_linear_ranges entries, so any
    lookup of a selector above 0x45 reads past the end of the array and
    treats whatever follows it as two more ranges. This happens on the
    normal registration path when the core checks the voltage constraints
    against every selector. TPS652G1 uses the same descriptors and is
    affected too.
    
    Use ARRAY_SIZE() so the count always matches the table.
    
    Fixes: 00c826525fba ("regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators")
    Cc: [email protected]
    Signed-off-by: Ridham Khurana <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification" [+ + +]
Author: Or Har-Toov <[email protected]>
Date:   Sun Oct 4 11:35:31 2026 +0300

    Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification"
    
    [ Upstream commit 86b785b18f8f4a6b4a7392d1e2b29d6bb095011a ]
    
    This reverts commit ad0ae7aefa7a ("net/mlx5: E-Switch, preserve max tx
    speed on vport state modification").
    
    mlx5_modify_vport_admin_state() and mlx5_esw_adj_vport_modify() query
    the vport's current max_tx_speed before modifying its state, and
    write that value back, to avoid resetting it to 0 as a side effect
    of an unrelated admin-state change.
    
    That's unnecessary: max_tx_speed is optional in MODIFY_VPORT_STATE -
    FW skips writing it whenever it's 0, treating that as "not provided"
    rather than "reset to zero". Leaving it unset already preserves FW's
    current value, with no query needed.
    
    Fixes: ad0ae7aefa7a ("net/mlx5: E-Switch, preserve max tx speed on vport state modification")
    Signed-off-by: Or Har-Toov <[email protected]>
    Reviewed-by: Mark Bloch <[email protected]>
    Signed-off-by: Tariq Toukan <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
Revert "net: stmmac: propagate PTP addend and system time programming errors" [+ + +]
Author: Jakub Kicinski <[email protected]>
Date:   Mon Oct 5 18:19:20 2026 -0700

    Revert "net: stmmac: propagate PTP addend and system time programming errors"
    
    [ Upstream commit d5a007b9b457c915ab1a53227e8939e4018aa97a ]
    
    This reverts commit 232d49dd4b40a666283de9e722899f088ed581b2.
    
    Anirudh reports a regression from this change.
    
    It is not appropriate for net this late in the release cycle
    in the first place, so let's revert and revisit in net-next.
    
    Reported-by: Anirudh Srinivasan <[email protected]>
    Link: https://lore.kernel.org/CAEev2e8+fr1tJnSErD+2TtLDw5fGJbQOMcM5eefMnLyFUR+m7w@mail.gmail.com
    Fixes: 232d49dd4b40 ("net: stmmac: propagate PTP addend and system time programming errors")
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
Revert "wifi: ath12k: add panic handler" [+ + +]
Author: Yingying Tang <[email protected]>
Date:   Thu Jun 11 20:23:32 2026 -0700

    Revert "wifi: ath12k: add panic handler"
    
    [ Upstream commit 05165f7b3b9ab6817fe216c24f90755b7c5e15f3 ]
    
    ath12k_core_panic_handler() is invoked via atomic_notifier_call_chain(),
    which runs inside an RCU read-side critical section. The current code calls
    ath12k_pci_sw_reset() synchronously from this context, which eventually
    reaches mhi_device_get_sync() and schedule_timeout(), triggering a voluntary
    context switch within RCU.
    
    Call trace:
    rcu_note_context_switch+0x4c4/0x508 (P)
    __schedule+0xbc/0x1204
    schedule+0x34/0x110
    schedule_timeout+0x84/0x11c
    __mhi_device_get_sync+0x164/0x228 [mhi]
    mhi_device_get_sync+0x1c/0x3c [mhi]
    ath12k_wifi7_pci_bus_wake_up+0x20/0x2c [ath12k_wifi7]
    ath12k_pci_read32+0x58/0x350 [ath12k]
    ath12k_pci_clear_dbg_registers+0x28/0xb8 [ath12k]
    ath12k_pci_panic_handler+0x20/0x44 [ath12k] ath12k_core_panic_handler+0x28/0x3c [ath12k]
    notifier_call_chain+0x78/0x1c0
    atomic_notifier_call_chain+0x3c/0x5c
    
    Revert change "wifi: ath12k: add panic handler" to avoid this issue.
    
    Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
    
    Signed-off-by: Yingying Tang <[email protected]>
    Tested-by: Joonhoe Kim <[email protected]>
    Reviewed-by: Rameshkumar Sundaram <[email protected]>
    Fixes: 809055628bce ("wifi: ath12k: add panic handler")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jeff Johnson <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

Revert "wifi: libertas: reject short monitor TX frames" [+ + +]
Author: Johannes Berg <[email protected]>
Date:   Wed Oct 7 22:42:08 2026 +0200

    Revert "wifi: libertas: reject short monitor TX frames"
    
    commit 9727d1c4e1c971fc42b049b645fdda6852758835 upstream.
    
    This reverts commit 13ff543e0b2c713aedeaadadde686686e949dc78.
    
    The 'goto free' just made things worse, causing a spinlock
    to be handled incorrectly. Revert this for now.
    
    Reported-by: Takashi Iwai <[email protected]>
    Cc: [email protected]
    Fixes: 13ff543e0b2c ("wifi: libertas: reject short monitor TX frames")
    Signed-off-by: Johannes Berg <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp [+ + +]
Author: Ziyi Guo <[email protected]>
Date:   Thu Oct 1 13:57:11 2026 +0000

    riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
    
    commit 4d0697f192975dab5985e921989be1d85cf580e9 upstream.
    
    Under CONFIG_SHADOW_CALL_STACK, handle_exception() reloads the kernel
    shadow call stack pointer (gp) only when the trap came from userspace.
    It made that decision with scs_load_current_if_task_changed, which
    compares the trap-time tp (read back from sscratch into s5) against the
    current tp:
    
            beq     \prev, tp, _skip_scs
            scs_load_current
    _skip_scs:
    
    tp is a user-writable register.  A user task that sets tp to the
    linear-map address of its own task_struct (¤t) before trapping
    makes the comparison succeed (can achieve by brute force with KASLR
    enable under our test), so the kernel skips scs_load_current and
    keeps running with the gp that userspace left in place.  Under
    CONFIG_SHADOW_CALL_STACK gp is the shadow call stack pointer and
    load_global_pointer is a no-op, so the compiler-emitted
    "sd ra, -8(gp)" / "ld ra, -8(gp)" in every non-leaf function then write
    to, and return through, an attacker-controlled address -- an
    unprivileged kernel arbitrary-write and control-flow-hijack primitive.
    The poisoned gp is saved to task_struct.scs_sp on return, so the reload
    is skipped on every subsequent entry as well.
    
    Decide "came from userspace" from the hardware sstatus.SPP bit (already
    in s1 at this point) instead of from tp, mirroring the check that
    ret_from_exception already uses a few instructions later.  SPP is
    written by hardware on trap entry and cannot be forged from U-mode.
    Legitimate behaviour is unchanged: user entries (SPP=0) reload the task
    shadow call stack, nested kernel entries (SPP=1) skip it.
    
    Fixes: d1584d791a29 ("riscv: Implement Shadow Call Stack")
    Signed-off-by: Ziyi Guo <[email protected]>
    Reviewed-by: Sami Tolvanen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE [+ + +]
Author: Zongmin Zhou <[email protected]>
Date:   Thu Sep 17 15:48:43 2026 +0800

    riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE
    
    commit 298510bbc7c3017c0faf481c6ea66f1065b657b4 upstream.
    
    errata_probe_ghostwrite() only marks the CPU as vulnerable when it is
    called at the RISCV_ALTERNATIVES_EARLY_BOOT stage, and the mitigation
    in ghostwrite_enable_mitigation() only takes effect if the vulnerable
    state was recorded before the boot alternatives are patched.
    
    The early boot stage is only executed when CONFIG_RISCV_ALTERNATIVE_EARLY
    is enabled, which currently is only selected by ERRATA_THEAD_MAE. In a
    kernel built with ERRATA_THEAD_GHOSTWRITE=y but ERRATA_THEAD_MAE=n, the
    early alternatives never run, so ghostwrite_state is never set to
    VULNERABLE: ghostwrite_enable_mitigation() returns false, xtheadvector
    remains enabled, and sysfs reports "Not affected" on a vulnerable
    T-Head C9xx CPU.
    
    Select RISCV_ALTERNATIVE_EARLY from ERRATA_THEAD_GHOSTWRITE so that the
    vulnerability is detected in the early boot stage and the default
    mitigation is applied.
    
    Fixes: 4bf97069239b ("riscv: Add ghostwrite vulnerability")
    Signed-off-by: Zongmin Zhou <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: fix load_unaligned_zeropad() fixup for RV32 [+ + +]
Author: Karl Mehltretter <[email protected]>
Date:   Mon Sep 7 21:07:50 2026 +0200

    riscv: fix load_unaligned_zeropad() fixup for RV32
    
    commit d4f25b097e46d82718bb737d4540c99b7ab0a408 upstream.
    
    The fixup for load_unaligned_zeropad() runs when REG_L crosses into an
    unmapped page. REG_L is lw on RV32 and ld on RV64, but the fixup assumes
    an 8-byte load: it rounds the address down to 8 bytes and derives the
    shift from three address bits.
    
    On RV32, a load starting in the last three bytes of a mapped page selects
    the word four bytes earlier and shifts it by 40, 48, or 56 bits, more than
    the register width. The caller gets earlier bytes instead of the string
    tail followed by zeroes. This affects RV32 MMU kernels built with
    RISCV_EFFICIENT_UNALIGNED_ACCESS=y, which selects DCACHE_WORD_ACCESS
    and lets dcache name hashing and comparison and strscpy() use this
    path.
    
    Derive the alignment and offset masks from sizeof(data) instead of a fixed
    8. This makes RV32 use the correct source word. RV64 code is unchanged: the
    complete extable.o is byte-for-byte identical before and after.
    
    Fixes: d0fdc20b0429 ("riscv: select DCACHE_WORD_ACCESS for efficient unaligned access HW")
    Cc: [email protected]
    Assisted-by: LLM
    Signed-off-by: Karl Mehltretter <[email protected]>
    Reviewed-by: Jisheng Zhang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds [+ + +]
Author: Leo Yu-Chi Liang <[email protected]>
Date:   Tue Oct 6 21:52:29 2026 -0700

    riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds
    
    [ Upstream commit 07e23d0b6f58eec351e52058b9a0a8af7b019c09 ]
    
    rv32_defconfig is built in two stages:
    
    - the generic (64-bit-oriented) "defconfig" target runs first
      and resolves a concrete NR_CPUS value using the 64BIT default.
    - then 32-bit.config is merged on top via merge_config.sh,
      which does not touch NR_CPUS.
    
    The final "make olddefconfig" pass sees NR_CPUS=256 is still within
    the "2 512" range therefore never recalculates it against the 32BIT
    default of 32, silently keeping the leaked 64-bit-stage value.
    
    The NR_CPUS-scaled regions (percpu areas, ...etc) of the resulting
    CONFIG_NR_CPUS=256 on a 32-bit build bloats and does not fit in the
    percpu/stack layout for rv32 and hangs early boot on QEMU's virt machine.
    
    Fix this by explicitly specify the range for 32/64 and SBI_V01/!SBI_V01.
    
    Fixes: 0fa749771993 ("riscv: Raise default NR_CPUS for 64BIT to 256")
    Signed-off-by: Leo Yu-Chi Liang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

riscv: futex: untag the user pointer before the atomic access [+ + +]
Author: Ziyi Guo <[email protected]>
Date:   Tue Oct 6 14:02:00 2026 +0000

    riscv: futex: untag the user pointer before the atomic access
    
    commit 405290be962b32eec842776fbe3bdf81f15b1676 upstream.
    
    access_ok() checks untagged_addr(uaddr), but arch_futex_atomic_op_inuser()
    and futex_atomic_cmpxchg_inatomic() hand the raw uaddr to the inline asm
    amoswap/amoadd/.../lr.w+sc.w through the "+m" (*uaddr) operand.  When the
    tagged address ABI is enabled (CONFIG_RISCV_ISA_SUPM, prctl
    PR_SET_TAGGED_ADDR_CTRL with PMLEN != 0), those two addresses differ: a
    user pointer whose top PMLEN bits hold a tag passes access_ok() after
    untagging, but the atomic is then performed on the still-tagged raw
    address.
    
    Supervisor-mode data accesses are not subject to the U-mode pointer
    masking (that is governed by menvcfg.PMM, which the kernel does not set),
    so hardware does not strip the tag for the kernel's own access.  With
    Sv57 and PMLEN=16 the tag bits overlap the canonical-address bits, so a
    tagged pointer can name a canonical kernel virtual address (e.g. in the
    linear map) whose untagged form is a valid user address.  An unprivileged
    process can thus make FUTEX_WAKE_OP perform an atomic read-modify-write on
    an arbitrary kernel address, with the matching FUTEX_OP_CMP_* result
    serving as a read oracle.
    
    get_user()/put_user()/raw_copy_{to,from}_user() already untag the pointer
    after the access_ok() check; do the same in the futex helpers so the
    atomic operates on the address that was actually validated.
    
    Fixes: 2e1743085887 ("riscv: Add support for the tagged address ABI")
    Reviewed-by: Samuel Holland <[email protected]>
    Signed-off-by: Ziyi Guo <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header [+ + +]
Author: Zongmin Zhou <[email protected]>
Date:   Mon Oct 5 19:02:37 2026 -0600

    riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header
    
    commit edba6017c19f97ecc718fad6b50e0908392247ac upstream.
    
    BIT() is a kernel-internal macro that is not available to userspace, but
    the MIPS vendor extension uapi header uses it without defining or
    including it. Any userspace program that includes this header and uses
    RISCV_HWPROBE_VENDOR_EXT_XMIPSEXECTL fails to build.
    
    Use _BITULL(0) from linux/const.h instead, which keeps the value at 1,
    so there is no ABI change.
    
    Fixes: bb4b0f8a1bcb ("riscv: hwprobe: Add MIPS vendor extension probing")
    Cc: [email protected]
    Signed-off-by: Zongmin Zhou <[email protected]>
    Reviewed-by: Jesse Taube <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts [+ + +]
Author: Shao Mingyin <[email protected]>
Date:   Mon Oct 5 19:02:38 2026 -0600

    riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts
    
    commit 282f4a8aa95c5a01b96e55eb5da297560e5f2986 upstream.
    
    The aligned scan boundary is derived from the last valid byte,
    (s + count - 1).  When count is huge (e.g. SIZE_MAX, which FORTIFY
    strcat/strlcat pass when the destination size is not known at compile
    time), s + count wraps around and the boundary lands before s, so the
    ZBB path returns a bogus length.  The original implementation
    (5ba15d419fab) had the same wrap-around in its (s + count) & ~7
    boundary computation; after 5d588c684833 the wrapped boundary is caught
    by the pre-loop guard "bgeu t0, t4, 2f", which then always exits for
    aligned strings of 8 or more characters and strnlen() returns 8
    instead of the real length.
    
    This silently truncates strings built by fortified strcat: the dm
    sysfs name attribute shows "live-bas" instead of "live-base", the
    truncated name pollutes the udev database, and blivet/anaconda (as
    well as LVM/dm-crypt/multipath userspace) break on RISC-V systems.
    
    Detect the wrap-around and saturate the boundary to the top of the
    address space, making the scan equivalent to strlen().  The saturation
    clamps the increment to ~s, so it stays branchless and wrap-free:
    
            s + min(count - 1, ~s) == saturating_add(s, count - 1)
    
    Normal counts are unaffected.
    
    Fixes: 5ba15d419fab ("riscv: lib: add strnlen() implementation")
    Cc: [email protected]
    Suggested-by: David Laight <[email protected]>
    Suggested-by: Qingfang Deng <[email protected]>
    Signed-off-by: Shao Mingyin <[email protected]>
    Acked-by: Michael Neuling <[email protected]>
    Tested-by: Troy Mitchell <[email protected]>
    Reviewed-by: Aurelien Jarno <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: patch: fix handling of bpf-jit execmem addresses [+ + +]
Author: Wei-Jie Hung <[email protected]>
Date:   Mon Oct 5 19:02:38 2026 -0600

    riscv: patch: fix handling of bpf-jit execmem addresses
    
    commit a510e1ae8c9030750c2edf7b0bc9b186cd8c7a06 upstream.
    
    Commit 8718e5a3090b ("riscv: patch: skip fixmap mapping when kernel text
    is already writable") gated the core_kernel_text() branch of patch_map()
    on CONFIG_STRICT_KERNEL_RWX, and explicitly left the vmalloc branch
    unchanged. That branch has a separate problem.
    
    That branch only creates a temporary writable fixmap alias when
    CONFIG_STRICT_MODULE_RWX is enabled, and otherwise assumes the target is
    directly writable and returns the address unchanged. That assumption no
    longer holds: bpf_prog_pack_alloc calls set_memory_rox() on every pack
    unconditionally in alloc_new_pack(), independently of any
    CONFIG_STRICT_*_RWX option, so BPF text in the vmalloc area is read-only
    regardless of what CONFIG_STRICT_MODULE_RWX says.
    
    With CONFIG_STRICT_MODULE_RWX=n, patch_map() returns the read-only
    address directly, the subsequent copy_to_kernel_nofault() takes a
    page fault and returns -EFAULT. bpf_arch_text_copy() turns that into
    -EINVAL, which propagates through bpf_jit_binary_pack_finalize() to the
    WARN_ON() in bpf_int_jit_compile() and leaves the program un-JITed.
    
    Note that BPF cannot be fixed the way kprobes was in
    commit bdc46e507b59 ("riscv: mm: make EXECMEM_KPROBES writable without
    CONFIG_STRICT_MODULE_RWX"). EXECMEM_BPF is already PAGE_KERNEL, i.e.
    writable at allocation time; the read-only mapping is established
    afterwards by generic code in alloc_new_pack(), which arch code cannot
    influence. The only place this can be handled is patch_map().
    
    This is the same problem that was fixed on arm64 by commit b1480ed230ac
    ("arm64: patching: fix handling of execmem addresses"), and the fix is
    the same: CONFIG_EXECMEM is what actually tracks whether the vmalloc
    area can hold executable memory that needs a temporary alias to be
    written. CONFIG_BPF_JIT, CONFIG_KPROBES and CONFIG_MODULES all select
    it.
    
    Note that this is not limited to CONFIG_MODULES=n. Unlike arm64, riscv
    selects CONFIG_ARCH_OPTIONAL_KERNEL_RWX, so CONFIG_STRICT_MODULE_RWX can
    be disabled with CONFIG_MODULES=y as well, and the bug is reachable in
    that configuration too.
    
    The !CONFIG_MMU build is unaffected: it has its own __patch_insn_set()
    and __patch_insn_write() implementations and never calls patch_map().
    
    Fixes: 2c9e5d4a0082 ("bpf: remove CONFIG_BPF_JIT dependency on CONFIG_MODULES of")
    Signed-off-by: Wei-Jie Hung <[email protected]>
    Reviewed-by: Pu Lehui <[email protected]>
    Tested-by: Pu Lehui <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: ptrace: reject CFI regset access when extensions are absent [+ + +]
Author: Chen Pei <[email protected]>
Date:   Thu Aug 20 14:32:33 2026 +0800

    riscv: ptrace: reject CFI regset access when extensions are absent
    
    commit adadf6df0bd55aa40ccbc6519fb443133e103227 upstream.
    
    riscv_cfi_get() and riscv_cfi_set() do not check whether the Zicfilp
    or Zicfiss extensions are present. On systems without them,
    PTRACE_GETREGSET on REGSET_CFI still succeeds and returns a zeroed
    user_cfi_state, misleading debuggers into believing the register set
    is available, and PTRACE_SETREGSET silently accepts writes that have
    no effect (e.g. clearing SR_ELP).
    
    Reject the access with -EINVAL when neither branch landing pads nor
    shadow stack is available to userspace, using the same availability
    helpers as the prctl path.
    
    Fixes: 2af7c9cf021c ("riscv/ptrace: expose riscv CFI status and state via ptrace and in core files")
    Signed-off-by: Chen Pei <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Cc: [email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

riscv: ptrace: Zero-initialize regset buffers before copyin [+ + +]
Author: Zongmin Zhou <[email protected]>
Date:   Wed Aug 26 19:57:11 2026 +0800

    riscv: ptrace: Zero-initialize regset buffers before copyin
    
    [ Upstream commit 59052a88ba5fe4a7bb34b3a0a42aa5d453d3bb97 ]
    
    user_regset_copyin() only copies `count` bytes, so a PTRACE_SETREGSET
    request with a short iov_len leaves the rest of the stack buffer
    uninitialized. In riscv_vr_set() that garbage is validated and copied
    into the target's vstate, and in riscv_cfi_set() it can be stored as
    the target's shadow stack pointer. Zero both buffers, as the get path
    already does.
    
    Fixes: 9300f0043974 ("RISC-V: Add ptrace support for vectors")
    Fixes: 2af7c9cf021c ("riscv/ptrace: expose riscv CFI status and state via ptrace and in core files")
    Signed-off-by: Zongmin Zhou <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

riscv: vector: Fix data pointer constraints in context save/restore [+ + +]
Author: Troy Mitchell <[email protected]>
Date:   Mon Oct 5 19:02:37 2026 -0600

    riscv: vector: Fix data pointer constraints in context save/restore
    
    [ Upstream commit 572b25f3a6453d8e7fc28cc0cefe41ed15be166c ]
    
    The standard vector save/restore asm advances datap but declares it as
    input-only. An inlined caller reusing the original pointer may therefore
    use the advanced address instead.
    
    Declare datap as read-write so the compiler can preserve the original
    pointer when needed.
    
    Fixes: 03c3fcd9941a ("riscv: Introduce struct/helpers to save/restore per-task Vector state")
    Signed-off-by: Troy Mitchell <[email protected]>
    Reviewed-by: GUO Ren (XuanTie) <[email protected]>
    Reviewed-by: Aurelien Jarno <[email protected]>
    Reviewed-by: Andy Chiu <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

riscv: vector: Fix output operands in context save [+ + +]
Author: Aurelien Jarno <[email protected]>
Date:   Mon Oct 5 19:02:37 2026 -0600

    riscv: vector: Fix output operands in context save
    
    [ Upstream commit 55b1276ef9c1c27e8a2b2c5e8ef0515b5ad0332c ]
    
    The __vstate_csr_save() inline assembly declares vcsr as an output
    operand while the assembly only writes vstart, vtype, and vl. Remove it
    as it is later saved by the C code.
    
    Fixes: d863910eabaf ("riscv: vector: Support xtheadvector save/restore")
    Signed-off-by: Aurelien Jarno <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Paul Walmsley <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
rust_binder: reschedule node refcount update on thread exit [+ + +]
Author: Alice Ryhl <[email protected]>
Date:   Thu Sep 3 11:36:03 2026 +0000

    rust_binder: reschedule node refcount update on thread exit
    
    commit 2a74ccd1bcc170e66525f34e9de8652b57e2cf3d upstream.
    
    When a thread exits via BINDER_THREAD_EXIT, its pending work items are
    cancelled. If a thread exits while holding a pending node refcount
    increment (e.g. pushed as deferred work to that thread), the refcount
    increment was previously dropped because Node::cancel() and
    NodeWrapper::cancel() were no-ops.
    
    Dropping the refcount update leaves the node's delivery state and count
    state desynchronized, and userspace will not receive the notification,
    which can cause the node to never be freed from the process's nodes tree
    when all external references are dropped.
    
    Fix this by implementing DeliverToRead::cancel() for Node and NodeWrapper
    to move the pending refcount update to the process's work queue on thread
    exit so another thread can deliver it to userspace.
    
    Cc: stable <[email protected]>
    Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
    Signed-off-by: Alice Ryhl <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    [ Dropped first argument in calls to `push_work()` to adjust to the
      existing form without mainline commit dbb17c9ea756 ("rust_binder: move
      (e)poll wait queue to Process"). - Miguel ]
    Signed-off-by: Miguel Ojeda <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ [+ + +]
Author: Kuba Piecuch <[email protected]>
Date:   Wed Sep 30 14:23:58 2026 +0000

    sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ
    
    commit af701b8d3238b9eb7cd450b0491300452c700bf5 upstream.
    
    When a task in the BPF scheduler's custody is moved to another CPU's
    local DSQ, ops.dequeue() is only called once the task is picked for
    execution, from set_next_task_scx() with SCX_DEQ_CORE_SCHED_EXEC, even
    though no core-sched pick took place. It should instead be called
    without flags when the task is inserted into the destination DSQ, as it
    is for same-rq dispatches.
    
    move_remote_task_to_local_dsq() sets p->scx.sticky_cpu across the
    migration so that deactivate_task() on the source rq doesn't end custody.
    Since commit b75aaea24c9f ("sched_ext: Properly mark SCX-internal
    migrations via sticky_cpu"), enqueue_task_scx() only clears it after
    inserting the task, so task_leave_custody() still sees the migration in
    progress and skips the custody exit.
    
    Clear p->scx.sticky_cpu as soon as enqueue_task_scx() has read it, as
    was done before that commit. The source side is unaffected.
    
    Fixes: ebf1ccff79c4 ("sched_ext: Fix ops.dequeue() semantics")
    Cc: [email protected] # 7.1.x: 18d62044cda7: sched_ext: Preserve rq tracking across local DSQ dispatch
    Cc: [email protected] # 7.1.x
    Reviewed-by: Andrea Righi <[email protected]>
    Assisted-by: Claude:claude-opus-5.5
    Signed-off-by: Kuba Piecuch <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    (cherry picked from commit af701b8d3238b9eb7cd450b0491300452c700bf5)
    [ jpiecuch: resolved context conflict, 7.2.y still names the function
      do_enqueue_task() rather than scx_do_enqueue_task() ]
    Signed-off-by: Kuba Piecuch <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

sched_ext: Generate qseq from a per-task counter [+ + +]
Author: Kuba Piecuch <[email protected]>
Date:   Sat Oct 3 11:53:17 2026 +0000

    sched_ext: Generate qseq from a per-task counter
    
    commit e6ac89b8b1c12e9104df45a14a26e2dfa96ded06 upstream.
    
    finish_dispatch() uses the qseq embedded in p->scx.ops_state to tell
    whether the QUEUED instance of a task it's about to claim is the one
    scx_bpf_dsq_insert() saw. qseq is generated from rq->scx.ops_qseq, but
    the counters of different rqs are independent, so if a task is dequeued
    and re-enqueued on a different rq between scx_bpf_dsq_insert() and
    finish_dispatch(), the new QUEUED instance can end up with the same
    qseq as the old one:
    
      CPU X                          CPU Z
      -----                          -----
                                     enqueue p on rq A, qseq = N
      ops.dispatch()
        scx_bpf_dsq_insert(p)
          records qseq N
                                     sched_setaffinity(p)
                                       dequeue p from rq A
                                       enqueue p on rq B, qseq = N
      finish_dispatch(p, N)
        qseq matches, p is claimed
    
    The claim itself is still atomic so the core stays consistent, but an
    insert issued for a previous QUEUED instance gets applied to a new one
    which the BPF scheduler has just received through ops.enqueue(). This
    breaks the guarantee that dispatches targeting a stale instance are
    ignored.
    
    Generate qseq from a per-task counter, p->scx.ops_qseq, instead so that
    consecutive QUEUED instances of a task never share a qseq regardless of
    which rq they're on. The counter is only updated in
    scx_do_enqueue_task() with the task's rq locked, so no additional
    synchronization is needed, and it fits in an existing hole in struct
    sched_ext_entity on 64bit. Remove the now unused rq->scx.ops_qseq.
    
    Never generate qseq 0. NONE and DISPATCHING don't carry a qseq, so
    scx_bpf_dsq_insert() on a task in either state records 0. With a
    per-task counter, every task's first QUEUED instance would otherwise get
    qseq 0 and could be claimed by such an insert. Wrap the counter where
    the QSEQ field wraps so that it can't reach a value that shifts to 0 on
    32bit either.
    
    Fixes: f0e1a0643a59 ("sched_ext: Implement BPF extensible scheduler class")
    Cc: [email protected] # v6.12+
    Assisted-by: Claude:claude-opus-5.5
    Signed-off-by: Kuba Piecuch <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    [ jpiecuch: 7.2.y lacks runnable_cpu in sched_ext_entity, so ops_qseq goes
      after selected_cpu; adjust context in scx_rq and the dump_line() CPU line ]
    Signed-off-by: Kuba Piecuch <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
scsi: ch: Do not keep references to data transfer element devices [+ + +]
Author: Ahmed Abdelhaleem Ahmed <[email protected]>
Date:   Tue Sep 22 15:46:46 2026 +0000

    scsi: ch: Do not keep references to data transfer element devices
    
    commit 27c0f718d3b3c99e6d315308e95d987d0382a8a8 upstream.
    
    ch_readconfig() looks up the scsi_device of every data transfer element
    whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in
    ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops
    it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere
    else - it only supplies the vendor, model and revision printed in the same
    loop.
    
    Once such a drive is removed, its scsi_device can never be released. It
    stays on the host's device list at its address, so a new device there is
    refused by anything that walks the list - target_core_pscsi reports
    "scsi_device_get() failed for H:C:T:L" - and the low-level driver's module
    can no longer be unloaded. Only a reboot recovers.
    
    It shows with any changer that reports its drives' ids; with the mhvtl
    virtual library (IBM 3573-TL personality), each create and remove of a
    library with four drives leaves four references behind, counted by the
    module's use count in lsmod. With ch not bound the count is unchanged, and
    with this patch applied it is unchanged too.
    
    Drop the reference as soon as the name has been printed, and remove the now
    unused dt[] array. That also removes the array leaked when ch_probe() fails
    after ch_readconfig().
    
    The same leak was reported with an RFC patch in 2022, which was not merged.
    
    Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
    Cc: [email protected]
    Link: https://lore.kernel.org/linux-scsi/[email protected]/
    Signed-off-by: Ahmed Abdelhaleem Ahmed <[email protected]>
    Reviewed-by: Laurence Oberman <[email protected]>
    Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

scsi: qedi: Initialize callback state before registration [+ + +]
Author: Runyu Xiao <[email protected]>
Date:   Thu Sep 10 17:24:05 2026 +0800

    scsi: qedi: Initialize callback state before registration
    
    commit 85de8b3a5eaa23d153aff4c7c83dddbc949064c9 upstream.
    
    qedi_get_protocol_tlv_data() can be called asynchronously by QED after
    qedi_ops->register_ops(). It takes stats_lock and reads ll2_mtu, but
    __qedi_probe() currently registers the callback before initializing the
    mutex and assigning the default MTU on the normal probe path.
    
    Initialize the callback-visible state before registering qedi_cb_ops. Keep
    the recovery path from reinitializing state because it reuses the existing
    qedi context.
    
    Fixes: 3cc5746e5ad7 ("scsi: qedi: Initialize the stats mutex lock")
    Cc: [email protected]
    Assisted-by: LLM Codex
    Signed-off-by: Runyu Xiao <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock() [+ + +]
Author: Stanley Jhu <[email protected]>
Date:   Mon Sep 28 11:58:15 2026 +0800

    scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock()
    
    commit 375f3a5691dd46b5d05b90a8968872ec8b2248c5 upstream.
    
    During MCQ host reset, ufshcd_host_reset_and_restore() stops the host
    controller via ufshcd_hba_stop() (HCE = 0) before calling
    ufshcd_complete_requests(hba, true) ->
    ufshcd_mcq_compl_pending_transfer(hba, true) ->
    ufshcd_mcq_force_compl_one() -> ufshcd_mcq_compl_all_cqes_lock().  Because
    ufshcd_mcq_force_compl_one() is its sole caller,
    ufshcd_mcq_compl_all_cqes_lock() always runs with HCE = 0.
    
    Despite the comment above ufshcd_mcq_compl_all_cqes_lock() stating that
    reading CQTPy may not be safe with the controller disabled, the function
    still calls ufshcd_mcq_update_cq_tail_slot() at the end of its sweep:
    
     1. Unsafe CQTPy MMIO read:
        Calling ufshcd_mcq_update_cq_tail_slot() at the end of the sweep reads
        CQTPy over MMIO while HCE = 0, directly contradicting the function's
        documented contract (commit 1373df88d535 ("scsi: ufs: core: Add a
        comment block above ufshcd_mcq_compl_all_cqes_lock()")) that reading
        CQTPy may not be safe with the controller disabled.
    
     2. Spurious error logs on empty slots:
        Sweeping all max_entries slots visits empty entries where
        command_desc_base_addr is 0, causing ufshcd_mcq_process_cqe() to log
        unguarded dev_err(hba->dev, "Abnormal CQ entry!\n") messages.
    
    Fix both issues in ufshcd_mcq_compl_all_cqes_lock():
    
     - Remove the ufshcd_mcq_update_cq_tail_slot() call and the redundant
       hwq->cq_head_slot = hwq->cq_tail_slot assignment without replacement.
       The two indices are already equal after the sweep: they are equal when
       the sweep starts, since ufshcd_mcq_poll_cqe_lock() consumes entries
       until cq_head_slot reaches cq_tail_slot, and the sweep advances
       cq_head_slot by exactly one full ring. Both indices are also
       reinitialized before the queue is reused.
    
     - Extract ufshcd_mcq_compl_cqe() and invoke it only on non-empty slots
       during full-ring sweeps, keeping "Abnormal CQ entry!" logging strictly
       for unexpected empty entries in ufshcd_mcq_poll_cqe_lock().
    
    Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode")
    Cc: [email protected]
    Reviewed-by: Peter Wang <[email protected]>
    Signed-off-by: Stanley Jhu <[email protected]>
    Reviewed-by: Bart Van Assche <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ [+ + +]
Author: Stanley Jhu <[email protected]>
Date:   Mon Sep 28 11:58:16 2026 +0800

    scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ
    
    commit 469fa055664bfd8717b087a80d59c03055789c17 upstream.
    
    In MCQ mode, ufshcd_mcq_compl_pending_transfer() uses
    blk_mq_tagset_busy_iter() to iterate over busy requests during error
    recovery and host reset. However, both iterator callbacks perform
    whole-queue operations redundantly for each visited request:
    
     - force_compl == true: ufshcd_mcq_force_compl_one() calls
       ufshcd_mcq_compl_all_cqes_lock() on every busy request, sweeping the
       entire completion ring (hwq->max_entries slots) once per active request
       under spin_lock_irqsave even though the first sweep already cleared all
       completion entries.
    
     - force_compl == false: ufshcd_mcq_compl_one() acquires cq_lock and polls
       CQTPy over MMIO via ufshcd_mcq_poll_cqe_lock() for every busy request
       without doing any per-request work.
    
    Sweep or poll each hardware queue (hba->uhq[i]) once at the start of
    ufshcd_mcq_compl_pending_transfer(). When force_compl is true, run
    blk_mq_tagset_busy_iter() afterward to complete residual in-flight
    requests with DID_REQUEUE, and remove the now-unused
    ufshcd_mcq_compl_one() callback.
    
    Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode")
    Cc: [email protected]
    Reviewed-by: Bart Van Assche <[email protected]>
    Signed-off-by: Stanley Jhu <[email protected]>
    Reviewed-by: Peter Wang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

scsi: ufs: core: Hold a clock reference across the probe [+ + +]
Author: Naomi Chu <[email protected]>
Date:   Wed Sep 9 17:10:45 2026 +0800

    scsi: ufs: core: Hold a clock reference across the probe
    
    [ Upstream commit 02a3178319639f650428164d4d003de4dc03e326 ]
    
    Clock gating becomes possible as soon as ufshcd_init_clk_gating() has run,
    and from that point on the probe keeps accessing host registers without
    ever taking a clock reference. This has been safe only because of the state
    check in __ufshcd_release(): gate_work is not queued unless
    hba->ufshcd_state is UFSHCD_STATE_OPERATIONAL, and the promotion to that
    state used to happen after the last register access of the probe, at the
    end of ufshcd_probe_hba().
    
    That is fragile: it only works while the promotion happens after the
    register accesses. Commit a390e6677f41 ("scsi: ufs: core: Expand the
    ufshcd_device_init(hba, true) call") changed that ordering by moving the
    promotion into ufshcd_init(), which schedules ufshcd_async_scan()
    afterwards. ufshcd_probe_hba() therefore now runs with the state already
    promoted, and it accesses host registers without holding a clock reference:
    
     - On hosts with UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH it calls
       ufshcd_hba_stop() and ufshcd_hba_enable() before ufshcd_device_init()
       sets the state back to UFSHCD_STATE_RESET, and both read
       REG_CONTROLLER_ENABLE, so gated clocks stall there instead of just
       losing a write.
    
     - It ends with an ufshcd_configure_auto_hibern8() write, which its other
       callers do take a clock reference for.
    
    Take a clock reference as soon as clock gating has been initialised and
    keep it until the probe is over. It then does not matter who drops a clock
    reference while the probe is running, and the register accesses of the
    probe no longer depend on hba->ufshcd_state. The reference is dropped by
    ufshcd_async_scan() once the scan has finished, or by the new out_release
    label if the probe fails after it was taken.
    
    Fixes: a390e6677f41 ("scsi: ufs: core: Expand the ufshcd_device_init(hba, true) call")
    Signed-off-by: Naomi Chu <[email protected]>
    Reviewed-by: Peter Wang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

scsi: ufs: mediatek: Handle mPHY power-on failures [+ + +]
Author: Pengpeng Hou <[email protected]>
Date:   Sun Sep 20 11:49:53 2026 +0800

    scsi: ufs: mediatek: Handle mPHY power-on failures
    
    [ Upstream commit 78e04810542da416d3bead707b60cec773f1524d ]
    
    The MediaTek helper enables VA09 before powering on the mPHY, but ignores
    the PHY result. A failure can leave VA09 enabled and publish
    mphy_powered_on as true, so a later power-on attempt is skipped.
    
    Check phy_power_on(), attempt to unwind VA09 on failure, and leave the
    state flag unchanged. Propagate the helper result from host initialization
    as well as its existing resume caller. Keep the original PHY error if the
    supply rollback also fails, and report that rollback separately.
    
    The issue was found by our static-analysis tool.
    
    Fixes: 561e3a8726b2 ("scsi: ufs-mediatek: Fix unbalanced clock on/off")
    Fixes: cf137b3ea49a ("scsi: ufs-mediatek: Support VA09 regulator operations")
    Assisted-by: gpt 5
    Signed-off-by: Pengpeng Hou <[email protected]>
    Reviewed-by: Peter Wang <[email protected]>
    Reviewed-by: Stanley Jhu <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Martin K. Petersen (Oracle) <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute [+ + +]
Author: Hui Peng <[email protected]>
Date:   Wed Sep 30 04:46:11 2026 +0000

    sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute
    
    commit 538b529509c7ab0d909cb65bb7264edca1788d30 upstream.
    
    When an SCTP stream output extension structure (streamoute) has not yet
    been allocated, sctp_getsockopt_pr_streamstatus() sets the local stack
    variables params.sprstat_abandoned_unsent = 0 and
    params.sprstat_abandoned_sent = 0, but then immediately jumps to 'out:',
    bypassing copy_to_user(). As a result, when an uninitialized user buffer
    is passed to getsockopt(SCTP_PR_STREAM_STATUS), the kernel returns
    success (0) without copying the zeroed stats back to user space, leaving
    uninitialized data in the user buffer.
    
    Refactor the !streamoute check into an if-else chain so that when
    streamoute is NULL, params is zeroed and falls through to copy_to_user(),
    copying the zeroed stats to user space and setting retval = 0 once before
    returning.
    
    Tested in QEMU against Linux 7.3.0-rc3 using an uninitialized
    sctp_prstatus user struct passed to getsockopt(SCTP_PR_STREAM_STATUS) on a
    freshly created stream: on the unfixed kernel the user struct contains
    uninitialized stack garbage; whereas with this fix applied, getsockopt()
    copies zeroed stats into user space and returns 0.
    
    Cc: [email protected]
    Reviewed-by: Xin Long <[email protected]>
    Signed-off-by: Hui Peng <[email protected]>
    Fixes: f952be79cebd ("sctp: introduce struct sctp_stream_out_ext")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
selftests/mm: cleanup -Wformat issues in hugetlb-mmap [+ + +]
Author: Carlos Llamas <[email protected]>
Date:   Sun Sep 27 16:24:18 2026 +0000

    selftests/mm: cleanup -Wformat issues in hugetlb-mmap
    
    commit 28eed9906e01d01cbdfb352e799413b2e8b33b76 upstream.
    
    Commit ae571cd6015c ("selftests/mm: hugetlb-mmap: add setup of HugeTLB
    pages") and commit 9c5a65f374f8 ("selftests/mm: merge map_hugetlb into
    hugepage-mmap") added logs of 'hugepage_size' which has a size_t type.
    However, the incorrect format specifier '%lu' was used which triggers
    -Wformat warnings when building for 32-bit:
    
      hugetlb-mmap.c:125:55: warning: format specifies type 'unsigned long'
      but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
        125 | ksft_print_msg("Default size hugepages (%lu kB)\n", hugepage_size >> 10);
            |                                         ~~~         ^~~~~~~~~~~~~~~~~~~
            |                                         %zu
    
      hugetlb-mmap.c:134:47: warning: format specifies type 'unsigned long'
      but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
        134 | ksft_exit_skip("Not enough %lu Kb pages\n", hugepage_size >> 10);
            |                            ~~~              ^~~~~~~~~~~~~~~~~~~
            |                            %zu
    
    Fix this by switching to the expected '%zu' format specifier.
    
    Link: https://lore.kernel.org/[email protected]
    Fixes: ae571cd6015c ("selftests/mm: hugetlb-mmap: add setup of HugeTLB pages")
    Fixes: 9c5a65f374f8 ("selftests/mm: merge map_hugetlb into hugepage-mmap")
    Signed-off-by: Carlos Llamas <[email protected]>
    Signed-off-by: Andrew Morton <[email protected]>
    Reviewed-by: Sarthak Sharma <[email protected]>
    Reviewed-by: SJ Park <[email protected]>
    Acked-by: Lorenzo Stoakes (ARM) <[email protected]>
    Cc: Mike Rapoport <[email protected]>
    Cc: David Hildenbrand <[email protected]>
    Cc: Liam R. Howlett <[email protected]>
    Cc: Vlastimil Babka <[email protected]>
    Cc: Suren Baghdasaryan <[email protected]>
    Cc: Michal Hocko <[email protected]>
    Cc: Shuah Khan <[email protected]>
    Cc: <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
selinux: fix data race on AVC latest_notif [+ + +]
Author: Christian Göttsche <[email protected]>
Date:   Wed Sep 23 12:13:23 2026 +0200

    selinux: fix data race on AVC latest_notif
    
    commit 1ca924044bf0de879a1648be93a56939652267d3 upstream.
    
    avc_policy_seqno() reads latest_notif without holding notif_lock, while
    avc_latest_notif_update() can update it under that lock. KCSAN reports
    these concurrent accesses during policy boolean updates and permission
    checks.
    
    Use READ_ONCE() for the lockless read and WRITE_ONCE() for the update.
    The spinlock continues to serialize the comparison and update against
    other writers. Reads made while holding notif_lock cannot race with a
    writer and can remain plain accesses.
    
    This marks both sides of the intentional concurrent access and constrains
    compiler transformations, without suppressing checking with data_race().
    
    Cc: [email protected]
    Fixes: 788e7dd4c22e ("SELinux: Improve read/write performance")
    Reported-by: [email protected]
    Closes: https://syzkaller.appspot.com/bug?extid=a7f7cb0737bd91aa698c
    Signed-off-by: Christian Göttsche <[email protected]>
    Acked-by: Stephen Smalley <[email protected]>
    Signed-off-by: Paul Moore <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts [+ + +]
Author: Stephen Smalley <[email protected]>
Date:   Mon Sep 28 10:19:17 2026 -0400

    selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts
    
    commit 28b7260548af3d35773477993ad4e4de41578dd7 upstream.
    
    When an NFSv4 filesystem exported with security_label is mounted a
    second time, sget_fc() returns the existing superblock and
    nfs_get_root() calls security_sb_set_mnt_opts() again on it. Since the
    superblock is already SB_INITIALIZED, selinux_set_mnt_opts() takes an
    early exit without setting SECURITY_LSM_NATIVE_LABELS in
    *set_kern_flags. nfs_get_root() then sees kflags without
    SECURITY_LSM_NATIVE_LABELS set and clears NFS_CAP_SECURITY_LABEL on
    the shared nfs_server, silently disabling per-file labeling for both
    the new and the original mount.
    
    Commit 3815a245b501 ("security/selinux: fix SECURITY_LSM_NATIVE_LABELS
    on reused superblock") fixed the same problem in
    selinux_sb_clone_mnt_opts().  The reused-superblock path for a plain
    second mount now goes through sb_set_mnt_opts rather than
    sb_clone_mnt_opts, so it needs the same treatment: on both
    SE_SBINITIALIZED early exits, set SECURITY_LSM_NATIVE_LABELS in
    *set_kern_flags when the superblock was already using
    SECURITY_FS_USE_NATVE.
    
    Cc: [email protected]
    Closes: https://github.com/SELinuxProject/selinux-kernel/issues/69
    Closes: https://github.com/SELinuxProject/selinux-kernel/issues/70
    Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/91
    Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/92
    Fixes: eb9ae686507b ("SELinux: Add new labeling type native labels")
    Signed-off-by: Stephen Smalley <[email protected]>
    Signed-off-by: Paul Moore <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
spi: sg2044-nor: Honor SPI clock limits [+ + +]
Author: Han Gao <[email protected]>
Date:   Thu Oct 1 02:22:51 2026 +0800

    spi: sg2044-nor: Honor SPI clock limits
    
    [ Upstream commit 61d44a2c07b2ad3f7db167f17ff2461ffe78441c ]
    
    The fixed divider ignores device and operation clock limits. Calculate
    the divider before each transfer so SCK does not exceed either limit.
    
    Advertise the controller maximum speed so the SPI core supplies a default
    when the device omits its maximum speed. Use the fastest divider when no
    speed limit is supplied.
    
    Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
    Signed-off-by: Han Gao <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

spi: sg2044-nor: Return transfer errors [+ + +]
Author: Han Gao <[email protected]>
Date:   Thu Oct 1 02:22:50 2026 +0800

    spi: sg2044-nor: Return transfer errors
    
    [ Upstream commit e130c54fbb603f9aeacf5029789b4a2c8c48f416 ]
    
    The transfer helpers return errors, but both dispatchers discard them.
    Return these errors to the SPI memory layer instead of reporting success.
    
    Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
    Signed-off-by: Han Gao <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock [+ + +]
Author: Haibo Chen <[email protected]>
Date:   Mon Sep 28 19:53:11 2026 +0800

    spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock
    
    [ Upstream commit 94b6df050433875f493fb8298b58d7b0dc32eb9c ]
    
    For 8D-8D-8D (octal DTR) mode the FlexSPI samples read data using
    MCR0[RXCLKSRC] = 3 (flash-memory-provided read strobe on the DQS pad),
    which requires the DLL to be locked. Per the i.MX95 Reference Manual
    (FlexSPI chapter, "DLL configuration for sampling"), when the serial
    root clock is above 100 MHz the DLL is enabled (DLLxCR[DLLEN] = 1,
    OVRDEN = 0) and software must then wait for STS2[xREFLOCK] and
    STS2[xSLVLOCK] to be asserted before starting a read or write. This DLL
    lock is relative to the serial root clock.
    
    While the module is in stop mode (MCR0[MDIS] = 1) the AHB and serial
    clocks are gated off internally, so the serial root clock the DLL locks
    against is not running. nxp_fspi_dll_calibration() both programs DLLxCR
    and then polls STS2 for lock. When it runs entirely in stop mode the
    STS2 REF/SLV lock bits never assert (observed as "DLL lock failed" with
    STS2 = 0).
    
    The MCR0 bit fields (RXCLKSRC) and the serial root clock rate still have
    to be reconfigured in stop mode, so keep entering stop mode around that.
    Only move the exit from stop mode (clearing MCR0[MDIS]) ahead of the DLL
    calibration/override step, so that the serial root clock is running when
    the DLL is calibrated and STS2 can report lock.
    
    Fixes: b4bde5cfff8e ("spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL")
    Signed-off-by: Haibo Chen <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Mark Brown <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
statmount: read the parent of an unmounted mount under mount_lock [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Sat Sep 26 15:44:25 2026 +0200

    statmount: read the parent of an unmounted mount under mount_lock
    
    commit bb46094057520304073130920c223451c2a694a7 upstream.
    
    statmount_mnt_basic() reads the ids of the parent through m->mnt_parent
    with namespace_sem held for reading. That's fine for a mount that is
    in a namespace. Everything above it is pinned by that namespace.
    
    STATMOUNT_BY_FD also accepts a file descriptor on a mount that has
    been unmounted on purpose and that only the file descriptor keeps alive.
    If that mount stayed attached to its parent when it was unmounted the
    parent is unmounted as well and nothing pins it for the child.
    
    The final mntput() unmounts the children under mount_lock alone and
    frees the parent afterwards. Concurrently, statmount_mnt_basic() reads
    m->mnt_parent twice while that can happen and can easily dereference a
    mount that's already gone.
    
    Read the parent of an unmounted mount under mount_lock. The parent
    can't be put while it is held and both ids come from the same mount. A
    mounted mount's parent is pinned by the namespace and a mount can't
    leave its namespace while namespace_sem is held, so the common case
    takes no global lock.
    
    Fixes: 0e5032237ee5 ("statmount: accept fd as a parameter")
    Cc: [email protected] # v7.0+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
strparser: make sure __strp_recv isn't running before tearing down the parser [+ + +]
Author: Sabrina Dubroca <[email protected]>
Date:   Mon Oct 5 15:50:02 2026 +0200

    strparser: make sure __strp_recv isn't running before tearing down the parser
    
    commit 0984ebc631792acf8fff105112ee74a6b8f1efcc upstream.
    
    The comment above strp_done() claims that if strp is stopped,
    strp_recv will no longer be called. That's only true if the caller has
    a mechanism (eg locking) to guarantee that strp_recv() calls that
    started before strp_stop() have completed by the time we call
    strp_done().
    
    This adds a dummy lock_sock/release_sock pair to guarantee that any
    in-flight strp_recv() (which runs under either bh_lock_sock or
    lock_sock, depending if it's called from ->sk_data_ready or strp_work)
    has completed.
    
    Only espintcp can be affected by this race condition, but this patch
    makes sure no future user of strp can have the bug.
    
    This could crash on strp->sk ("general mode" of strp), but this mode
    has been here for 9 years and has never been used. It'll be gone soon,
    no point worrying about it.
    
    Switch the stopped/paused/etc bits to u8's to avoid races between
    strp_stop() and strp_pause/unpause().
    
    A reproducer has been published and turns the possible UAF into an
    exploit [1].
    
    Reported-by: Hyunwoo Kim <[email protected]>
    Link: https://lore.kernel.org/all/aZLn2Faeg1FB7XOf@v4bel/
    Link: https://lore.kernel.org/all/aZgpkyTDU3aXe_V0@v4bel/
    Link: https://github.com/m0x41nos/RustyTux [1]
    Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
    Cc: [email protected]
    Signed-off-by: Sabrina Dubroca <[email protected]>
    Reviewed-by: Hyunwoo Kim <[email protected]>
    Link: https://patch.msgid.link/425d9d926709b542ed5331110c19fee4aee1f28d.1791206940.git.sd@queasysnail.net
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
swiotlb: fix default_swiotlb_limit() for non-growable default pool [+ + +]
Author: Marek Szyprowski <[email protected]>
Date:   Wed Sep 30 10:50:55 2026 +0200

    swiotlb: fix default_swiotlb_limit() for non-growable default pool
    
    commit 911655ab1dfb9d526978a75df3b210132620d30a upstream.
    
    Commit ad96ce3252db ("swiotlb: determine potential physical address
    limit") changed default_swiotlb_limit() to return the maximum physical
    address that could ever be used by dynamically allocated pools, so that
    the value stays constant when CONFIG_SWIOTLB_DYNAMIC=y. However,
    io_tlb_default_mem.phys_limit is returned even when the default pool
    cannot grow, e.g. when swiotlb_init_remap() is called with a remap
    callback.
    
    This breaks Xen dom0 on x86: pci_xen_swiotlb_init() passes SWIOTLB_ANY
    and xen_swiotlb_fixup(), so phys_limit is set to the top of dom0 memory,
    although xen_swiotlb_fixup() makes the default pool below the 32-bit
    boundary. xen_swiotlb_dma_supported() then rejects 32-bit DMA masks,
    even though the bounce buffer is perfectly usable by such devices.
    
    Return phys_limit only if the default pool can actually grow, otherwise
    report the real end of the default pool, like in the
    !CONFIG_SWIOTLB_DYNAMIC case.
    
    Reported-by: Andreas Greve <[email protected]>
    Reported-by: James Dingwall <[email protected]>
    Fixes: ad96ce3252db ("swiotlb: determine potential physical address limit")
    Closes: https://lore.kernel.org/xen-devel/[email protected]/
    Cc: [email protected]
    Assisted-by: Claude Opus 5.5 (1M context) <[email protected]>
    Tested-by: James Dingwall <[email protected]>
    Link: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Marek Szyprowski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
tcp: reject net_iov in zerocopy receive mapping hints [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Wed Sep 30 19:25:24 2026 +0900

    tcp: reject net_iov in zerocopy receive mapping hints
    
    commit 8b1f0af1fd5fd113432233ed8a3862ee7c30a84f upstream.
    
    After copying a readable prefix, receive_fallback_to_copy() asks
    tcp_zerocopy_set_hint_for_skb() where page mapping can resume. If the
    next skb is unreadable, find_next_mappable_frag() passes its net_iov
    fragment to can_map_frag().
    
    skb_frag_page() returns NULL for a net_iov, but can_map_frag()
    dereferences it in PageCompound(). A v7.2 KASAN run on a connected TCP
    socket with 64 readable bytes followed by a 4096-byte NET_IOV_DMABUF
    fragment reported:
    
      BUG: KASAN: null-ptr-deref in can_map_frag
      tcp_zerocopy_receive -> can_map_frag
      Kernel panic - not syncing: KASAN: panic_on_warn set
    
    The diagnostic inserted the net_iov directly because the test host has
    no devmem-capable NIC. Hardware end-to-end reachability remains untested
    and requires CONFIG_NET_DEVMEM plus a supported DMA-buf-bound RX queue.
    
    Reject all net_iov fragments before skb_frag_page(). This covers both
    DMABUF and IOURING net_iov types while leaving page-backed checks
    unchanged. With the guard, the same queue copied the readable prefix,
    returned a 4096-byte skip hint, and completed without a fault.
    
    Fixes: 9f6b619edf2e ("net: support non paged skb frags")
    Cc: [email protected]
    Signed-off-by: Daehyeon Ko <[email protected]>
    Reviewed-by: Mina Almasry <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
tee: optee: ffa: support shared memory offsets on large-page kernels [+ + +]
Author: Mahantesh Salimath <[email protected]>
Date:   Thu Sep 10 16:11:24 2026 +0000

    tee: optee: ffa: support shared memory offsets on large-page kernels
    
    [ Upstream commit 3c0d2f1f431c51a11253f28763be723ac782fd7a ]
    
    OP-TEE FF-A memory objects use 4 KiB pages, while the kernel page
    size may be larger. Consequently, tee_shm->offset can be greater than
    or equal to FFA_PAGE_SIZE, but OP-TEE rejects such a value in
    internal_offs.
    
    Do not encode the excess page offset in offs_low/offs_high. Those
    fields describe the logical memref offset and are copied back into
    tee_param->shm_offs on return. Folding the page offset into them breaks
    parameter round trips when a memref is reused. They are also ignored by
    the OPTEE_RPC_CMD_SHM_ALLOC response path, which uses only global_id and
    internal_offs to construct the shared-memory mobj.
    
    Instead, start the FF-A descriptor at the 4 KiB page containing the
    shared buffer, the same approach as optee_fill_pages_list() in the SMC
    ABI. Store the remaining in-page offset in internal_offs and preserve
    shm_offs in offs_low/offs_high. This keeps internal_offs within the
    FF-A page size, maps RPC allocations at the correct address, and
    preserves normal memref offsets across repeated invocations.
    
    Tested on ARMv8-A with 64 KiB PAGE_SIZE. OP-TEE OS ran as a secure
    partition under Hafnium (SPMC) over FF-A. Verified registered shared
    memory with tee_shm->offset >= 4 KiB, memref reuse on the same
    TEEC_Operation, and RPC OPTEE_RPC_CMD_SHM_ALLOC (xtest regression
    6007-6009). optee_hello_world, optee_aes, and xtest regression 1005,
    1007, 1008, 4001-4003 and 6001-6003 also passed.
    
    Fixes: 4615e5a34b95 ("optee: add FF-A support")
    Acked-by: Liming Sun <[email protected]>
    Acked-by: James Hurley <[email protected]>
    Acked-by: Dave Thompson <[email protected]>
    Signed-off-by: Mahantesh Salimath <[email protected]>
    Reviewed-by: Sumit Garg <[email protected]>
    Signed-off-by: Jens Wiklander <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper() [+ + +]
Author: Georgiy Osokin <[email protected]>
Date:   Mon Sep 28 17:31:13 2026 +0300

    tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper()
    
    commit b7f925fd5226deb953c8dcdc9677d3fcc2717c00 upstream.
    
    tee_dyn_shm_alloc_helper() derives nr_pages from a caller-supplied size
    and passes it to alloc_pages_exact() without checking it. For size == 0
    nr_pages is 0, and alloc_pages_exact(0) calls get_order(0), which is
    documented as undefined and returns BITS_PER_LONG - PAGE_SHIFT. The page
    allocator then trips its order > MAX_PAGE_ORDER warning and fails the
    allocation; on a panic_on_warn kernel that ends the boot.
    
    This can be triggered by TEE_IOC_SHM_ALLOC with struct
    tee_ioctl_shm_alloc_data where size is 0.
    
    Reject a zero page count, as register_shm_helper() already does for the
    register path.
    
    Fixes: cf4441503e20 ("tee: optee: Move pool_op helper functions")
    Cc: [email protected]
    Cc: [email protected]
    Signed-off-by: Georgiy Osokin <[email protected]>
    Reviewed-by: Sumit Garg <[email protected]>
    Signed-off-by: Jens Wiklander <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
tipc: destroy topsrv workqueues before closing connections [+ + +]
Author: Yuqi Xu <[email protected]>
Date:   Mon Sep 28 16:24:38 2026 +0800

    tipc: destroy topsrv workqueues before closing connections
    
    commit 3acdd44385bc7e2e57605e073691ce69cc5a960d upstream.
    
    tipc_topsrv_stop() closed subscriber connections while the topology
    server's send and receive workqueues were still running. Socket
    callbacks and subscription events could then queue more work, and
    in-flight send/recv work could drop the last connection reference
    during the conn_idr walk.
    
    That race produced several teardown failures: refcount_t addition on
    0 from conn_get() on a connection whose release was blocked on
    idr_lock, a subsequent use-after-free in tipc_conn_close(),
    queue_work() on an already destroyed workqueue from the listener
    data-ready callback, and an RCU stall in tipc_topsrv_exit_net()
    while the walk spun under idr_lock.
    
    Clear srv->listener under idr_lock so it acts as a shutdown flag,
    skip queue_work() once it is NULL, destroy the workqueues to flush
    in-flight work, and only then close the remaining connections.
    Refuse tipc_conn_lookup() after that flag is cleared, and drop
    idr_lock when the teardown walk finds no connection, so an
    in-flight subscription event cannot pin idr_in_use while the
    walk holds the lock.
    
    v3 supersedes the narrower in-thread diff Tung Quang Nguyen
    posted on 2026-09-23. It keeps his teardown order and adds the
    lookup refusal and the empty-idr unlock.
    
    Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
    Cc: [email protected]
    Reported-by: Vega <[email protected]>
    Assisted-by: LLM
    Signed-off-by: Yuqi Xu <[email protected]>
    Reviewed-by: Ren Wei <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

tipc: hold a reference to nodes found by link name [+ + +]
Author: Chengfeng Ye <[email protected]>
Date:   Tue Sep 29 00:12:46 2026 +0800

    tipc: hold a reference to nodes found by link name
    
    commit 17e73bae400f6a434dc006e3bee92c94cf781954 upstream.
    
    tipc_node_find_by_name() returns a node after dropping its RCU read lock
    without taking a reference.  The LINK_SET, LINK_GET and LINK_RESET_STATS
    handlers then lock and access the node, racing with timer-driven cleanup of
    a down peer.  Generic netlink serialization does not exclude the node
    timer.
    
    The following interleaving can leave a handler using a freed node:
    
      CPU 0: find the node under RCU and release the node read lock
      CPU 1: tipc_node_timeout() clears the links and unlinks the down node
      CPU 1: drop the list and timer references, queuing tipc_node_free()
      CPU 0: leave the RCU read-side critical section
      CPU 1: complete the grace period and free the node
      CPU 0: acquire the node lock through the stale pointer
    
    LINK_SET also uses the node's media address after releasing the node lock,
    when passing queued packets to tipc_bearer_xmit().
    
    KASAN on v7.3-rc5 reported:
    
      BUG: KASAN: slab-use-after-free in _raw_read_lock_bh
      Write of size 4 at addr ffff88807e06f008 by task poc/92
      Call Trace:
       _raw_read_lock_bh                 kernel/locking/spinlock.c:287
       tipc_nl_node_set_link             net/tipc/node.c:2475
       genl_family_rcv_msg_doit          net/netlink/genetlink.c:1114
       genl_rcv_msg                      net/netlink/genetlink.c:1209
       netlink_rcv_skb                   net/netlink/af_netlink.c:2575
    
      Allocated by task 0:
       tipc_node_create                  net/tipc/node.c:539
       tipc_node_check_dest              net/tipc/node.c:1196
       tipc_disc_rcv                     net/tipc/discover.c:252
    
      Freed by task 92:
       kfree                             mm/slub.c:6801
       rcu_core                          kernel/rcu/tree.c:2919
    
      Last potentially related work creation:
       __call_rcu_common.constprop.0     kernel/rcu/tree.c:3181
       tipc_node_timeout                 net/tipc/node.c:814
    
    Acquire a reference to the selected node with kref_get_unless_zero() before
    leaving RCU, returning NULL if the node has already been released.  Release
    that reference on every caller exit after the last node access, including
    transmission in LINK_SET.  Keep the existing link lookup order and locking
    so concurrent link removal still takes the existing error paths.
    
    Fixes: 6a939f365bdb ("tipc: Auto removal of peer down node instance")
    Cc: [email protected]
    Signed-off-by: Chengfeng Ye <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
unshare: don't drop active namespace references that were never taken [+ + +]
Author: Christian Brauner <[email protected]>
Date:   Wed Sep 30 15:32:08 2026 +0200

    unshare: don't drop active namespace references that were never taken
    
    commit 0b6f31a3c0b16066f812e94b52a704174a6f23cd upstream.
    
    Active references on the namespaces of an nsproxy are taken when the
    nsproxy is installed into a task in switch_task_namespaces() and
    copy_namespaces() and dropped again by put_nsproxy() through
    deactivate_nsproxy().
    
    But ksys_unshare() calls put_nsproxy() on an nsproxy that was never
    installed when set_cred_ucounts() fails. The new namespaces of that
    nsproxy go from zero to minus one and the namespaces shared with the
    caller lose a reference that belongs to the nsproxy the caller keeps
    using:
    
      WARNING: kernel/nscommon.c:171 at __ns_ref_active_put+0x1cd/0x230
       nsproxy_ns_active_put
       deactivate_nsproxy
       ksys_unshare
    
    Afterwards the namespaces the caller lives in aren't listed by listns()
    anymore. set_cred_ucounts() only fails when alloc_ucounts() can't
    allocate and it only allocates when the real uid of the caller differs
    from its effective uid.
    
    Commit cefd55bd2159 ("nsproxy: fix free_nsproxy() and simplify
    create_new_namespaces()") separated the two cases on purpose.
    nsproxy_free() frees an nsproxy that was prepared but never installed
    and that's what a failed setns() uses in put_nsset(). Export it and use
    it for a failed unshare() as well.
    
    Fixes: a98621a0f187 ("unshare: fix nsproxy leak in ksys_unshare() on set_cred_ucounts() failure")
    Cc: [email protected] # v7.1+
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Christian Brauner (Amutable) <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
usb: f81604: fix struct f81604_int_data size mismatch [+ + +]
Author: Ji-Ze Hong (Peter Hong) <[email protected]>
Date:   Mon Aug 24 21:18:14 2026 +0800

    usb: f81604: fix struct f81604_int_data size mismatch
    
    commit 7f85d1170575645f9f327062d78017a23b2714eb upstream.
    
    The struct f81604_int_data defines 9 bytes of interrupt data:
    - Byte 0: Status register (sr)
    - Byte 1: Interrupt register (isrc)
    - Byte 2: Interrupt enable register (ier)
    - Byte 3: Arbitration lost capture (alc)
    - Byte 4: Error code capture (ecc)
    - Byte 5: Error warning limit register (ewlr)
    - Byte 6: RX error counter (rxerr)
    - Byte 7: TX error counter (txerr)
    - Byte 8: Reserved (val)
    
    The hardware sends exactly 9 bytes for the interrupt endpoint.
    However, the struct was defined with __aligned(4) attribute which
    caused the compiler to pad the struct to 12 bytes.
    
    This causes a problem in f81604_read_int_callback() where the short
    URB check compares urb->actual_length against sizeof(*data). When
    sizeof(struct f81604_int_data) is 12 but the hardware only sends 9
    bytes, the check fails and valid interrupt messages are discarded.
    
    This results in the driver only being able to transmit once because
    the TX complete interrupt is never processed.
    
    Fix this by removing the __aligned(4) attribute so the struct size
    matches the actual hardware data size of 9 bytes.
    
    Fixes: 7299b1b39a25 ("can: usb: f81604: handle short interrupt urb messages properly")
    Cc: [email protected]
    Reported-by: Dynetrex, Admin <[email protected]>
    Closes: https://lore.kernel.org/all/[email protected]/
    Signed-off-by: Ji-Ze Hong (Peter Hong) <[email protected]>
    Acked-by: Greg Kroah-Hartman <[email protected]>
    Tested-by: Drew Willey <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Marc Kleine-Budde <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down [+ + +]
Author: Tianyi Gao <[email protected]>
Date:   Tue Oct 6 18:32:36 2026 +0100

    veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down
    
    [ Upstream commit 3f090039995f609a8e236f37980dee5712dded61 ]
    
    A veth device advertises NETDEV_XDP_ACT_NDO_XMIT only if its peer has an
    XDP program attached or GRO enabled, that is, only if the peer will have
    NAPI to receive the frames.
    
    veth_set_features() updates the peer's flag when GRO is toggled, but
    returns early if the device is down, and veth_open() only refreshes the
    flags of the device being opened. Toggling GRO while the device is down
    therefore leaves the peer's flag stale after the device comes up.
    
    If GRO was enabled while down, the device comes up with NAPI but the
    peer does not advertise NDO_XMIT, and devmap rejects redirects to the
    peer with -EOPNOTSUPP. If GRO was disabled while down, the device comes
    up without NAPI but the peer still advertises NDO_XMIT, so redirects are
    accepted and then dropped in veth_xdp_xmit() with -ENXIO.
    
    Commit 7a6102aa6df0 ("veth: Update XDP feature set when bringing up
    device") made veth_open() refresh the device's own flags. Refresh the
    peer's flags there too. The peer's flag depends on this device's XDP
    program and GRO setting, not on whether the peer is up, so it is
    correct to set it even if the peer is down.
    
    Fixes: 8267fc71abb2 ("veth: take into account peer device for NETDEV_XDP_ACT_NDO_XMIT xdp_features flag")
    Signed-off-by: Tianyi Gao <[email protected]>
    Reviewed-by: Toke Høiland-Jørgensen <[email protected]>
    Acked-by: Jesper Dangaard Brouer <[email protected]>
    Acked-by: Lorenzo Bianconi <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
vsock/virtio: account only unread bytes in read_skb() [+ + +]
Author: Daehyeon Ko <[email protected]>
Date:   Fri Oct 2 00:13:10 2026 +0900

    vsock/virtio: account only unread bytes in read_skb()
    
    commit a463f55c791b96cfd12df8b10ea737d45c80bb18 upstream.
    
    After a partial stream receive, rx_bytes tracks the unread suffix while
    buf_used and peer credit still cover the whole packet.
    virtio_transport_read_skb() dequeues that packet but passes pkt_len for
    both counters, underflowing rx_bytes.
    
    On a connected CID_LOCAL stream with an SK_SKB verdict, a 40-byte read
    from a 100-byte packet made SIOCINQ report -40, an empty recv return
    ELOOP, and poll report the empty socket readable.  After verdict detach,
    receiving 40 bytes wrapped the counter to zero and hid those queued bytes
    until one more byte arrived.  The fixed run kept the counter balanced
    and exposed all queued data immediately.
    
    This was found during an LLM-assisted manual source audit of VSOCK
    receive accounting while re-evaluating virtio_transport_read_skb() after
    CVE-2024-50169.
    
    Subtract only skb->len minus the VSOCK offset from rx_bytes.  Retain the
    full packet length for buf_used and peer credit.
    
    Fixes: 45ca7e9f0730 ("vsock/virtio: fix `rx_bytes` accounting for stream sockets")
    Cc: [email protected]
    Reviewed-by: Luigi Leonardi <[email protected]>
    Signed-off-by: Daehyeon Ko <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
vsock: Fix memory leak in vmci_transport_recv_dgram_cb() [+ + +]
Author: Ilia Gavrilov <[email protected]>
Date:   Thu Oct 8 14:41:17 2026 +0000

    vsock: Fix memory leak in vmci_transport_recv_dgram_cb()
    
    [ Upstream commit 7c24a4e87e219072e5e106f6791146cbf3b056b3 ]
    
    During the closure of a datagram socket, the vmci_transport_recv_dgram_cb()
    function may be called, which will add the packets
    to the socket's backlog; then, after the receive queue is cleared,
    the __release_sock() function will move the packet back from the socket's
    backlog to the receive queue, which will lead to a memory leak.
    
    sock_close
      __sock_release
        __vsock_release
          // take ownership by user-space
          lock_sock_nested
          sock_set_flag(sk, SOCK_DEAD)
          vmci_transport_release
                                          vmci_dispatch_dgs
                                            vmci_datagram_invoke_guest_handler
                                              vmci_transport_recv_dgram_cb
                                                sk_receive_skb
                                                  if (!sock_owned_by_user(sk))
                                                      [...]
                                             (!)  else if sk_add_backlog()
                                                      [...]
      (!) skb_queue_purge(&sk->sk_receive_queue)
    
          release_sock
            __release_sock
              // move all packets from the backlog
              // to the receive queue
       (!)    sk_backlog_rcv
                vsock_queue_rcv_skb
                [...]
                  __sock_queue_rcv_skb
                    if (!sock_flag(sk, SOCK_DEAD))
                      // Since the socket is "dead", the function will not
                      // be called
                      sk->sk_data_ready(sk)
            sock_release_ownership(sk);
            sock_put
    
    Add a receive queue cleanup in the socket destructor to fix this.
    
    syzkaller report:
    
    unreferenced object 0xffff8880117bfb80 (size 240):
      comm "irq/56-vmw_vmci", pid 205, jiffies 4295064448 (age 73.992s)
      hex dump (first 32 bytes):
        78 dc 26 1e 80 88 ff ff 78 dc 26 1e 80 88 ff ff  x.&.....x.&.....
        00 00 00 00 00 00 00 00 c0 da 26 1e 80 88 ff ff  ..........&.....
      backtrace:
        [<ffffffff82be8d97>] __alloc_skb+0x287/0x330 net/core/skbuff.c:505
        [<ffffffffa114bcbd>] vmci_transport_recv_dgram_cb+0xbd/0x210 [vmw_vsock_vmci_transport]
        [<ffffffffa05072c6>] vmci_datagram_invoke_guest_handler+0x366/0x450 [vmw_vmci]
        [<ffffffffa050ad75>] vmci_dispatch_dgs+0x235/0x490 [vmw_vmci]
        [<ffffffffa050b025>] vmci_interrupt+0x55/0x290 [vmw_vmci]
        [<ffffffff8137ad2b>] irq_thread_fn+0x8b/0x1a0 kernel/irq/manage.c:1205
        [<ffffffff8137c7ae>] irq_thread+0x28e/0x530 kernel/irq/manage.c:1314
        [<ffffffff81253dd6>] kthread+0x2e6/0x3a0 kernel/kthread.c:376
        [<ffffffff81004392>] ret_from_fork+0x22/0x30 arch/x86/entry/entry_64.S:295
    
    Found by InfoTeCS on behalf of Linux Verification Center
    (linuxtesting.org) with Syzkaller.
    
    Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
    Reviewed-by: Stefano Garzarella <[email protected]>
    Signed-off-by: Ilia Gavrilov <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
wifi: brcmfmac: fix P2P device removal race in brcmf_detach() [+ + +]
Author: Michele Dionisio <[email protected]>
Date:   Thu Sep 24 14:30:27 2026 +0200

    wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
    
    commit 08a3f02fea636e97a7422d1512f76dacdb5b0887 upstream.
    
    When the driver is removed while the user space process that created
    the P2P device (e.g. wpa_supplicant) is still exiting, the P2P device
    interface is removed twice and the kernel crashes.
    
    The two paths are:
    
     - wpa_supplicant, on exit, sends NL80211_CMD_DEL_INTERFACE for the P2P
       device. nl80211_del_interface() holds RTNL and the wiphy mutex and
       calls brcmf_p2p_del_vif(), which disables discovery and waits up to
       1.5 s for BRCMF_E_IF_DEL. Then it calls brcmf_remove_interface(),
       which unregisters the wdev and frees the vif and the ifp.
    
     - brcmf_detach() sets the bus down, so BRCMF_E_IF_DEL never arrives,
       and calls brcmf_remove_interface(ifp, false) for the same ifp.
       brcmf_p2p_ifp_removed() reads ifp->vif and then blocks on
       rtnl_lock(). When brcmf_p2p_del_vif() releases RTNL, it calls
       cfg80211_unregister_wdev() on the wdev that was already unregistered
       and freed.
    
    The second list_del_rcu() of wdev->list faults on LIST_POISON2:
    
      brcmfmac: brcmf_p2p_del_vif delete P2P vif
      brcmfmac: brcmf_p2p_deinit_discovery enter
      brcmfmac: brcmf_p2p_del_vif P2P: GO_NEG_PHASE status cleared
      brcmfmac: brcmf_detach Enter
      brcmfmac: brcmf_bus_change_state 1 -> 0
      brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
      brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
      brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
      [1.5 s later, brcmf_p2p_del_vif() timed out]
      brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
      brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
      brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
      Unable to handle kernel paging request at virtual address dead000000000122
      Internal error: Oops: 96000044 [#1] PREEMPT_RT SMP
      pc : _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
      Call trace:
       _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
       cfg80211_unregister_wdev+0x10/0x1c [cfg80211]
       brcmf_p2p_ifp_removed+0x84/0xb0 [brcmfmac]
       brcmf_remove_interface+0x1f4/0x254 [brcmfmac]
       brcmf_detach+0x88/0x180 [brcmfmac]
       brcmf_sdio_remove+0x90/0x7b0 [brcmfmac]
       brcmf_sdiod_remove+0x20/0xa0 [brcmfmac]
       brcmf_ops_sdio_remove+0xbc/0x12c [brcmfmac]
       sdio_bus_remove+0x38/0x144
       device_release_driver_internal+0x1e8/0x2c0
       device_release_driver+0x14/0x20
       brcmf_sdio_bus_remove+0x2c/0x40 [brcmfmac]
       brcmf_fwvid_unregister_vendor+0xd8/0x170 [brcmfmac]
       __exit_compat+0x18/0x418 [brcmfmac_cyw]
       __arm64_sys_delete_module+0x1ac/0x244
    
    The log was taken with debug=0x406 on an i.MX 8M Plus board with a
    CYW55513 (Sona IF513) on SDIO. The driver is the Ezurio backport of
    brcmfmac from v6.18.22 on a 5.4-rt kernel. The code involved is the same
    in mainline.
    
    To reproduce:
    
      1. Start wpa_supplicant on wlan0 and let it associate. It creates the
         P2P device (iw dev shows "type P2P-device").
      2. Stop wpa_supplicant and remove the driver without waiting for
         wpa_supplicant to exit:
    
           kill $(pidof wpa_supplicant)
           rmmod brcmfmac_cyw brcmfmac
    
    The crash is reproducible on that board.
    
    For the interface without a netdev (the P2P device), take RTNL and the
    wiphy mutex in brcmf_detach() before reading iflist, and remove it with
    locked=true. If brcmf_p2p_del_vif() runs first, brcmf_detach() finds the
    slot empty. If brcmf_detach() runs first, nl80211 does not find the wdev
    any more. The interfaces with a netdev are removed as before, because
    brcmf_del_if() takes RTNL on its own for the primary interface.
    
    Fixes: 9831bcb987df ("brcmfmac: Deleting of p2p device is leaking memory.")
    Cc: [email protected]
    Assisted-by: claude-opus-5-5
    Signed-off-by: Michele Dionisio <[email protected]>
    Acked-by: Arend van Spriel <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Johannes Berg <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

wifi: mac80211: add AQL support for multicast packets [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Fri Jul 24 11:54:28 2026 +0000

    wifi: mac80211: add AQL support for multicast packets
    
    [ Upstream commit 836c1addd3bf42d47ca5f7a5780a7ec52abf332e ]
    
    Excessive multicast traffic with little competing unicast traffic can easily
    flood hardware queues, leading to throughput issues. Additionally, filling
    the hardware queues with too many packets breaks FQ for multicast data.
    Fix this by enabling AQL for multicast packets.
    
    Signed-off-by: Felix Fietkau <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Johannes Berg <[email protected]>
    Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mac80211: add ieee80211_txq_aql_pending() [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Fri Jul 24 11:54:29 2026 +0000

    wifi: mac80211: add ieee80211_txq_aql_pending()
    
    [ Upstream commit 9a197e71eb7b45860e37a9f3bdf61a843781ae12 ]
    
    Add a function to allow drivers to query the pending AQL airtime
    for a given txq, for both unicast and broadcast.
    This will be used for mt76 to limit buffering in AP mode for power-save
    stations.
    
    Signed-off-by: Felix Fietkau <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Johannes Berg <[email protected]>
    Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: account non-AQL frames per peer rather than per link [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Tue Aug 18 12:58:25 2026 +0000

    wifi: mt76: account non-AQL frames per peer rather than per link
    
    [ Upstream commit 752770d7a58c821c17909c3ca67f9f14ab146a40 ]
    
    The driver increments wcid->non_aql_packets when a frame goes to the
    hardware queue. The completion path decrements the counter again.
    
    For an MLO peer, the hardware reports the completion on the link that it
    used for the transmission. This link can differ from the link that the
    driver queued the frame on. In that case, the increment and the
    decrement go to different link wcids, and the count drifts upwards until
    it blocks the station.
    
    Keep the count on the wcid of the primary link, like the other peer-wide
    state.
    
    Fixes: 86c051f2c418 ("wifi: mt76: mt7925: enabling MLO when the firmware supports it")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: add PS buffering support for HW-managed TIM drivers [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Sat Aug 1 14:53:25 2026 +0000

    wifi: mt76: add PS buffering support for HW-managed TIM drivers
    
    [ Upstream commit a547b414bf7ea9877456b5630573293cc0e2cae7 ]
    
    Add MT_DRV_HW_PS_BUFFERING flag for drivers where firmware controls
    the TIM bit based on buffered frames. Instead of blocking all TX to
    PS stations (which starves firmware and prevents TIM from being set),
    allow limited frame delivery using AQL pending airtime as the
    throttle. Replenish the firmware buffer on TX completion.
    
    Add mt76_sta_ps_transition() helper for drivers to call from MCU
    PS sync events.
    
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7603: initialize global station WCID [+ + +]
Author: Cristian Papa <[email protected]>
Date:   Thu Sep 3 22:07:02 2026 -0300

    wifi: mt76: mt7603: initialize global station WCID
    
    commit 456de496b53ae73e6e3020fec815dbdc88aa7c07 upstream.
    
    mt7603 uses a driver-private global station WCID for frames that have
    neither a station nor a vif, including frames injected through a monitor
    interface. Unlike the core global WCID initialized by
    mt76_register_device(), this WCID is published without ever being passed
    to mt76_wcid_init().
    
    Since commit 0335c034e726 ("wifi: mt76: fix race condition related to
    checking tx queue fill status"), mt76_tx() queues every such frame on the
    WCID's tx_pending or tx_offchannel queue and links its tx_list. The first
    injected frame therefore reaches __skb_queue_tail() with an uninitialized
    sk_buff_head and dereferences a NULL prev pointer.
    
    Initialize the WCID before publishing it.
    
    The fix was tested on an MT7603 PCIe device. Three wildcard probe requests
    were injected through a monitor interface. The hardware queue head and tail
    advanced from 0 to 3 and a second radio captured the third request over the
    air. No oops or reset occurred. After restoring AP mode, a 150 MB transfer
    also completed without a reset.
    
    Fixes: 0335c034e726 ("wifi: mt76: fix race condition related to checking tx queue fill status")
    Cc: [email protected]
    Signed-off-by: Cristian Papa <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

wifi: mt76: mt7915: disable rx napi when removing device [+ + +]
Author: Nicolas Cavallari <[email protected]>
Date:   Mon Aug 10 17:45:10 2026 +0200

    wifi: mt76: mt7915: disable rx napi when removing device
    
    [ Upstream commit 916c484d29d82f45c281da2786fcd6a1284430ce ]
    
    Unloading the mt7915e module with a MT7916 triggers multiples WARN in
    __netif_napi_del_locked() and in page_pool_disable_direct_recycling()
    because the driver does not disable the napi before destroying it.
    
    This is troublesome since on MT7916 it is required to unload the module
    and reinsert it with a different enable_6ghz parameter to change the
    frequency.  The system generally becomes unstable after reinserting the
    module.
    
    Fix it by disabling rx napi inside mt7915e itself, even through napi rx is
    enabled in the mt76 generic code.  Disabling it in the mt76 generic code
    was previously attempted and reverted because napi was disabled too
    late and rx handlers could access freed structures.  Note that the tx
    side is enabled and disabled by the mt76 generic code.
    
    It is disabled in mt7915_stop_hardware() since, unlike
    mt7915_unregister_device(), is it also called in the probe path if an
    error happens after rx napi is enabled.
    
    Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
    Signed-off-by: Nicolas Cavallari <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7925: don't put the band auto marker in TGID [+ + +]
Author: Devin Wittmayer <[email protected]>
Date:   Thu Sep 10 19:44:28 2026 -0700

    wifi: mt76: mt7925: don't put the band auto marker in TGID
    
    [ Upstream commit 5796b2bf9ff718342773ac760d86eb126c112a4f ]
    
    band_idx starts out as 0xff, which tells the firmware to pick the band on
    its own. A remain-on-channel grant normally writes a real index over it
    before anything else looks. Two cases never see that: an MLD station
    throws the grant away, and an AP has no association to trigger one.
    
    The TX descriptor reads the same field into a two-bit slot, so the marker
    comes out as 3. Every data frame from those two goes out tagged band 3.
    Beacons are fine, they reach the firmware separately and never build a
    descriptor.
    
    Same numbers on an MT7925 and on a Netgear A9000:
    
                            stock         patched
      station, one link     0x00000001    0x00000001
      station, two links    0x00003001    0x00000001
      AP                    0x00003013    0x00000013
      real band index, STA  0x00001001    0x00001001
      real band index, AP   0x00001013    0x00001013
    
    Only the marker cases move.
    
    Fixes: 0cb349d742d1 ("wifi: mt76: mt7925: update mt7925_mac_link_bss_add for MLO")
    Signed-off-by: Devin Wittmayer <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7925: restore the legacy BSS after MLO teardown [+ + +]
Author: Aaron Ma <[email protected]>
Date:   Wed Aug 26 12:36:58 2026 +0800

    wifi: mt76: mt7925: restore the legacy BSS after MLO teardown
    
    [ Upstream commit 8f9e5807671ee97cacf1957f4a09e43f4f1017a9 ]
    
    Removing the last link of an MLD interface leaves the firmware with the
    MLD BSS and DEV entry: the removal loop skips the deflink, and the
    hweight16(mvif->valid_links) fallback reads the stale pre-update
    valid_links, which is still non-zero. The entry keeps the per-link MAC
    address, so every subsequent legacy association fails authentication
    until the interface is removed or the module is reloaded.
    
    Remove the deflink BSS and add it back as a legacy BSS on the transition
    to zero links.
    
    Fixes: 69acd6d910b0 ("wifi: mt76: mt7925: add mt7925_change_vif_links")
    Signed-off-by: Aaron Ma <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt792x: pick the SAR table layout from the table itself [+ + +]
Author: Devin Wittmayer <[email protected]>
Date:   Fri Sep 4 18:35:51 2026 -0700

    wifi: mt76: mt792x: pick the SAR table layout from the table itself
    
    [ Upstream commit af97bf5a7e72da9026de184676df8e2fa57e1058 ]
    
    The SAR power tables are parsed with a version byte from a different
    ACPI table, never their own.
    
    Some firmware declares version 1 and ships version 2 tables. The
    entries then start a byte early, and the 6 GHz limits the table
    carries are dropped, because the older layout has no room for them.
    
      ASUS GA503RM, MTCL declares v1:
      MTGS  28 bytes   v1: (28-6) % 5 = 2, no fit   v2: 3 tables
      MTDS  19 bytes   v1: (19-6) % 6 = 1, no fit   v2: 1 table
    
    The layouts accept disjoint lengths, so take whichever one fits and
    keep it per table.
    
    Reported-by: Sagun Kayastha <[email protected]>
    Closes: https://github.com/morrownr/mt76/issues/62
    Fixes: f965333e491e ("mt76: mt7921: introduce ACPI SAR support")
    Signed-off-by: Devin Wittmayer <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit [+ + +]
Author: Junjie Cao <[email protected]>
Date:   Thu Sep 10 09:23:00 2026 +0800

    wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit
    
    [ Upstream commit 45f53d98cbaa078907b6a300ff3974dfb5ae8776 ]
    
    Some ASUS firmware carries 0xff in MTGS power slots. The driver narrows
    the byte to s8, so the slot reads as -1 in its 0.5 dBm units, wins the
    min() against the regulatory limit and caps every rate the driver
    programs. On an ASUS Zenbook 14 UM3406HA (MT7922) all six MTGS tables
    hold 0xff in every power byte, and txpower_sku shows tmac 3 on every
    supported OFDM/HT/VHT/HE rate against EEPROM entries of 25-39, under
    both the FR and the world regulatory domain. Huy Nguyen Dinh Quang saw
    the same clamp on a Vivobook S 14 M5406WA, with 5 GHz TX at ~40 Mbps,
    and proposed skipping the geo entry.
    
    Skip a geo entry whose power byte is 0xff. The MTDS entry is narrowed
    the same way on its way into the geo lookup, so give it the same
    treatment, and clamp the dynamic value plus offset at 127 so a no-limit
    entry cannot wrap.
    
    Fixes: f965333e491e ("mt76: mt7921: introduce ACPI SAR support")
    Link: https://bugzilla.redhat.com/show_bug.cgi?id=2515420
    Reported-by: Huy Nguyen Dinh Quang <[email protected]>
    Closes: https://lore.kernel.org/linux-wireless/[email protected]/
    Signed-off-by: Junjie Cao <[email protected]>
    Tested-by: Cristian Fleischer <[email protected]>
    Link: https://patch.msgid.link/acb947435fc78d5c06039c7bd5609c735468b0ee.1789002236.git.junjie.cao@intel.com
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout [+ + +]
Author: Tao Gong <[email protected]>
Date:   Sun Aug 23 05:37:39 2026 +0000

    wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout
    
    [ Upstream commit 9c9e4e4c8b45873e53774ab8207825b37b7565ec ]
    
    Correct the definition of struct mt7996_mcu_wed_rro_ba_delete_event to
    match the 12-byte event record layout observed from firmware.
    
    The event TLV sent by firmware is 12 bytes in length rather than 8 bytes.
    It contains an additional 4 bytes that appear to be wlan_id and tid.
    For example, a captured batch deletion of sessions 8, 9, and 10 (TIDs 6,
    0, and 1) shows:
    
      00000000: 02 00 0c 00 08 00 01 00 06 00 00 00 02 00 0c 00
      00000010: 09 00 01 00 00 00 00 00 02 00 0c 00 0a 00 01 00
      00000020: 01 00 00 00
    
    The previous 8-byte structure corrupts the parsing of subsequent TLVs,
    leading to unhandled delete events and erroneous session deletions.
    Consequently, clients that create and tear down BA sessions in batches
    (such as Apple Wi-Fi clients) fail to properly clean up stale sessions,
    causing HW_RRO to be lost upon subsequent reassociations.
    
    Fixes: a5d028d66836 ("wifi: mt76: mt7996: add wed rro delete session garbage collector")
    Signed-off-by: Tao Gong <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init() [+ + +]
Author: Lu Huang <[email protected]>
Date:   Wed Sep 30 16:54:35 2026 +0800

    wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init()
    
    commit 52f6a065e0810c739a5dabd33a58047f08100f50 upstream.
    
    When the eFuse block covering MT7976C_EFUSE_OFFSET is invalid,
    mt7996_mcu_get_eeprom() returns -EINVAL without writing buf, but
    mt7996_variant_fem_init() tolerates -EINVAL and keeps running, so
    buf[idx] == 0xc reads uninitialized stack memory.  A stale 0x0c byte
    misclassifies a 0x7976 aDie as 7976C, selects MT7996_FEM_INT and the
    wrong default EEPROM, overriding valid calibration data.  Only consult
    the eFuse byte when the read succeeded; with an invalid eFuse, fall
    back to the three explicit aDie version checks.
    
    Fixes: e8cb33ad546a ("wifi: mt76: mt7996: add support for more variants")
    Cc: [email protected]
    Signed-off-by: Lu Huang <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

wifi: mt76: mt7996: program a link again if the driver holds it [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Tue Aug 18 12:58:21 2026 +0000

    wifi: mt76: mt7996: program a link again if the driver holds it
    
    [ Upstream commit f5e0b20f6c6d548d985acdd620c5110776c915c2 ]
    
    The firmware needs the driver to remove active links from the BSSINFO table
    when it destroys the interface. A link therefore stays registered from its
    first chanctx assignment until the interface goes away. If the driver holds
    the link already, a second add does nothing.
    
    mac80211 gives a non-AP MLD a new address each time it sets a link up. A link
    that comes back after a failed attempt thus carries an address that the
    hardware does not know, on a BSS that the driver never programs again. The
    station then authenticates from an address that nothing answers. The failure
    repeats until the driver tears the interface down for good.
    
    Program the address and the BSS again. This is the pair that the initial add
    sets up. For a station it does what mt7996_mcu_mld_link_oper() does for an AP.
    
    Fixes: 08813703ac41 ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: mt7996: take over connection monitoring [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Tue Aug 18 12:58:23 2026 +0000

    wifi: mt76: mt7996: take over connection monitoring
    
    [ Upstream commit 0ec14f8c8c5da1c9c314bce4f0bf53c009fbc998 ]
    
    mt76 runs its own beacon monitor. mt76_beacon_mon_check() counts a miss
    for each affiliated link of an MLD, and it stops the count while the phy
    is off channel. mt7996 supplies it through mt76_rx_beacon(), but it does
    not set CONNECTION_MONITOR. Therefore mac80211 also starts its legacy
    monitor.
    
    The legacy monitor knows one interface, not a set of links. It also
    counts while the radio serves a different link. After seven beacon
    intervals it removes an association that still carries traffic on the
    other links.
    
    Set the CONNECTION_MONITOR flag to disable the legacy monitor.
    
    Fixes: 4df75606ece5 ("wifi: mt76: add per-link beacon monitoring for MLO")
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

wifi: mt76: use ALTX queue for packets to disassociated stations [+ + +]
Author: Felix Fietkau <[email protected]>
Date:   Tue Sep 1 11:22:32 2026 +0200

    wifi: mt76: use ALTX queue for packets to disassociated stations
    
    [ Upstream commit 7c2e6b43c3082c2242ecfa5875b2b4b2cd06140f ]
    
    Running these packets through regular buffering queues could cause them
    to hang, especially when the packets were for stations that in disassoc
    state.
    
    Fixes: dedf2ec30fe4 ("wifi: mt76: fix queue assignment for deauth packets")
    Acked-by: Lorenzo Bianconi <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Felix Fietkau <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

 
wireguard: noise: reject response consumption after intermediate initiation [+ + +]
Author: Jason A. Donenfeld <[email protected]>
Date:   Thu Oct 8 14:59:16 2026 +0200

    wireguard: noise: reject response consumption after intermediate initiation
    
    commit d0305f8d90029556260c6824b61c493c424eba9e upstream.
    
    Two threads begin processing the identical response message, received
    twice. The first thread, A, runs. While it's running, the second one,
    B, gets partway through, and during that slow calculation, or even while
    blocking on down_write(), A completes and then also a handshake
    initiation that's already been queued up runs in thread C, which itself
    takes that same down_write(). The handshake initiation creation
    succeeds, and sets the state back to waiting-for-response, and calls
    up_write(), at which point thread B resumes, because either its finished
    its calculations or was finally allowed to acquire down_write(). Thread
    B then copies the state back to the peer, and begins a new session,
    using that state, which is the same session as the one made in thread A.
    
    Thread A                        Thread B                        Thread C
    
    down_read()
     sA = handshake->state
     memcpy(cA, handshake->crypto)
    up_read()
    if (sA != 1)
     goto fail
    slow_crypto(cA)
                                    down_read()
                                     sB = handshake->state
                                     memcpy(cB, handshake->crypto)
                                    up_read()
                                    if (sB != 1)
                                     goto fail
                                    slow_crypto(cB)
    down_write()
     if (sA != handshake->state)
      goto fail
     memcpy(handshake->crypto, cA)
     handshake->state = 2
    up_write()
    down_write()
     if (handshake->state != 2)
      goto fail
     derive_session(handshake->crypto)
    up_write()
                                                                    down_write()
                                                                     slow_crypto(handshake->crypto)
                                                                     handshake->state = 1
                                                                    up_write()
                                    down_write()
                                     if (sB != handshake->state)
                                       goto fail
                                     memcpy(handshake->crypto, cB)
                                     handshake->state = 2
                                    up_write()
                                    down_write()
                                     if (handshake->state != 2)
                                      goto fail
                                     derive_session(handshake->crypto)
                                    up_write()
    
    This seems basically impossible to hit in a meaningful way in practice,
    but ensure that it absolutely cannot happen by comparing the ephemeral
    private key that's on the stack with the latest one that the peer's
    handshake state has.
    
    Cc: [email protected]
    Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
    Reported-by: Jérémy Jean <[email protected]>
    Signed-off-by: Jason A. Donenfeld <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

wireguard: queueing: preserve tstamp_type when encapsulating packet [+ + +]
Author: Ramses de Norre <[email protected]>
Date:   Thu Oct 8 14:59:15 2026 +0200

    wireguard: queueing: preserve tstamp_type when encapsulating packet
    
    commit 65ab9de4bdd4c05d8277cfc20ae0b9f5aff60897 upstream.
    
    Sending traffic through a wireguard tunnel on a host using the fq
    qdisc fills the log with:
    
      fq: likely mono tstamp with tstamp_type 0
    
    An skb carries a timestamp in skb->tstamp and, separately, a
    skb->tstamp_type field recording which clock that timestamp came from.
    The two have to agree.
    
    When wireguard encapsulates a packet it calls wg_reset_packet(), which
    clears the fields that must not leak from the inner packet into the
    tunnel packet. It does so in two steps:
    
      skb_scrub_packet(skb, true);
      memset(&skb->headers, 0, sizeof(skb->headers));
    
    skb_scrub_packet() deliberately keeps skb->tstamp when it holds a
    monotonic timestamp: that value is the time the packet is scheduled to
    be sent, and the qdisc still needs it. The memset then zeroes
    skb->tstamp_type, because that field sits inside the headers group
    while skb->tstamp does not. The packet therefore leaves wireguard
    carrying a monotonic timestamp labelled as a realtime one.
    
    Nothing noticed until commit c4f796c4f16b ("net_sched: sch_fq: convert
    skb->tstamp if not monotonic"): fq used to assume every timestamp was
    monotonic. It now consults tstamp_type, spots the mismatch, warns, and
    falls back to treating the value as monotonic. Pacing still ends up
    correct, so the log spam is the actual problem.
    
    Save tstamp_type before the memset and restore it when encapsulating,
    next to the hash fields that are already carried over this way. When
    decapsulating it stays zeroed, which is right: an incoming packet's
    timestamp is a realtime receive timestamp.
    
    Fixes: d98d58a00261 ("net: Set skb->mono_delivery_time and clear it after sch_handle_ingress()")
    Signed-off-by: Ramses de Norre <[email protected]>
    Reviewed-by: Toke Høiland-Jørgensen <[email protected]>
    Reviewed-by: Eric Dumazet <[email protected]>
    Cc: [email protected]
    Signed-off-by: Jason A. Donenfeld <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
workqueue: Fix NULL current_pwq deref in chained work check [+ + +]
Author: Pavankumar Kondeti <[email protected]>
Date:   Mon Sep 28 09:18:56 2026 +0530

    workqueue: Fix NULL current_pwq deref in chained work check
    
    commit 980db94e3eeefdd8a1c46f86412c33a7f7806f51 upstream.
    
    current_wq_worker() only tells us that %current is a kworker. It does
    not guarantee that the worker is currently executing a work item, as
    worker->current_pwq is populated only while process_one_work() is running
    the work function.
    
    is_chained_work() can be reached while queueing on a draining or
    destroying workqueue. If a kworker outside work-item execution reaches
    that path, current_wq_worker() returns a worker but worker->current_pwq is
    NULL, and the chained-work test can fault before it emits the intended
    warning.
    
    Guard the chained-work test with worker->current_pwq. A kworker without
    current_pwq is not executing work on the target workqueue, so the helper
    should return false and let the draining/destroying warning fire.
    
    Fixes: 8d03ecfe4718 ("workqueue: reimplement is_chained_work() using current_wq_worker()")
    Cc: [email protected]
    Signed-off-by: Pavankumar Kondeti <[email protected]>
    Signed-off-by: Tejun Heo <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
x86/CPU/AMD: Fix AMD TLBI Erratum #1718 [+ + +]
Author: Borislav Petkov (AMD) <[email protected]>
Date:   Fri Oct 2 14:16:17 2026 -0700

    x86/CPU/AMD: Fix AMD TLBI Erratum #1718
    
    commit 87db7795cbaaf636ae22ae031f4906db7bb77803 upstream.
    
    The processor may fail to invalidate a TLB entry while executing an
    INVLPGB/TLBSYNC instruction pair.
    
    Detect the erratum and apply a software workaround when a microcode fix
    is not present.
    
    Fixes: 82378c6c2f43 ("x86/mm: Use INVLPGB for kernel TLB flushes")
    Signed-off-by: Borislav Petkov (AMD) <[email protected]>
    Reviewed-by: Rik van Riel <[email protected]>
    Acked-by: Lorenzo Stoakes (ARM) <[email protected]>
    Tested-by: Lorenzo Stoakes (ARM) <[email protected]>
    Tested-by: Rik van Riel <[email protected]>
    Cc: [email protected]
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
xen/netfront: don't leak the skb when xennet_fill_frags() fails [+ + +]
Author: Josef Bacik <[email protected]>
Date:   Wed Oct 7 17:57:32 2026 +0000

    xen/netfront: don't leak the skb when xennet_fill_frags() fails
    
    commit 93ccaf1c26e2133396173b76a071e59024daa622 upstream.
    
    When a response chain has more slots than fit in the skb's frags,
    xennet_fill_frags() returns an error and xennet_poll() jumps to its
    error path.  That path moves what's left on tmpq to errq to be freed,
    but the skb being filled was already dequeued from tmpq, so it's never
    freed.  Each chain that overflows leaks the skb and the pages attached
    to it as frags, and the backend decides how many slots it sends.
    
    Put the skb back on tmpq before taking the error path, like the
    xennet_set_skb_gso() failure just above it does.
    
    Fixes: ad4f15dc2c70 ("xen/netfront: don't bug in case of too many frags")
    Cc: [email protected]
    Signed-off-by: Josef Bacik <[email protected]>
    Reviewed-by: Juergen Gross <[email protected]>
    Link: https://patch.msgid.link/20261007-b4-xen-netfront-fill-frags-leak-v1-1-a8a01ff9cd52@toxicpanda.com
    Signed-off-by: Jakub Kicinski <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
xfs: fix exchange-range-to-eof file size exchange [+ + +]
Author: Darrick J. Wong <[email protected]>
Date:   Mon Oct 12 08:22:37 2026 -0400

    xfs: fix exchange-range-to-eof file size exchange
    
    [ Upstream commit 7dfb218c829c1acb626e0fe92c5fddb9a26a03e9 ]
    
    Norbert Szetei posted a patch containing an incomplete description of a
    bug in XFS_IOC_EXCHANGE_RANGE's TO_EOF flag.  The bug tricks
    exchange-range into modifying a file so that it has shared blocks
    starting beyond EOF, which is never allowed because files never have
    written data beyond EOF, and you can only share written data blocks.
    This is key to all the incorrect behavior that follows.
    
    Eventually I got from Norbert a description of what's going wrong:
    
    > Fair. Here it is with physical block numbers, 4k blocks. peer is the file
    > that gets rewritten and file1 is the one that ends up with the flag
    > cleared.
    >
    > Start, nothing shared:
    >
    >       peer size 4096   -> [100]
    >       file1 size 12288 -> [200] [201] [202]
    >       donor1 size 4096 -> [300]
    >       donor2 size 4096 -> [400]
    >
    > 1. FICLONERANGE peer's block into file1's middle slot:
    >
    >       peer size 4096   -> [100]
    >       file1 size 12288 -> [200] [100] [202] reflink flag set
    >                             ^^^^^ both files own block 100
    >
    > 2. XFS_IOC_EXCHANGE_RANGE file1 against donor1, file1_offset 0,
    > file2_offset 8192, length 0, TO_EOF. One block is exchanged, and the sizes
    > are exchanged with it:
    >
    >       file1 size 4096   -> [200] [100] [300] reflink flag set
    >                              ^^^^^^^^^^^ still owned, now past the size
    >       donor1 size 12288 -> [202]
    >
    > file1 says it is one block long while it still owns three. Nothing was
    > unmapped. file2_offset is block 2, so this exchange cannot clear a flag.
    >
    > 3. XFS_IOC_EXCHANGE_RANGE file1 against donor2, both offsets 0, length 4096.
    > By i_disk_size this is two one-block files exchanging everything, so
    > xmi_can_exchange_reflink_flags() agrees and the flag is cleared:
    >
    >       file1 size 4096   -> [400] [100] [300] reflink flag CLEARED
    >       donor2 size 4096  -> [200]
    >
    > Block 100 is still shared with peer.
    >
    > 4. pwrite(file1, 4096, 4096), which is file1's second slot, block 100.
    > xfs_is_cow_inode(file1) is false, so no CoW:
    >
    >       peer size 4096 -> [100] same block, new contents
    >
    > Block 100 is the only one that matters here. PoC below, it reads a file
    > called peer in the current directory. The filesystem needs reflink and
    > exchange-range, which mkfs.xfs 7.x turns on by default.
    
    So yes, TO_EOF is screwing up the file size even if it's actually
    exchanging the data block correctly.  The following is the intended
    behavior of XFS_EXCHANGE_RANGE_TO_EOF, as described by its manpage:
    
    "Ignore the length parameter.  All bytes in file1_fd from file1_offset
     to EOF are moved to file2_fd, and file2's size is set to
     (file2_offset+(file1_length-file1_offset)).  Meanwhile, all bytes in
     file2 from file2_offset to EOF are moved to file1 and file1's size is
     set to (file1_offset+(file2_length-file2_offset))."
    
    In other words, if we only exchange a portion of the file data, then we
    should only exchange the portion of the file size that relates to the
    exchanged data.  Unfortunately, the code swaps the ondisk file size and
    the incore file sizes, which is incorrect if the caller passes in a
    nonzero offset.
    
    Having confused the file sizes, the PoC uses a second exchange-range
    call on what looks like a non-reflinked single-block file.  Because the
    file size is set incorrectly, exchange-range thinks it's exchanging the
    full contents of two files and clears the reflink flag on the broken
    file.  That enables an extending write of the broken file to rewrite the
    shared block that's just past EOF.  This has become known colloquially
    as refluxfs.
    
    Once the file sizes are set correctly, the second exchange-range no
    longer thinks that it's doing a full-contents swap, so it won't clear
    the reflink flag on either of its file arguments.
    
    Norbert followed up to an earlier version of this patch with a second
    complaint about us not handling the i_disk_size state correctly:
    
    > The offsets are bounded against the incore i_size but subtracted from
    > the ondisk i_disk_size, so a file that has not been written back gives
    > xmi_isize1 = 0 + (0 - 12288).
    >
    > For instance, you can do:
    >
    > $ xfs_io -f -c "pwrite -q 0 4096" -c fsync file1
    > $ xfs_io -f -c "pwrite -q 0 12288" \
    >   -c "exchangerange -s 0 -d 12288 file1" dirty
    > $ stat -c %s file1
    > 0
    > $ stat -c %i file1
    > 131
    > $ sudo xfs_io -r -c "bulkstat_single 131" . | grep bs_size
    > bs_size = 18446744073709539328
    
    That's wrong, and the new file size update logic depends on the ondisk
    i_disk_size matching the incore i_size, so flush the pagecache as needed
    to push it upwards.
    
    Link: https://lore.kernel.org/linux-xfs/[email protected]/
    Reported-by: Norbert Szetei <[email protected]>
    Cc: [email protected] # v6.10
    Fixes: 966ceafc7a4371 ("xfs: create deferred log items for file mapping exchanges")
    Signed-off-by: Darrick J. Wong <[email protected]>
    Reviewed-by: Dave Chinner <[email protected]>
    Signed-off-by: Carlos Maiolino <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

xfs: stop exchanging reflink flags when exchanging mappings [+ + +]
Author: Norbert Szetei <[email protected]>
Date:   Mon Oct 12 08:34:07 2026 -0400

    xfs: stop exchanging reflink flags when exchanging mappings
    
    [ Upstream commit d84d6c1a7f1e2de9e601703a326a4c1b7b421943 ]
    
    When an exchange covers both files from offset 0 to i_disk_size,
    xmi_can_exchange_reflink_flags() assumes every mapping moved and hands
    the reflink flag over to the other file.
    
    That assumption is wrong.  A file can still own shared blocks past
    i_disk_size, e.g. after EXCHANGE_RANGE_TO_EOF sets a smaller size
    without unmapping anything.  The flag is cleared anyway, and the next
    write to such a block happens in place instead of CoW, corrupting the
    other file that shares it.
    
    Commit a23eca88448e ("xfs: fix exchange-range reflink flag clearing
    issue with INO1_WRITTEN") fixed one instance of this.  Rather than add
    another special case, stop moving the flags.
    xfs_exchmaps_ensure_reflink() already sets the flag on both inodes
    before the exchange, so both just keep it.
    
    Nothing sets CLEAR_INO{1,2}_REFLINK anymore.  Intents logged by older
    kernels may still carry them; recovery already masks them off, so they
    stay in the log format mask and are ignored.
    
    XFS_IOC_SWAPEXT has the same problem: it moves the reflink flag from
    one inode to the other along with the extents.  Just removing that is
    not enough here: the exchange path flags both inodes up front in
    xfs_exchmaps_ensure_reflink(), but swapext has no such step, so the
    inode receiving the shared extents would be left without the flag.
    Set it on both inodes instead, and make sure both have a CoW fork,
    since an inode with the reflink flag is expected to have one.
    
    The flag now stays until FALLOC_FL_UNSHARE_RANGE, xfs_scrub, or a
    truncate to zero removes it.
    
    Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges")
    Fixes: f0bc4d134b46 ("xfs: swap inode reflink flags when swapping inode extents")
    Cc: [email protected] # v6.10
    Assisted-by: LLM
    Signed-off-by: Norbert Szetei <[email protected]>
    Reviewed-by: Dave Chinner <[email protected]>
    Reviewed-by: Darrick J. Wong <[email protected]>
    Signed-off-by: Carlos Maiolino <[email protected]>
    [ sashal: Removed an extra duplicate INO1_WRITTEN guard when deleting xmi_can_exchange_reflink_flags(). ]
    Signed-off-by: Sasha Levin <[email protected]>
    Signed-off-by: Greg Kroah-Hartman <[email protected]>

 
zloop: zero out only the unread tail of short reads [+ + +]
Author: Shin'ichiro Kawasaki <[email protected]>
Date:   Wed Sep 16 15:56:57 2026 +0900

    zloop: zero out only the unread tail of short reads
    
    [ Upstream commit 58304e139cb3fa640da74bc02101f0926d0607e2 ]
    
    zloop_complete_rq() handles a short read from a zone's backing file by
    zero-filling every bio in the request. This is correct when the entire
    request is beyond the written part of the zone. When a read request
    straddles the boundary between written and unwritten data, read_iter()
    returns a partial byte count and zloop then zeroes the whole request
    even for the partially read area with valid data.
    
    Such an unexpected zero data read was observed with fio test script
    t/zbd/test-zbd-support and its test case 69, failing with "bad magic
    header 0".
    
    Avoid the unexpected zero data read by zeroing out only the unread tail
    part. When read data size cmd->ret is smaller than the request size,
    call the new helper function zloop_fill_zero_rq() that walks through
    each bio_vec and fills zeros from the specified start offset.
    
    Fixes: eb0570c7df23 ("block: new zoned loop block device driver")
    Reviewed-by: Damien Le Moal <[email protected]>
    Reviewed-by: Christoph Hellwig <[email protected]>
    Signed-off-by: Shin'ichiro Kawasaki <[email protected]>
    Link: https://patch.msgid.link/[email protected]
    Signed-off-by: Jens Axboe <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>