Commit graph

1,485,420 commits

Author SHA1 Message Date
Nathan Chancellor
eb13a1ff27 random: vDSO: avoid call to memset() when zeroing reserved parameter
After a recent change in LLVM [1], builds with the random vDSO
implementation, such as PowerPC and RISC-V, fail when checking the vDSO:

  arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
  arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported

memset() is now generated when zeroing params->reserved for some builds
because LLVM has an optimization (now run in more instances) that can
recognize at compile time when it is assigning a static value to a
contiguous area of memory and turn that into a call to memset(). Both
clang and GCC assume memset() is always available [2].

Clang has an internal fiddly hook, -max-store-memset, which we can set
to a high number, to disable generating out of line memset calls [3].
Similarly, GCC has -finline-stringops=memset to do the same [4], should
this issue ever hit future version of GCC. While these options wouldn't
make sense for normal kernel code, it is fine for the extremely limited
and intentionally compact vDSO code.

Link: 90cebef141 [1]
Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
Link: b28eeb28be [3]
Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [4]
Closes: https://github.com/ClangBuiltLinux/linux/issues/2183
Cc: stable@vger.kernel.org # v6.12+
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2026-10-02 12:12:13 +02:00
Chris Mason
f35e3b5784 futex: Fix private hash use-after-free on resize
poll_state_synchronize_rcu(mm->futex.phash.batches) is used by
futex_ref_drop() to check that a grace period has passed since the
current hash was published. This relies on batches referencing a grace
period which started after the hash pointer was assigned.

__futex_pivot_hash() sets mmph->batches before it replaces mmph->hash:

    scoped_guard(rcu) {
            mmph->batches = get_state_synchronize_rcu();
            rcu_assign_pointer(mmph->hash, new);
    }

The scoped_guard(rcu) doesn't stop new grace periods from starting, and
if one starts between those two assignments, futex_ref_drop() can move
forward while a reader still holds a pointer to the old hash.

Fix things by setting mmph->batches after assigning mmph->hash.  The
scoped_guard(rcu) isn't needed, so let's drop that as well.

Fixes: 56180dd20c ("futex: Use RCU-based per-CPU reference counting instead of rcuref_t")
Assisted-by: kres
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://patch.msgid.link/20261001135022.2220288-1-mason@kernel.org
2026-10-02 11:47:13 +02:00
Kuan-Wei Chiu
26f6b6357b irq: Make refcount_interrupt kunit test selectable
Currently, refcount_interrupt_test is built unconditionally when
CONFIG_KUNIT is enabled, causing it to run unexpectedly during boot.

Fix this by introducing CONFIG_REFCOUNT_INTERRUPT_KUNIT_TEST so the
test can be configured independently, following standard kunit
practices.

Fixes: 07a88e2bcd ("irq: Add KUnit test for refcounted interrupt enable/disable")
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Reviewed-by: Radu Rendec <radu@rendec.net>
Reviewed-by: Boqun Feng <boqun@kernel.org>
Link: https://patch.msgid.link/20261001082519.16195-2-boqun@kernel.org
2026-10-02 11:40:12 +02:00
Lorenzo Bianconi
232d49dd4b net: stmmac: propagate PTP addend and system time programming errors
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: cc4c9001ce ("net: stmmac: Switch stmmac_hwtimestamp to generic HW Interface Helpers")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 10:31:09 +01:00
Felix Fietkau
f5e0b20f6c wifi: mt76: mt7996: program a link again if the driver holds it
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: 08813703ac ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
Link: https://patch.msgid.link/20260818125825.395538-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-10-02 11:26:58 +02:00
Johan Hovold
6c95ca52f2 tty: add missing driver flag kernel-doc colon
A recent change adding a new TTY driver flag left out a colon required
for well-formed kernel-doc.

Fixes: 8df07fe935 ("tty: fix saved termios reset race")
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Link: https://lore.kernel.org/ec3a09d6-4ba4-41b8-abb1-b59e265f4532@infradead.org
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20261002072736.2063004-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-10-02 11:15:22 +02:00
Sang-Hoon Choi
4c9dc0faca cxgb4/ch_ktls: disable softirqs around tid_list erases
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: 65e302a9bd ("cxgb4/ch_ktls: Clear resources when pf4 device is removed")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reviewed-by: Ayush Sawal <ayush.sawal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 09:58:07 +01:00
Petr Mladek
c83e3d2912 braille: nbcon: Allow to use a serial console with NBCON API as Braille console
The Braille console is not registered in console_list. Instead, it is
integrated with the virtual terminal (VT) and shows what is displayed
on the terminal. It writes the data using con->write*() callback
of the associated serial console driver.

braille_write() is called from the VT code under console_lock().
The associated serial console driver can be converted to the NBCON API
though. The situation is similar to flushing nbcon consoles in the legacy
loop when some boot consoles are still registered, see
nbcon_legacy_emit_next_record().

But there is a big difference though. braille_write() is not directly
called from the code paths flushing registered consoles. The VT code
expects that braille_write() succeeds. It does not replay the message
when it can't acquire the ownership. As a result, braille_write():

  + must try harder to get the ownership.

  + has to be synchronized only against non-printk serial console
    which depend nbcon_device_try_acquire() using NBCON_PRIO_NORMAL.

Let's look at it from another side and try to simulate the original
locking using the NBCON API:

  1. Take con->device_lock(), aka the port->lock in the legacy serial
     console driver.

  2. Acquire nbcon context to provide some synchronization for a panic()
     context. Use NBCON_PRIO_NORMAL because it contends only with
     nbcon_device_try_acquire() users. Do it in a busy loop. It should
     always succeed when con->device_lock() succeeded because all other
     users do the same. The only exception is when the context get acquired
     by a CPU handling panic.

  3. In panic, disable interrupts and try to acquire the nbcon context.
     Use NBCON_PRIO_PANIC. And try even an unsafe takeover because
     otherwise the Braille console won't see the text shown during panic().
     It is similar to the oops_in_progress/trylock handling in the legacy
     serial console driver.

Finally, avoid the newline prepending logic in the existing serial console
drivers when they are used as a Braille console. As explained above,
the Braille console shows the last modified line on the terminal (VT).
braille_write() is called when single characters are added. Most
messages are not ended by newline. Anyway, the VT code does not have
logic to reply partially printed messages.

Fixes: 13189fa73a ("printk: nbcon: Rely on kthreads for normal operation")
Reviewed-by: John Ogness <john.ogness@linutronix.de>
[pmladek@suse.com: Remove white space changes in braille_register_console(). Typo fix.]
Link: https://patch.msgid.link/20261001140727.124398-2-pmladek@suse.com
Signed-off-by: Petr Mladek <pmladek@suse.com>
2026-10-02 10:26:42 +02:00
Yuqi Xu
3acdd44385 tipc: destroy topsrv workqueues before closing connections
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: c5fa7b3cf3 ("tipc: introduce new TIPC server infrastructure")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 08:20:15 +01:00
David S. Miller
f7b3ef049a Merge branch 'dim-overflow'
Shashank Mohan Jain says:

====================

lib/dim: fix 32-bit overflow in dim_calc_stats()

On 32-bit kernels dim_calc_stats() multiplies the u32 byte, packet and
completion counts of a DIM window by USEC_PER_MSEC (1000L) in 32-bit
long arithmetic. Once a window carries more than about 4.3 MB, bpms
wraps, and net_dim steers interrupt moderation on a meaningless
throughput value. At 1 Gbit/s line rate a 64-event window passes that
size when there are fewer than about 1,860 DIM events per second,
which is common while NAPI keeps the interrupt masked under load.
32-bit users of the library include mtk_eth_soc (MT7621, MT7623),
bcmgenet and bcmsysport on 32-bit ARM, xilinx_axienet on Zynq-7000 and
MicroBlaze, and virtio_net in 32-bit guests. The overflow goes back to
the mlx5e code the library was moved from.

Patch 1 does the multiplications in 64 bits and divides with
DIV_ROUND_UP_ULL(); the results on 64-bit are unchanged. Patch 2 adds a
KUnit suite for dim_calc_stats() whose large-window cases fail on
32-bit without patch 1. It is part of this series as described under
"Co-posting selftests" in maintainer-netdev.rst.

The series is based on net (a7bfaba482) and has no dependencies; both
patches also apply to mainline (fd179f8a05) and net-next.

The bug was found and the patches were prepared with Claude Code
(Anthropic), model Claude Opus 5.5 (claude-opus-5-5).

Tested:
- KUnit (CONFIG_DIMLIB_KUNIT_TEST=y) on UML i386 (SUBARCH=i386):
  without patch 1, 4 of the 7 dim_calc_stats cases fail (many_bytes,
  bytes_32bit_limit, gigabit, many_packets); with it all pass. On UML
  x86_64 all cases pass with and without patch 1. Both were run on
  mainline and on net.
- W=1 builds of lib/dim/ for UML x86_64 and i386 without warnings;
  dim.o references no libgcc 64-bit division helpers. A native i386
  defconfig build (vmlinux and modules, DIMLIB=y) succeeds.
- checkpatch --strict. Its "does MAINTAINERS need updating?" warning
  on patch 2 does not apply: lib/dim/ is already covered by the
  DYNAMIC INTERRUPT MODERATION entry.

Not tested: 32-bit ARM or MIPS builds (no cross compiler was
available), and no run on a 32-bit NIC. The traffic levels at which
the drivers hit the overflow are derived from how they count DIM
events, not measured.

Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 07:52:32 +01:00
Shashank Mohan Jain
636035157a lib/dim: add KUnit test for dim_calc_stats()
Add a KUnit suite for the DIM library that checks the packet, byte,
event and completion rates computed by dim_calc_stats(), including
counter wraparound and windows whose byte or packet count times
USEC_PER_MSEC does not fit in 32 bits. The latter cases fail on 32-bit
architectures without the previous commit.

Assisted-by: LLM
Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 07:52:31 +01:00
Shashank Mohan Jain
0843b23890 lib/dim: fix 32-bit overflow in dim_calc_stats() rates
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: cb3c7fd4f8 ("net/mlx5e: Support adaptive RX coalescing")
Fixes: 4c4dbb4a73 ("net/mlx5e: Move dynamic interrupt coalescing code to include/linux")
Assisted-by: LLM
Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2026-10-02 07:52:31 +01:00
Leon Hwang
7a39c732a2 kprobes: Skip disarmed probes when checking optkprobe overlap
On x86, an optkprobe at A replaces five bytes with a jump. If a disabled
probe B is at A+2, get_optimized_kprobe() stops at B when arming a new
probe C at A+4. It leaves A optimized:

              A    A+1  A+2  A+3  A+4
  A's jump  | e9 | d0 | d1 | d2 | d3 |
  after C   | e9 | d0 | d1 | d2 | cc |

The INT3 for C overwrites the last byte of A's jump displacement, so
execution can jump to the wrong address. B can have prepared optinsns
while disarmed, but has no jump to unoptimize.

Continue past disarmed and unprepared probes to find the active optimized
probe before arming a probe in its jump.

Link: https://lore.kernel.org/all/20260930053618.104498-1-leon.hwang@linux.dev/

Fixes: afd66255b9 ("kprobes: Introduce kprobes jump optimization")
Cc: stable@vger.kernel.org
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
2026-10-02 15:51:57 +09:00
Dave Airlie
26fe67ec0d Merge tag 'drm-intel-fixes-2026-10-01' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-fixes
drm/i915 fixes for v7.3-rc6:
- Disable VRR DC balance by default to fix timing issues

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patch.msgid.link/5a9a11777f605b59550783923add4568e974a6ea@intel.com
2026-10-02 11:26:47 +10:00
Dave Airlie
d87d131d18 Only 1 fix to Keep VF LMEM BAR size low if no VFs enabled from
Marcin and a preparation patch for that.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmq+agcACgkQ+mJfZA7r
 E8p65wf9EQf3SmSrhbvW05LLMCTjAHBaXhfYFvaIc7tbkFw9LSi5ensw7UJWko80
 UtKcY36FC0vfQ/w8ZVdl1T2aA03hLeO/syHFL4pp5r2izwgnCUHBk5cp0Ts8Lc/s
 bIM5rcyslrxKGVuiKYpHS2AJlIztswiNdM9PorQVupKb4QJ3UP/86HnNt5sUGK84
 Wn1hl6Qxm6Z9+JGHBu8SjvA8cONnPNKecNts2ITNIbq94Syc53RyFkur/HzonLyq
 3PYR1daShHeKRgmwFCgVXKYalavUKw0bF3HfAS8AM8/cxKpdzg7tzrmXSDizROMW
 wM7qfiGtCRI7LWna1LJRU0dFwHdE5g==
 =6xVO
 -----END PGP SIGNATURE-----

Merge tag 'drm-xe-fixes-2026-10-01' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes

Only 1 fix to Keep VF LMEM BAR size low if no VFs enabled from
Marcin and a preparation patch for that.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patch.msgid.link/ar5qJ-OV2gNI1TwN@intel.com
2026-10-02 11:26:20 +10:00
Quchaosheng
28bc1ef699 net/packet: guard the ll header push in packet_rcv_spkt()
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 d549699048 ("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 9f10374bb0 ("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: d549699048 ("net/packet: fix packet receive on L3 devices without visible hard header")
Cc: stable@vger.kernel.org
Signed-off-by: Quchaosheng <quchaosheng000406@163.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260928113108.2127215-1-quchaosheng000406@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 18:24:13 -07:00
Jakub Kicinski
2d3b94c607 Merge branch 'amt-send-the-relay-s-general-query-directly-from-the-receive-path'
Omar Ramadan says:

====================
amt: send the relay's General Query directly from the receive path

The relay queues its General Query on the amt device with a raw tunnel
pointer in skb->cb, and a query that waits in a qdisc can outlive its
tunnel: a use-after-free in amt_dev_xmit(), reported by Microsoft with
a KASAN reproducer. Patch 1 sends the query directly from
amt_request_handler(), inside the RCU section that found or created
the tunnel, so it never waits in a qdisc and nothing is stored in
skb->cb.

Patch 2 adds the selftest Taehee asked for. It counts the queries that
leave the relay through its amt device and expects none. It fails
without patch 1 and passes with it.
====================

Link: https://patch.msgid.link/20260928202312.74574-1-omar@blockcast.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 18:11:14 -07:00
Omar Ramadan
c41817fcaf selftests: net: amt: check that the relay's queries bypass the amt device
The relay used to hand its General Queries to dev_queue_xmit() on the
amt device, where a query could wait in a qdisc and outlive the tunnel
it pointed to. The previous patch sends them directly from the receive
path instead.

Count the IGMP and MLD queries that leave the relay through amtr with
tc flower filters on its egress, installed before the gateway comes
up, and check that there are none. The forwarding tests before it
already show that the gateway received its queries, since it cannot
join without one.

Without the previous patch the new test fails (one run counted 7 IGMP
and 6 MLD queries); with it, all of amt.sh passes.

Signed-off-by: Omar Ramadan <omar@blockcast.net>
Link: https://patch.msgid.link/20260928202312.74574-3-omar@blockcast.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 18:11:09 -07:00
Omar Ramadan
afae89de73 amt: send the relay's General Query directly from the receive path
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: cbc21dc1cf ("amt: add data plane of amt interface")
Reported-by: AutonomousCodeSecurity@microsoft.com
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Reported-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
Signed-off-by: Omar Ramadan <omar@blockcast.net>
Link: https://patch.msgid.link/20260928202312.74574-2-omar@blockcast.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 18:11:09 -07:00
Jamal Hadi Salim
c9728fcf2e net/sched: em_text: reject unterminated algo before autoload
This is a follow-up to commit 9c572a8303 ("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 3ab720881b.

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: d675c989ed ("[PKT_SCHED]: Packet classification based on textsearch (ematch)")
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260918133953.12494-1-bernard.ladenthin%40gmail.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-2DIU.v1.20260929183844@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 17:59:43 -07:00
Sunho Park
26f90559a7 srcu: Fix WARN_ON() for rcu_segcblist_n_cbs() in cleanup_srcu_struct()
The WARN_ON() added by commit 78a38cbf6f ("srcu: Queue sdp->work
when the delay timer is successfully deleted") uses rcu_segcblist_n_cbs()
to detect callbacks that srcu_barrier() failed to wait for. However, the
->len counter is decremented only at the end of srcu_invoke_callbacks(),
after the invoking loop has finished. Since srcu_barrier() can return
right after the barrier callback is invoked, cleanup_srcu_struct() can see
a non-zero n_cbs even though the cblist is already physically empty,
falsely triggering the WARN_ON() together with a still-pending delay_work
timer.

This can be triggered as follows, as seen in the syzbot report against
kvm_destroy_vm() -> cleanup_srcu_struct(&kvm->srcu):

1. call_srcu(&kvm->srcu, &bus->rcu, __free_bus) starts SRCU grace
   period GP1.

2. GP1 ends: a delay timer is armed and sdp->work is queued, but
   sdp->work has not run yet.

3. Another call_srcu(&kvm->srcu, &bus->rcu, __free_bus) call invokes
   srcu_segcblist_advance(), which moves the GP1 callback to
   RCU_DONE_TAIL, and starts SRCU grace period GP2.

4. srcu_barrier() is called. It queues its barrier callback after the
   GP2 callback and waits for srcu_invoke_callbacks() to invoke it.

5. GP2 ends: another delay timer is armed, and the sdp->work queued in
   step 2 begins to run. Its srcu_invoke_callbacks() call invokes
   srcu_segcblist_advance() again, moving the GP2 and barrier callbacks
   to RCU_DONE_TAIL as well, and then invokes all of them. However,
   rcu_segcblist_add_len(), which updates srcu_cblist's ->len, has not
   run yet at this point.

6. srcu_barrier() returns once its callback has been invoked, and
   cleanup_srcu_struct() starts running. It finds the delay timer
   armed in step 5 still pending and srcu_cblist's ->len still
   non-zero (because step 5 has not reached rcu_segcblist_add_len()
   yet), and WARN_ON() fires even though every callback has actually
   been invoked.

Use rcu_segcblist_empty(), which checks the actual head of the cblist,
instead of rcu_segcblist_n_cbs(), which checks the racy ->len counter.
Callbacks that have genuinely not been invoked yet still leave the list
non-empty, so the WARN_ON() still catches callers that skip srcu_barrier()
or queue callbacks after it.

Link: https://lore.kernel.org/rcu/e6350377085ddd85d6ef00d8e9a67bd50c762d3c@linux.dev/T/#t
Reported-by: syzbot+d4faf7db59e11f6fd1ab@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d4faf7db59e11f6fd1ab
Fixes: 78a38cbf6f ("srcu: Queue sdp->work when the delay timer is successfully deleted")
Suggested-by: Zqiang <qiang.zhang@linux.dev>
Signed-off-by: Sunho Park <shpark061104@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Sean Christopherson <seanjc@google.com>
2026-10-01 17:17:48 -07:00
Chengfeng Ye
17e73bae40 tipc: hold a reference to nodes found by link name
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: 6a939f365b ("tipc: Auto removal of peer down node instance")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://patch.msgid.link/20260928161246.1895273-1-nicoyip.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 17:15:38 -07:00
Guangshuo Li
048739be3e drm/mediatek: Fix ovl adaptor platform device leak
mtk_drm_probe() creates an OVL adaptor platform device with
platform_device_register_data() when the display pipeline requires the
OVL adaptor.

If a later initialization step fails, the probe error path releases
the DRM resources without unregistering the already registered OVL
adaptor device. The normal remove path likewise leaves the device
registered after the DRM driver is unbound.

Keep track of whether the OVL adaptor was successfully registered and
unregister it on probe failure. Also recover the platform device from
the stored DDP component device and unregister it during normal
removal.

The issue was identified by a static analysis tool I developed and
confirmed by manual review.

Fixes: 0d9eee9118 ("drm/mediatek: Add drm ovl_adaptor sub driver for MT8195")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260921131156.403652-1-lgs201920130244@gmail.com/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
2026-10-01 23:06:43 +00:00
Jakub Kicinski
8e9cb39859 Merge branch 'ibmveth-fix-open-fail-unwind-after-lan-registration'
Mingming Cao says:

====================
ibmveth: fix open-fail unwind after LAN registration

ibmveth_open() has two independent unwind holes after the logical LAN
is set up. Neither needs the MQ RX series. This posting is against
current net.git.

Patch 1 issues h_free_logical_lan() on every post-register failure.
A pool allocation failure jumped to out_free_buffer_pools without
the hypercall, so PHYP still owned the buffer-list page when it was
unmapped. request_irq() failure already issued H_FREE before taking
the same label.

  Fixes: d43732ce02 ("ibmveth: properly unwind on init errors")

Patch 2 gives TX LTBs their own walk. out_free_buffer_pools reuses
open()'s loop index, so after the pool unwind i is -1 and the TX
buffers leak. 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).

  Fixes: d926793c1d ("ibmveth: Implement multi queue on xmit")

The MQ RX series on net-next keeps the helper versions of these
guards and does not depend on this pair. If both land, keep the
helpers in that series; these two patches are the current
single-queue open-fail path only.
====================

Link: https://patch.msgid.link/cover.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 15:59:30 -07:00
Mingming Cao
84bec0bf03 ibmveth: fix TX LTB and filter unwind on open-fail
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: d926793c1d ("ibmveth: Implement multi queue on xmit")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/d14314c2b10f125f5e578782484ba3cc50564d53.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 15:59:28 -07:00
Mingming Cao
af0524bf4c ibmveth: h_free logical LAN on open-fail after register
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: d43732ce02 ("ibmveth: properly unwind on init errors")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/7a56fbfb9e0674f011f4e310fbd7dfd8e67c30aa.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01 15:59:28 -07:00
Wentao Liang
2af45da333 drm/mediatek: Fix runtime PM leak in mtk_hdmi_ddc_v2_probe()
pm_runtime_get_sync() unconditionally bumps the usage counter, but
nothing puts it back when devm_i2c_add_adapter() fails, leaving the DDC
runtime-resumed after a failed probe. Drop the reference on that error
path.

Fixes: 8d0f798862 ("drm/mediatek: Introduce HDMI/DDC v2 for MT8195/MT8188")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260916174229.2088824-1-vulab@iscas.ac.cn/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
2026-10-01 22:52:44 +00:00
Wentao Liang
3753e34b73 drm/mediatek: Fix pdev reference leak in mtk_drm_bind()
When the device is not the mmsys master, mtk_drm_bind() returns early
after taking a reference on the disp-mutex device via
of_find_device_by_node(), without ever dropping it: mtk_drm_unbind()
only puts mutex_dev for the master. Drop the reference before returning
from the non-master path.

Fixes: 1ef7ed4835 ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20260916174058.2088709-1-vulab@iscas.ac.cn/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
2026-10-01 22:40:43 +00:00
Francisco Beltrán Millalén
a22e5e4f2e drm/amdgpu: reset VI ASIC on MacBookPro14,3
On a MacBookPro14,3 with a Radeon Pro 555 (Polaris11), the framebuffer
is at MC address 0 when amdgpu loads after a cold boot, as the firmware
leaves it (MC_VM_FB_LOCATION = 0x007f0000), while the VBIOS ASIC_Init
table places it at 0xF4_0000_0000 (0xf47ff400).  amdgpu reads the
location once, at init, so after a re-POST (S3 resume or GPU reset)
the framebuffer has moved and the driver keeps programming the old
one: the SMU is handed a table that was never written and the GPU
does not come back, which leaves the internal panel black.

Resetting the ASIC on load makes ASIC_Init run before the driver reads
the location, so the driver uses the VBIOS placement from the start and
every later re-POST puts the framebuffer back where it already is.

Add the Radeon Pro 555 used in this machine to the existing VI reset
quirk table.

Tested on a MacBookPro14,3 on 6.18.49 with the quirk table backported
(the kernel also carries unrelated local PCI and ACPI patches for this
machine).  The framebuffer is at 0x000000F400000000 after both cold and
warm boot, and the GPU survived 9 S3 cycles (lid close and rtcwake, one
of them with the lid closed for about 7.5 minutes and a USB-C disk
attached), each followed by a few minutes of 3D load; no ring timeouts
or VM faults were reported.  The reset adds about 0.23 s to amdgpu init.

Suggested-by: Christian König <christian.koenig@amd.com>
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/all/20260924132952.25054-1-fbeltranmillalen@gmail.com/
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Francisco Beltrán Millalén <fbeltranmillalen@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b6b1d97218)
Cc: stable@vger.kernel.org
2026-10-01 17:18:34 -04:00
Timur Kristóf
08c9100f65 drm/amd/pm/si: Fix updating clock limits on AC/DC
Assume that the AC limits are the maximum of all power states,
and the DC limits are the maximum of battery power states.
This shouldn't make any difference in practice, but is
cleaner and more robust against bogus information in the VBIOS.

Fixes: e6c5d36756 ("drm/amd/pm/si: Fix updating clock limits from power states")
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260923120354.1027996-2-timur.kristof@gmail.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ef8cb9dcc7)
Cc: stable@vger.kernel.org
2026-10-01 17:18:14 -04:00
Simon Polack
b76a5b7bee drm/amd/display: Fix stale replay_events after mod_power stream removal
[Why]
mod_power_remove_stream() shifts the remaining power_entity slots down
but does not move replay_events, and mod_power_add_stream() does not
initialize it. replay_events therefore stay bound to the map slot
instead of the stream.

When several streams are disabled in one atomic commit,
amdgpu_dm_mod_power_update_streams() removes them one after another.
The eDP stream can then be looked up in a slot whose stale
replay_events already have replay_event_hw_programming set, so
amdgpu_dm_replay_set_event() returns early ("already in desired state")
without calling mod_power_set_replay_event(). Replay is not disabled
before the eDP panel is powered off. After DPMS on, the sink reports
neither replay state nor frame lock (DPCD 0x378 = 0x00, no error bits),
so the HPD IRQ recovery does not trigger and the panel stays black
until a full modeset.

Seen with an eDP panel using FreeSync Replay plus two DP-MST displays:
DPMS off/on of all outputs leaves eDP black, while DPMS of eDP alone
works. Doing an eDP-only DPMS first makes the next all-output DPMS
fail reliably.

[How]
Shift replay_events together with the PSR cached fields in
mod_power_remove_stream() and initialize it to replay_event_vsync in
mod_power_add_stream(), matching the psr_event_vsync initial value used
for PSR (both vsync events are driven together by
amdgpu_dm_crtc_set_static_screen_optimze()).

Tested on 7.3.0-rc3 (238650ef6c): the reproducer above now recovers
reliably, and Replay still engages when the screen is idle.

The issue was debugged with help from an AI assistant (Claude), which
analysed ftrace/kprobe traces and the driver source, pointed to the
missing replay_events handling and suggested this change. I collected
the traces and built and tested the fix on the affected hardware.

Fixes: 4cef2ac4c7 ("drm/amd/display: Introduce power module on Linux")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Simon Polack <spolack+git@mailbox.org>
Reviewed-by: Ray Wu <ray.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 3d47e38e27)
Cc: stable@vger.kernel.org
2026-10-01 17:18:05 -04:00
Imre Kaloz
de1eab13ef drm/radeon: Read the VRAM VBIOS signature with readb()
igp_read_bios_from_vram() checked bios[0]/bios[1] with a plain
__iomem load, which faults on sparc64 before the copy runs at all.
radeon_read_bios() already reads its two signature bytes with
readb() ahead of its own copy; use the same accessor here, keeping
the check before the allocation.

Fixes: b442962a9e ("drm/radeon/kms: add support for "Surround View"")
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 09155b8932)
Cc: stable@vger.kernel.org
2026-10-01 17:18:05 -04:00
Hari Mishal
217f64f348 drm/amd/display: guard dc_sink dereferences in MST mode validation
dm_dp_mst_is_port_support_mode() reads
aconnector->dc_sink->dsc_caps... for the DSC branch-throughput check,
and get_conv_frl_bw()'s HDMI-PCON FRL-bandwidth path reads
aconnector->dc_sink->edid_caps.max_frl_rate, both without a NULL
check. dc_sink is cleared asynchronously on MST unplug, and both
functions run from paths that the driver's own comments document as
racing that teardown: the connector probe worker's ->mode_valid
callback and a compositor's atomic check, neither of which holds the
MST manager lock that the teardown path uses. The former does have an
existing dsc_aux NULL check, but dsc_aux isn't reliably cleared in
every path that clears dc_sink, so it doesn't cover this.

Fail the port-support check and skip the FRL conversion path when the
sink is already gone.

Fixes: f04d275d94 ("drm/amd/display: add mst port output bw check")
Fixes: 5c9b8b27a8 ("drm/amd/display: Tie FRL support into amdgpu_dm")
Assisted-by: gkh_clanker_t1000
Signed-off-by: Hari Mishal <harimishal1@gmail.com>
Reviewed-by: Fangzhi Zuo <jerry.zuo@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7c3db8da4e)
Cc: stable@vger.kernel.org
2026-10-01 17:18:05 -04:00
Adrian Betschart
106b4a2a78 drm/amd/display: Try RGB before YCbCr 4:4:4 in stream validation
amdgpu_dm_create_validate_stream_for_sink() walks encoding_order[] and
uses the first encoding that validates. YCbCr 4:4:4 is listed before
RGB, so an HDMI sink that advertises 4:4:4 gets YCbCr 4:4:4 whenever the
"color format" property is left at AUTO, even though RGB fits the same
link.

That contradicts the documented AUTO behaviour for HDMI in enum
drm_connector_color_format (RGB, falling back to YCbCr 4:2:0 only when
the bandwidth is not available or the mode is 4:2:0-only), which the
amdgpu implementation of the property also describes. It also leaves
the "Broadcast RGB" property without effect on such sinks, since the
quantization range it selects only applies to RGB output.

Try RGB first. The mask still holds every encoding the sink supports,
so a mode that cannot carry RGB falls back exactly as before.

For reference, v7.2 picked RGB here unless YCbCr 4:4:4 was forced
through debugfs, while earlier kernels picked YCbCr 4:4:4 for any HDMI
sink that advertised it.

Fixes: 0b0ff65d3c ("drm/amd/display: Refactor stream validation")
Suggested-by: Adolfo Rodrigues <adolfotregosa@gmail.com>
Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Reviewed-by: Fangzhi Zuo <jerry.zuo@amd.com>
Tested-by: Adolfo Rodrigues <adolfotregosa@gmail.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7de432bc75)
2026-10-01 17:18:05 -04:00
Sasha Levin
fbc988f236 drm/amd/display: Fix sanitizer check for the DML frame size limit
Building x86_64 allmodconfig with clang fails:

  .../dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c:10491:13:
  error: stack frame size (3128) exceeds limit (3072) in
  'dml_core_mode_programming' [-Werror,-Wframe-larger-than]

That config enables both KASAN and UBSAN, and should get the 4096
byte limit meant for clang COMPILE_TEST sanitizer builds. The check
in the dml and dml2_0 Makefiles concatenates the three symbols with
no separator:

  ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)$(CONFIG_UBSAN)),y)

KASAN and KCSAN cannot be enabled together, so before UBSAN was
added the string was at most "y". UBSAN can be enabled alongside
either of them, and with both set the string becomes "yy",
$(filter y,yy) is empty, and the build falls through to the
non-sanitizer limit of 3072. Adding UBSAN to the check therefore
lowered the limit for the most heavily instrumented builds instead
of raising it.

Separate the symbols with spaces so that $(filter) sees individual
words, and test for a non-empty result. Only the configs with two
sanitizers enabled change behaviour.

Found by KernelCI builds of the linus-next tree.

Fixes: ebf8b0fd85 ("drm/amd/display: Relax DML frame limit with UBSAN")
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 0400d53fd0)
Cc: stable@vger.kernel.org
2026-10-01 17:18:05 -04:00
Alex Deucher
e3e7fdece7 drm/amdgpu/gmc12.1: properly pass flush_type to gmc_v12_1_flush_vm_hub()
In gmc_v12_1_flush_gpu_tlb(), flush_type was not properly
passed to gmc_v12_1_flush_vm_hub().  This only affected
the MMIO path.  In most cases the flush would go through
MES.

Reviewed-by: Mukul Joshi <mukul.joshi@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1f0f66fab1)
Cc: stable@vger.kernel.org
2026-10-01 17:18:05 -04:00
Alex Deucher
1d1f1acecd drm/amdgpu: drop userq callback assignment for sdma 7.1
Not enabled in 7.1 so drop the assignment.

Cc: Horatio Zhang <hongkun.zhang@amd.com>
Cc: Hawking.Zhang@amd.com
Fixes: 4ed5116aac ("drm/amdgpu: Add sdma v7_1_0 support")
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 106e19f69a)
Cc: stable@vger.kernel.org
2026-10-01 17:18:01 -04:00
Willian Oliveira
cc172e1777 drm/amdgpu/gfx6: fix firmware leak on teardown
The firmware requested in gfx_v6_0_init_microcode() is not released
when the GFX block is torn down, leaking the firmware resources.

Add gfx_v6_0_free_microcode() and call it from gfx_v6_0_sw_fini()
to release the PFP, ME, CE and RLC firmware.

Signed-off-by: Willian Oliveira <williandossantosdeoliveira287@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 386e81346f)
Cc: stable@vger.kernel.org
2026-10-01 17:17:58 -04:00
Guangshuo Li
f001304615 drm/amdgpu: fix ACP MFD device leak on init failure
acp_hw_init() registers ACP child devices with mfd_add_devices() before
attaching them to the ACP power domain and initializing the hardware.

If attaching a child to the power domain fails, or if the ACP reset or
clock enable operation times out, the failure path frees only the
source cell, resource, and platform-data allocations. The child
platform devices already registered by mfd_add_devices() remain
registered and are never released.

Remove the children from the power domain and unregister the MFD
devices on failures that occur after mfd_add_devices() succeeds. Keep
mfd_add_devices() failures on the existing cleanup path since the MFD
core already rolls back partially registered children itself.

The issue was identified by a static analysis tool I developed and
confirmed by manual review.

Fixes: 25030321ba ("drm/amd: add pm domain for ACP IP sub blocks")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 63da68d6a2)
Cc: stable@vger.kernel.org
2026-10-01 17:17:57 -04:00
Guangshuo Li
f5a5add360 drm/amdgpu: fix IP instance memory leak on kobject add failure
amdgpu_discovery_sysfs_ips() allocates ip_hw_instance with
kzalloc_flex() and initializes its embedded kobject before calling
kobject_add().

If kobject_add() fails, the return value is ignored and execution
continues without dropping the initial kobject reference. The failed
kobject is not retained in the kset list, so the normal sysfs teardown
path cannot find it. As a result, ip_hw_instance_release() is never
called and the ip_hw_instance allocation is leaked.

Call kobject_put() when kobject_add() fails so the initial reference is
dropped and ip_hw_instance_release() can free the allocation. Keep the
existing best-effort sysfs behavior by continuing with the remaining IP
entries after the failed registration.

The issue was identified by a static analysis tool I developed and
confirmed by manual review.

Fixes: a6c40b1780 ("drm/amdgpu: Show IP discovery in sysfs")
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 5c75fbcca8)
Cc: stable@vger.kernel.org
2026-10-01 17:17:57 -04:00
Theo Andersen Carton
eadb85cca1 drm/amdgpu: skip the noirq suspend reset for a switcheroo-parked GPU
amdgpu_pmops_suspend_noirq() resets the ASIC unconditionally. When the GPU
has been parked by vga_switcheroo it has neither power nor a PCIe link, so
the reset cannot reach it: pci_set_power_state() reports the device as
inaccessible and amdgpu_asic_reset() returns -EINVAL. A failure there
aborts the entire noirq suspend phase, and with it the system suspend, so
the machine cannot sleep at all while the GPU is switched off.

amdgpu_device_prepare(), amdgpu_device_suspend() and amdgpu_device_resume()
all bail out early on DRM_SWITCH_POWER_OFF. This callback was added later,
for an unrelated reason, and did not inherit the check. nouveau guards
every one of its PM callbacks the same way.

Bail out the same way here. On a single-GPU system switch_power_state is
never DRM_SWITCH_POWER_OFF, so this is a no-op there.

Found on a MacBookPro11,5, where the Radeon is powered down through
apple-gmux so that the internal panel can be driven by the iGPU instead.
Every suspend failed in amdgpu_pmops_suspend_noirq() while the card was
off; with this check a full S3 cycle completes.

Fixes: 9e051720f9 ("drm/amdgpu: Ensure HDA function is suspended before ASIC reset")
Signed-off-by: Theo Andersen Carton <andersen.theo@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 539d055863)
Cc: stable@vger.kernel.org
2026-10-01 17:17:57 -04:00
Alex Deucher
0bfb1bfc82 drm/amdgpu/gmc12: properly pass flush_type to gmc_v12_0_flush_vm_hub()
In gmc_v12_0_flush_gpu_tlb(), flush_type was not properly
passed to gmc_v12_0_flush_vm_hub().  This only affected
the MMIO path.  In most cases the flush would go through
MES.

Reviewed-by: Mukul Joshi <mukul.joshi@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 6498e33f22)
Cc: stable@vger.kernel.org
2026-10-01 17:17:57 -04:00
Ray Wu
51cc916648 drm/amd/display: map PWM brightness through custom backlight curve
[Why/How]
On the PWM path, convert the userspace brightness to an input signal and
derive the target luminance from the custom backlight curve, then pass
the resulting millipercent to the power module.

This keeps PWM programming and backlight curve mapping in the power
module, aligning the Linux path with the Windows behavior.

Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5723
Fixes: 3c108046e1 ("drm/amd/display: Add power module on Linux")
Assisted-by: Cursor:Claude-Opus-4.8
Signed-off-by: Ray Wu <ray.wu@amd.com>
Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com>
Reviewed-by: ChiaHsuan (Tom) Chung <chiahsuan.chung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit bc4e099caa)
Cc: stable@vger.kernel.org
2026-10-01 17:17:47 -04:00
Pierre-Eric Pelloux-Prayer
eaeac1498b drm/amdgpu: implement workaround for sdma dcc corruption
For unknown reasons, on gfx12 using multiple entities can causes
random corruption of BOs with DCC.
This workaround seems to prevent the issue until the root cause
is understood and fixed.

Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5663
Fixes: 3a6f6eeb3d ("drm/amdgpu: give ttm entities access to all the sdma scheds")
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit cd647796ac)
Cc: stable@vger.kernel.org
2026-10-01 17:17:42 -04:00
Andrew Martin
0e4101c11a drm/amdkfd: Fix always mapped range mapping to all ACCESS GPUs
CWSR ranges use the always mapped flag and only need a mapping on the
GPU running the queue. However, svm_range_validate_and_map now updates
the mapping on every GPU with the ACCESS attribute, which is all
supported GPUs when XNACK is on. After the range is prefetched to VRAM,
those GPUs may span different XGMI hives, so the page owner mismatches
and is set to NULL. hmm_range_fault then tries to migrate the VRAM
pages back to system memory, but svm_migrate_to_ram skips it because
migrating pages back to system memory is not allowed while the GPU
mapping is being updated, so the CPU page fault is never resolved.

Only map to the ACCESS GPUs if the range is not mapped to any GPU and
is not in VRAM.

Fixes: b96f261049 ("drm/amdkfd: Unmap svm range from GPU set to no-access")
Signed-off-by: Andrew Martin <andrew.martin@amd.com>
Assisted-by: Claude:claude-opus-5
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Philip Yang <philip.yang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 093cf8842a)
Cc: stable@vger.kernel.org
2026-10-01 17:17:16 -04:00
Jesse Zhang
8228688eb4 drm/amdgpu/gfx11: set KMD_QUEUE for kernel gfx queues
Set KMD_QUEUE in the GFX MQD and kernel ring control registers so CP
preserves kernel IB VMIDs instead of replacing them with the queue VMID.
Use prop->kernel_queue to distinguish kernel and user MQDs.

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 893642e0e3)
2026-10-01 17:17:16 -04:00
Jesse Zhang
9fe5745f9d drm/amdgpu/gfx12: set KMD_QUEUE for kernel gfx queues
Set KMD_QUEUE in the GFX MQD and kernel ring control registers so CP
preserves kernel IB VMIDs instead of replacing them with the queue VMID.
Use prop->kernel_queue to distinguish kernel and user MQDs.

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 14741c0168)
2026-10-01 17:17:15 -04:00
Jesse Zhang
56b2b97e78 drm/amdgpu: fix empty fence backup and replay intervals
amdgpu_ring_set_fence_errors_and_reemit() and
amdgpu_ring_backup_unprocessed_commands() masked last_seq and sync_seq to
fence-array indices before the loop, then walked a do/while until the two
indices met. When hardware completed every command before the driver
signalled the fences, last_seq == sync_seq, but the masked-index do/while
could not tell that empty interval from a full table and walked the whole
fence array, backing up and replaying already-completed commands.

Read the raw sequence numbers, return early through amdgpu_fence_process()
when they are equal, and mask only at the array index. Guard the
force-completion against a NULL guilty_fence so a non-guilty backup does
not dereference it.

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 78fbe15663)
2026-10-01 17:17:15 -04:00
Jesse Zhang
6b6c4fab88 drm/amdgpu: support non-guilty job save on ring backup
amdgpu_ring_backup_unprocessed_commands() is also used to preserve a
ring that carries no guilty command - for example a collateral kernel
gfx ring that shares the faulting pipe during a gfx user-queue pipe
reset. Such a ring is backed up with a NULL guilty_fence and all of its
unprocessed commands must be saved so they can be replayed after the
reset rebuilds the ring's MQD.

The early-return that skips an already-seen guilty fence compared
"ring->guilty_fence == guilty_fence", which is also true when both are
NULL. A non-guilty save therefore hit the early return and left
ring_backup_entries_to_copy at 0, so the pending commands were dropped
when the ring was rebuilt.

Guard the early return with a non-NULL guilty_fence so a NULL fence
never takes it and every unprocessed command is backed up.

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b3f73daa1c)
2026-10-01 17:17:15 -04:00
Timur Kristóf
cd883d0a39 drm/amd/pm/si: Check AMD_IS_MOBILITY flag for PPSMC_SYSTEMFLAG_GPIO_DC
Unfortunately, some desktop boards eg. the FirePro D500
have the HARDWAREDC platform flag set and also have
a battery power state configured in their VBIOS.
This makes no sense for a desktop GPU and results in
incorrect behaviour: the clocks are stuck at lowest.

We observed that the kernel driver can work around
the issue in two possible ways:
1. Set PPSMC_SWSTATE_FLAG_DC on all power states
2. Clear PPSMC_SYSTEMFLAG_GPIO_DC

We think that the PPSMC_SYSTEMFLAG_GPIO_DC flag
makes the SMC assume it's running on battery even
though this is a desktop machine with no battery,
and that's why it doesn't do DPM on power states
without PPSMC_SYSTEMFLAG_GPIO_DC.

Issue was uncovered by "Fix updating clock limits from
power states" because previously the limits for the
battery state were not tracked separately. However,
battery power state has lower frequencies and voltages,
so the kernel doesn't set the DC flag on the current
power state anymore. That causes the SMC to be stuck
on the lowest clocks.

Let's clear PPSMC_SYSTEMFLAG_GPIO_DC on desktop GPUs.
We can use the AMD_IS_MOBILITY flag to determine that.

Fixes: e6c5d36756 ("drm/amd/pm/si: Fix updating clock limits from power states")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/16352
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260923120354.1027996-1-timur.kristof@gmail.com
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 58473c7c49)
Cc: stable@vger.kernel.org
2026-10-01 17:17:02 -04:00