Skip to contentSkip to conversation

6.18.42-rc1 review

PATCH In review Greg Kroah-Hartman 13 participants 689 messages Jul 30 – Aug 2 Page 1 of 6

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.18.42-rc1 review

This is the start of the stable review cycle for the 6.18.42 release. There are 675 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sat, 01 Aug 2026 14:13:45 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.42-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.18.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 6.18.42-rc1

Nikunj A Dadhania <[email protected]>
KVM: SVM: Bump asid_generation on CPU online to avoid ASID collision after hotplug

Koen Koning <[email protected]>
gpu: Fix uninitialized buddy for built-in drivers

Russell King (Oracle) <[email protected]>
net: stmmac: fix dwmac4 transmit performance regression

Gal Pressman <[email protected]>
net/mlx5e: Fix NULL pointer dereference in ioctl module EEPROM query

Cen Zhang <[email protected]>
usb: gadget: f_tcm: synchronize delayed set_alt with teardown

Alice Ryhl <[email protected]>
rust: device: avoid trailing ; in printing macros

Miguel Ojeda <[email protected]>
rust: allow suspicious_runtime_symbol_definitions lint for Rust >= 1.98

SJ Park <[email protected]>
mm/damon/core: disallow overlapping input ranges for damon_set_regions()

SJ Park <[email protected]>
mm/damon/core: validate ranges in damon_set_regions()

Adrian Hunter <[email protected]>
i3c: mipi-i3c-hci: Fix handling of shared IRQs during early initialization

Adrian Hunter <[email protected]>
i3c: mipi-i3c-hci: Fix Hot-Join NACK

Guoniu Zhou <[email protected]>
pmdomain: imx93-blk-ctrl: Extract PHY as shared domain for DSI/CSI

Marco Felsch <[email protected]>
pmdomain: imx93-blk-ctrl: convert to devm_* only

Haoxiang Li <[email protected]>
net: ipa: fix SMEM state handle leaks in SMP2P init

Bryam Vargas <[email protected]>
ata: libata-core: Reject an invalid concurrent positioning ranges count

Breno Leitao <[email protected]>
bootconfig: fix NULL-pointer arithmetic in xbc_snprint_cmdline()

Breno Leitao <[email protected]>
bootconfig: move xbc_snprint_cmdline() to lib/bootconfig.c

Junrui Luo <[email protected]>
octeontx2-af: cn10k: restrict VF LMTLINE sharing to its own PF

Michael Bommarito <[email protected]>
octeontx2-af: validate body pcifunc in rvu_mbox_handler_rep_event_notify

Shradha Gupta <[email protected]>
net: mana: Optimize irq affinity for low vcpu configs

Dexuan Cui <[email protected]>
net: mana: Validate the packet length reported by the NIC

Tony Luck <[email protected]>
fs/resctrl: Fix use-after-free during unmount

Tony Luck <[email protected]>
fs/resctrl: Move RMID initialization to first mount

Tony Luck <[email protected]>

    fs/resctrl: Move allocation/free of closid_num_dirty_rmid[]

Tony Luck <[email protected]>
x86,fs/resctrl: Rename some L3 specific functions

Tony Luck <[email protected]>
x86,fs/resctrl: Rename struct rdt_mon_domain and rdt_hw_mon_domain

Tony Luck <[email protected]>
fs/resctrl: Split L3 dependent parts out of __mon_event_count()

Guangshuo Li <[email protected]>
mmc: vub300: fix use-after-free on probe failure

Johan Hovold <[email protected]>
mmc: vub300: rename probe error labels

Ingo Blechschmidt <[email protected]>
dm: avoid leaking the caller's thread keyring via the table device file

Christian Brauner <[email protected]>
cred: add kernel_cred() helper

Doruk Tan Ozturk <[email protected]>
accel/amdxdna: reject command submission on devices without a submit op

Souvik Banerjee <[email protected]>
ovl: use linked upper dentry in copy-up tmpfile

Koichiro Den <[email protected]>
dmaengine: dw-edma-pcie: Reject devices without driver data

Krzysztof Kozlowski <[email protected]>
dmaengine: dw-edma: Fix confusing cleanup.h syntax

Michael Bommarito <[email protected]>
thunderbolt: Prevent XDomain delayed work use-after-free on disconnect

Mika Westerberg <[email protected]>

    thunderbolt: Remove XDomain from the bus without holding tb->lock

Mika Westerberg <[email protected]>
thunderbolt: Remove service debugfs entries during unregister

Mika Westerberg <[email protected]>
thunderbolt: Keep XDomain reference during the lifetime of a service

Florian Fuchs <[email protected]>
mtd: maps: vmu-flash: fix fault in unaligned fixup

Pratyush Yadav (Google) <[email protected]>
kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES

Muchun Song <[email protected]>
mm/sparse-vmemmap: fix vmemmap accounting underflow

Tanmay Shah <[email protected]>
remoteproc: xlnx: Check remote core state

Terry Bowman <[email protected]>
cxl: Fix CXL_HEADERLOG_SIZE to match RAS Capability size

Dave Jiang <[email protected]>
cxl/pci: Remove CXL VH handling in CONFIG_PCIEAER_CXL conditional blocks from core/pci.c

Terry Bowman <[email protected]>
cxl/pci: Remove unnecessary CXL RCH handling helper functions

Terry Bowman <[email protected]>
cxl/pci: Remove unnecessary CXL Endpoint handling helper functions

Chuck Lever <[email protected]>
SUNRPC: Return an error from xdr_buf_to_bvec() on overflow

Chuck Lever <[email protected]>
SUNRPC: Add helpers to convert xdr_buf byte ranges to scatterlists

Jeff Layton <[email protected]>
sunrpc: allocate a separate bvec array for socket sends

Mike Snitzer <[email protected]>
NFSD: pass nfsd_file to nfsd_iter_read()

Claudiu Beznea <[email protected]>
pinctrl: renesas: rzg2l: Use -ENOTSUPP instead of -EOPNOTSUPP

Arunpravin Paneer Selvam <[email protected]>
gpu/buddy: bail out of try_harder when alignment cannot be honoured

Joel Fernandes <[email protected]>
gpu: Move DRM buddy allocator one level up (part two)

Pablo Neira Ayuso <[email protected]>
netfilter: nf_conntrack_sip: validate skb_dst() before accessing it

Florian Westphal <[email protected]>
netfilter: nf_conntrack_sip: remove net variable shadowing

Theodor Arsenij Larionov-Trichkine <[email protected]>
netfilter: nft_fib: reject fib expression on the netdev egress hook

Florian Westphal <[email protected]>
netfilter: nf_tables: remove register tracking infrastructure

Abel Vesa <[email protected]>
arm64: dts: qcom: hamoa: Fix OPP tables for all DisplayPort controllers

Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: correct RBR opp entry

Jason Wang <[email protected]>
VDUSE: avoid leaking information to userspace

Eugenio Pérez <[email protected]>
vduse: take out allocations from vduse_dev_alloc_coherent

Eugenio Pérez <[email protected]>
vduse: remove unused vaddr parameter of vduse_domain_free_coherent

Eugenio Pérez <[email protected]>
vduse: return internal vq group struct as map token

Darrick J. Wong <[email protected]>
xfs: don't replace the wrong part of the cow fork

Joanne Koong <[email protected]>
fuse-uring: fix race between registration and connection abortion

Ricardo Robaina <[email protected]>
audit: fix recursive locking deadlock in audit_dupe_exe()

Ricardo Robaina <[email protected]>
audit: use 'unsigned int' instead of 'unsigned'

Jeff Layton <[email protected]>
audit: widen ino fields to u64

Mickaël Salaün <[email protected]>
landlock: Account all audit data allocations to user space

Mickaël Salaün <[email protected]>
landlock: Fix formatting

Harry Wentland <[email protected]>
drm/amd/display: Fix DTB DTO updates breaking live pixel rate sources

Eric Biggers <[email protected]>
fscrypt: Avoid dynamic allocation in fscrypt_get_devices()

Namjae Jeon <[email protected]>
ksmbd: validate ACE size against SID sub-authorities

Namjae Jeon <[email protected]>
ksmbd: bound DACL dedup walk to copied ACEs

Wentao Guan <[email protected]>
ksmbd: restore DACL size on check_add_overflow() to avoid malformed ACL

Haofeng Li <[email protected]>
ksmbd: validate num_subauth when copying ACE in set_ntacl_dacl

Youssef Samir <[email protected]>
net: qrtr: ns: Raise node count limit to 512

Ming Lei <[email protected]>

    ublk: wait on ublk_dev_ready() instead of ub->completion

Jia Yao <[email protected]>
drm/xe/uapi: Reject coh_none PAT index for CPU_ADDR_MIRROR

Mikulas Patocka <[email protected]>
dm-verity: fix buffer overflow in FEC calculation

Eric Biggers <[email protected]>
dm-verity-fec: replace {MAX,MIN}_RSN with {MIN,MAX}_ROOTS

Eric Biggers <[email protected]>
dm-verity-fec: fix reading parity bytes split across blocks (take 3)

Eric Biggers <[email protected]>
dm-verity-fec: fix the size of dm_verity_fec_io::erasures

Jiayuan Chen <[email protected]>
bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops

Christian König <[email protected]>
drm/amdgpu: fix check in amdgpu_hmm_invalidate_gfx

Yang Wang <[email protected]>
drm/amd/pm: fix smu13 power limit range calculation

Asad Kamal <[email protected]>
drm/amdgpu: fix aperture mapping leak

Ce Sun <[email protected]>
drm/amdgpu: invoke pm_genpd_remove() before freeing genpd

Ce Sun <[email protected]>
drm/amdgpu: fix resource leak on ACP reset timeout

Boyuan Zhang <[email protected]>
drm/amdgpu: fix division by zero with invalid uvd dimensions

Luca Coelho <[email protected]>
drm/dp_mst: Handle torn-down topology gracefully in drm_dp_mst_topology_queue_probe()

Boyuan Zhang <[email protected]>
drm/amdgpu/vcn4: avoid rereading IB param length

Boyuan Zhang <[email protected]>
drm/amdgpu/vce: fix integer overflow in image size

Jakob Linke <[email protected]>
drm/amdgpu/soc24: reset dGPU if suspend got aborted

Alex Deucher <[email protected]>

    drm/amdgpu/sdma4.4.2: replace BUG_ON() with WARN_ON()

Boyuan Zhang <[email protected]>
drm/amdgpu/jpeg: fix jpeg_v5_0_1_is_idle detection

Boyuan Zhang <[email protected]>
drm/amdgpu/jpeg: fix jpeg_v4_0_3_is_idle detection

Alex Deucher <[email protected]>
drm/amdgpu/gfx9: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>

    drm/amdgpu/gfx9.4.3: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/gfx8: drop unecessary BUG_ON()

Alex Deucher <[email protected]>
drm/amdgpu/gfx12: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/gfx11: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/gfx10: replace BUG_ON() with WARN_ON()

Yang Wang <[email protected]>
drm/amd/pm: make pp_features read-only when scpm is enabled

Yang Wang <[email protected]>
drm/amd/pm: fix amdgpu_pm_info power display units

Ethan Nelson-Moore <[email protected]>
watchdog: s32g_wdt: remove incorrect options in watchdog_info struct

James Raphael Tiovalen <[email protected]>
vxlan: mdb: Fix source list corruption on a failed replace

Stefano Garzarella <[email protected]>
vsock/virtio: collapse receive queue under memory pressure

Daehyeon Ko <[email protected]>

    tipc: clear sock->sk on the failed-insert path in tipc_sk_create()

Yuxiang Yang <[email protected]>
tcp: challenge ACK for non-exact RST in SYN-RECEIVED

Yizhou Zhao <[email protected]>
tcp: initialize standalone TCP-AO response padding

Justin Lai <[email protected]>
rtase: Workaround for TX hang caused by hardware packet parsing

Asim Viladi Oglu Manizada <[email protected]>
pppoe: reload header pointer after dev_hard_header()

Shuvam Pandey <[email protected]>
ovpn: hold peer before scheduling keepalive work

Pavitra Jha <[email protected]>
ovpn: fix peer refcount leak in TCP error paths

Kyle Zeng <[email protected]>
openvswitch: fix GSO userspace truncation underflow

Doruk Tan Ozturk <[email protected]>
mctp: serial: handle zero-length frames to prevent rx buffer overflow

Doruk Tan Ozturk <[email protected]>
mac802154: llsec: reject frames shorter than the authentication tag

Ibrahim Hashimov <[email protected]>
mac802154: hold an interface reference across the scan worker

Michael Bommarito <[email protected]>
ila: reload IPv6 header after pskb_may_pull in checksum adjust

Sergey Temerkhanov <[email protected]>
ice: use READ_ONCE() to access cached PHC time

Aleksandr Loktionov <[email protected]>
ice: reject out-of-range ptype in ice_parser_profile_init

Eddie Phillips <[email protected]>
gve: fix Rx queue stall on alloc failure

James Montgomery <[email protected]>
ksmbd: defer destroy_previous_session() until after NTLM authentication

Carl Johnson <[email protected]>
smb: client: handle STATUS_STOPPED_ON_SYMLINK responses without a symlink target

Raphael Zimmer <[email protected]>
rbd: Reset positive result codes to zero in object map update path

Christian Brauner <[email protected]>
super: fix emergency thaw deadlock on frozen block devices

Masami Hiramatsu (Google) <[email protected]>
selftests/ftrace: Reset triggers at top level before instance loop

Paul Greenwalt <[email protected]>
ice: fix PTP Call Trace during PTP release

Sven Schnelle <[email protected]>
ptp: ptp_s390: Add missing facility check

Jann Horn <[email protected]>
proc: Fix broken error paths for namespace links

Coia Prant <[email protected]>
net: pcs: xpcs: fix SGMII state reading

Fan Wu <[email protected]>
net: hip04: fix RX buffer leak on build_skb failure

Shiming Cheng <[email protected]>
net: gro: fix double aggregation of flush-marked skbs

David Lee <[email protected]>

    net/x25: fix use-after-free in x25_kill_by_neigh()

Manjunath Patil <[email protected]>
net/mlx5e: Use sender devcom for MPV master-up

Bryam Vargas <[email protected]>
net/iucv: fix use-after-free of a severed iucv_path

Hidayath Khan <[email protected]>
net/af_iucv: fix NULL deref in afiucv_hs_callback_syn()

Doruk Tan Ozturk <[email protected]>
geneve: require CAP_NET_ADMIN in the device netns for changelink

Sungmin Kang <[email protected]>
net: slip: serialize receive against buffer reallocation

Doruk Tan Ozturk <[email protected]>
vxlan: require CAP_NET_ADMIN in the device netns for changelink

Breno Leitao <[email protected]>
phonet: pep: fix use-after-free in pep_get_sb()

Markus Breitenberger <[email protected]>
net: stmmac: intel: skip SerDes reconfig when rate is unchanged

Lu Baolu <[email protected]>
iommu/vt-d: Disallow SVA if page walk is not coherent

Zhang Yi <[email protected]>
iomap: fix out-of-bounds bitmap_set() with zero-length range

Yitang Yang <[email protected]>
io_uring/rw: fix missing ERESTARTSYS conversion in read paths

Tengda Wu <[email protected]>
ftrace: Add global mutex to serialize trace_parser access

Eric Biggers <[email protected]>
fscrypt: Add missing superblock check in find_or_insert_direct_key()

Amir Goldstein <[email protected]>
fs: preserve ACL_DONT_CACHE state in forget_cached_acl()

Chen Changcheng <[email protected]>
fs/super: fix emergency thaw double-unlock of s_umount

Christian Brauner <[email protected]>
binfmt_elf_fdpic: only honour the first PT_INTERP

Chancel Liu <[email protected]>
ASoC: fsl_sai: Fix spurious BCLK on resume by clearing BYP

Chancel Liu <[email protected]>
ASoC: fsl: imx-card: Skip sysclk reset for active DAIs in shutdown

Shihuang Liu <[email protected]>
amt: fix use-after-free in AMT delayed works

Douya Le <[email protected]>
libceph: remove debugfs files before client teardown

Douya Le <[email protected]>
libceph: reject zero bucket types in crush_decode

Raphael Zimmer <[email protected]>
libceph: Reject monmaps advertising zero monitors

Shuangpeng Bai <[email protected]>

    libceph: refresh auth->authorizer_buf{,_len} after authorizer update

Zhao Zhang <[email protected]>
libceph: guard missing CRUSH type name lookup

Raphael Zimmer <[email protected]>
libceph: Fix multiplication overflow in decode_new_up_state_weight()

Douya Le <[email protected]>
libceph: bound get_version reply decode to front len

Wentao Liang <[email protected]>
ceph: fix writeback_count leak in write_folio_nounlock()

WenTao Liang <[email protected]>
ceph: fix refcount leak in ceph_readdir()

Bryam Vargas <[email protected]>
ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()

Max Kellermann <[email protected]>
ceph: add owner/capability checks for CEPH_IOC_SET_LAYOUT*

Zhiling Zou <[email protected]>
sctp: close UDP tunnel sockets during netns teardown

Zhiling Zou <[email protected]>
sctp: avoid auth_enable sysctl UAF during netns teardown

Jun Yang <[email protected]>
sctp: don't free the ASCONF's own transport in DEL-IP processing

Rik van Riel <[email protected]>
mm/huge_memory: set PG_has_hwpoisoned only after new folio head is established

Breno Leitao <[email protected]>
mm/kmemleak: fix checksum computation for per-cpu objects

David Howells <[email protected]>
afs: Fix afs_edit_dir_remove() to get, not find, block 0

Geliang Tang <[email protected]>
mptcp: pm: userspace: fix use-after-free in get_local_id

Michael Bommarito <[email protected]>
mptcp: only set DATA_FIN when a mapping is present

Chenguang Zhao <[email protected]>
mptcp: decrement subflows counter on failed passive join

Will Deacon <[email protected]>
Revert "arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates"

Will Deacon <[email protected]>
arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates

Dev Jain <[email protected]>
arm64: make huge_ptep_get handled unaligned addresses

Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Prevent out-of-bounds write in __trace_probe_log_err()

Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Fix potential underflow in LEN_OR_ZERO macro

Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Avoid temporary buffer truncation in trace_probe_match_command_args()

Masami Hiramatsu (Google) <[email protected]>
tracing/eprobe: Fix exact system name matching in eprobe_dyn_event_match()

Masami Hiramatsu (Google) <[email protected]>
tracing: Fix union collision of module and refcnt for dynamic events

deepakraog <[email protected]>
tracing: Fix resource leak on mmiotrace trace_pipe close

Steven Rostedt <[email protected]>

    tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev

Usama Arif <[email protected]>
tracing: Fix context switch counter truncation

Xu Rao <[email protected]>
misc: nsm: pin the module while the device is open

Runyu Xiao <[email protected]>
misc: nsm: only unlock nsm_dev on post-lock error paths

Guangshuo Li <[email protected]>
intel_th: fix MSC output device reference leak

Alexander Usyskin <[email protected]>
mei: bus: access mei_device under device_lock on cleanup

Ethan Nelson-Moore <[email protected]>
selftests: ntsync: correct CONFIG_NTSYNC name

Jiangshan Yi <[email protected]>
serial: 8250_mid: Fix NULL function pointer dereference on DNV/ICX-D/SNR platforms

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: implement gpio get_direction() callback

Ben Hutchings <[email protected]>
uio_hv_generic: Bind to FCopy device by default

Ian Abbott <[email protected]>
comedi: comedi_parport: deal with premature interrupt

Nathan Chancellor <[email protected]>
x86/boot/compressed: Disable jump tables

Tze Yee Ng <[email protected]>
firmware: stratix10-svc: fix memory leaks and list corruption bugs

Cen Zhang (Microsoft) <[email protected]>

    rhashtable: clear stale iter->p on table restart

Xu Rao <[email protected]>
cdrom: fix stack out-of-bounds read in CDROMVOLCTRL

Rong Bao <[email protected]>
LoongArch: Retrieve CPU package ID from PPTT when available

Kanglong Wang <[email protected]>
LoongArch: Move jump_label_init() before parse_early_param()

Haoran Jiang <[email protected]>
LoongArch: Fix oops during single-step debugging

George Guo <[email protected]>
LoongArch: Fix address space mismatch in kexec command line lookup

Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function for Rust 1.99.0

Alexandre Courbot <[email protected]>
rust: allow clippy::unwrap_or_default globally

FUJITA Tomonori <[email protected]>
rust: time: fix as_micros_ceil() to round correctly for negative Delta

Alice Ryhl <[email protected]>
rust_binder: only print failure if error has source

Zixing Liu <[email protected]>
platform/loongarch: laptop: Explicitly reset bl_powered state when suspend

Christian Brauner <[email protected]>
binfmt_misc: set have_execfd only once the interpreter is opened

Christian Brauner <[email protected]>
exec: fix unsigned loop counter wrap in transfer_args_to_stack()

Chengfeng Ye <[email protected]>
Bluetooth: RFCOMM: Fix session UAF in set_termios

Chengfeng Ye <[email protected]>
Bluetooth: hci_sync: Protect UUID list traversal

MinJea Kim <[email protected]>
staging: rtl8723bs: fix inverted HT40 secondary channel offset

Moksh Panicker <[email protected]>
staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie()

Wentao Liang <[email protected]>
wifi: ath11k: fix refcount leak in ath11k_ahb_fw_resources_init()

LiangCheng Wang <[email protected]>
wifi: brcmfmac: set F2 blocksize to 256 for BCM43752

Fan Wu <[email protected]>
wifi: brcmfmac: make release_scratchbuffers idempotent

Devin Wittmayer <[email protected]>
wifi: mt76: mt7925: drop TXRX_NOTIFY on non-mmio buses

Devin Wittmayer <[email protected]>
wifi: mt76: mt7921: drop TXRX_NOTIFY on non-mmio buses

Devin Wittmayer <[email protected]>
wifi: mt76: mt7615: drop TXRX_NOTIFY on non-mmio buses

Huihui Huang <[email protected]>
wifi: wilc1000: validate assoc response length before subtracting header

Doruk Tan Ozturk <[email protected]>
wifi: mwifiex: fix NULL dereference when the AP has HT-cap but no HT-oper

Daniel Hodges <[email protected]>
wifi: ath6kl: fix use-after-free in aggr_reset_state()

Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB access from firmware ADDBA window size

Norbert Szetei <[email protected]>
ALSA: timer: don't re-enter an instance callback that is still running

Norbert Szetei <[email protected]>
ALSA: timer: drain a slave's callback before its master detaches it

Kai Vehmanen <[email protected]>
ALSA: hda: codecs: hdmi: disable keep-alive before audio format change

Norbert Szetei <[email protected]>
ALSA: seq: close a re-opened queue timer in the destructor

Nikita Maksimov <[email protected]>
ALSA: hda/realtek: Fix speakers on Lunnen Ground 14

Johan Hovold <[email protected]>
media: vpif_capture: fix OF node reference imbalance

Guangshuo Li <[email protected]>
media: vivid: fix cleanup bugs in vivid_init()

Hans Verkuil <[email protected]>
media: vivid: check for vb2_is_busy() when toggling caps

Hans Verkuil <[email protected]>
media: vivid: add vivid_update_reduced_fps()

Guangshuo Li <[email protected]>
media: vimc: fix reference leak on failed device registration

Guangshuo Li <[email protected]>
media: vidtv: fix reference leak on failed device registration

Benjamin Gaignard <[email protected]>
media: verisilicon: Export only needed pixels formats

Zile Xiong <[email protected]>
media: vb2: use ssize_t for vb2_read/vb2_write

Sakari Ailus <[email protected]>
media: v4l2-subdev: Fail {enable,disable}_streams and s_streaming nicely

Mirela Rabulea <[email protected]>
media: v4l2-fwnode: Fix subdev owner overwritten in v4l2_async_register_subdev_sensor()

Pengpeng Hou <[email protected]>
media: v4l2-ctrls: validate HEVC active reference counts

Sergey Shtylyov <[email protected]>
media: v4l2-ctrls-request: add NULL check in v4l2_ctrl_request_complete()

Myeonghun Pak <[email protected]>
media: ti: vpe: unwind v4l2 device registration on probe error

Hungyu Lin <[email protected]>
media: tegra-video: vi: fix invalid u32 return value in format lookup

Dmitry Osipenko <[email protected]>
media: synopsys: hdmirx: Fix HPD lane hold time

Valery Borovsky <[email protected]>
media: sun4i-csi: Return queued buffers on start_streaming() failure

Myeonghun Pak <[email protected]>
media: stm32: dcmi: unregister notifier on probe failure

Valery Borovsky <[email protected]>
media: stm32-dcmipp: Return queued buffers on start_streaming() failure

Ma Ke <[email protected]>
media: saa7134: Fix a possible memory leak in saa7134_video_init1

Tommaso Merciai <[email protected]>
media: rzg2l-cru: Skip ICnMC configuration when ICnSVC is used

Valery Borovsky <[email protected]>
media: rtl2832_sdr: Return queued buffers on start_streaming() failure

Deepanshu Kartikey <[email protected]>

    media: rtl2832: fix use-after-free in rtl2832_remove()

Myeonghun Pak <[email protected]>
media: radio-si476x: Unregister v4l2_device on probe failure

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID GEN3

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID GEN2

Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID 680

Valery Borovsky <[email protected]>
media: pwc: Return queued buffers on start_streaming() failure

Valery Borovsky <[email protected]>
media: pwc: Drain fill_buf on start_streaming() failure

Krzysztof Kozlowski <[email protected]>
media: pci: dm1105: Free allocated workqueue

Guoniu Zhou <[email protected]>
media: nxp: imx8-isi: Fix scale factor calculation for hardware rounding

Guoniu Zhou <[email protected]>
media: nxp: imx8-isi: Fix potential out-of-bounds issues

Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Fix missing v4l2_subdev_cleanup() in pipe init error path

Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Clean up already-initialized pipes on probe failure

Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Add missing v4l2_subdev_cleanup() in crossbar and pipe

David Carlier <[email protected]>
media: nuvoton: npcm-video: fix memory leaks in probe and remove

David Carlier <[email protected]>
media: nuvoton: npcm-video: fix error handling in npcm_video_init()

Valery Borovsky <[email protected]>
media: msi2500: Return queued buffers on start_streaming() failure

Anand Moon <[email protected]>
media: meson: vdec: Fix memory leak in error path of vdec_open

Guangshuo Li <[email protected]>
media: marvell-cam: fix missing pci_disable_device() on remove

Dmitry Baryshkov <[email protected]>
media: iris: Fix use IRQF_NO_AUTOEN when requesting the IRQ

Marco Nenciarini <[email protected]>
media: intel/ipu6: Improve DWC PHY HSFREQRANGE band selection for overlapping ranges

Sakari Ailus <[email protected]>
media: imx219: Fix maximum frame length in lines

Martin Hecht <[email protected]>
media: i2c: alvium: fix critical pointer access in alvium_ctrl_init

Wang Jun <[email protected]>
media: cx23885: add ioremap return check and cleanup

Johan Hovold <[email protected]>
media: cx231xx: fix devres lifetime

Brandon Brnich <[email protected]>
media: chips-media: wave5: Move src_buf Removal to finish_encode

Pengpeng Hou <[email protected]>
media: cedrus: skip invalid H.264 reference list entries

Samuel Holland <[email protected]>
media: cedrus: Fix missing cleanup in error path

Myeonghun Pak <[email protected]>
media: cedrus: clean up media device on probe failure

Myeonghun Pak <[email protected]>
media: cec: seco: unregister adapter on IR probe failure

David Carlier <[email protected]>
media: aspeed: fix missing of_reserved_mem_device_release() on probe failure

Ricardo Ribalda <[email protected]>
media: amlogic-c3: Add validations for ae and awb config

Valery Borovsky <[email protected]>
media: airspy: Return queued buffers on start_streaming() failure

Maíra Canal <[email protected]>
drm/v3d: Reach the GMP through the hub registers on V3D 7.x

Matthew Brost <[email protected]>
drm/gpusvm: Fix MM reference leak in drm_gpusvm_range_evict

Linmao Li <[email protected]>
drm/vc4: Prevent shader BO mappings from becoming writable

Ian Forbes <[email protected]>
drm/vmwgfx: Validate vmw_surface_metadata::array_size

Leo Li <[email protected]>
drm/amd/display: Fix missing DCE check in dm_gpureset_toggle_interrupts()

Linmao Li <[email protected]>
drm/vc4: Shut down BO cache timer before teardown

Leo Li <[email protected]>
drm/amd/display: Fix flip-done timeouts on mode1 reset

Zhu Lingshan <[email protected]>

    drm/amdgpu: fix bo->pin leaking in amdgpu_bo_create_reserved

Mario Limonciello <[email protected]>
drm/amdgpu: Disable PCIe dynamic speed switching on Ryzen Pinnacle Ridge

Mario Limonciello <[email protected]>
drm/amd/display: Fix backlight max_brightness to match exported range

Alessandro Rinaldi <[email protected]>
drm/amd/display: Force PWM backlight on Lenovo Legion 5 15ARH05

Andriy Korud <[email protected]>
drm/amd/display: dce100: skip non-DP stream encoders for DP MST

Leo Li <[email protected]>
drm/amd/display: consolidate DCN vblank/flip handling onto vupdate_no_lock

WenTao Liang <[email protected]>
drm/amd/display: set new_stream to NULL after release

Timur Kristóf <[email protected]>

    drm/amd/pm/ci: Don't disable MCLK DPM on Bonaire 0x6658 (R7 260X)

Mario Limonciello <[email protected]>
drm/amdgpu: Fix VFCT bus number matching with soft filter

Mario Limonciello <[email protected]>
drm/amdgpu: Release VFCT ACPI table reference

Osama Abdelkader <[email protected]>
drm/panthor: return error on truncated firmware

Matthew Brost <[email protected]>
drm/ttm: Account for NULL and handle pages in ttm_pool_backup

Jason Macnak <[email protected]>
drm/virtio: Don't detach GEM from a non-created context

Alex Deucher <[email protected]>
drm/gfx10: Program DB_RING_CONTROL

Yang Wang <[email protected]>
drm/amd/pm: fix smu14 power limit range calculation

Jani Nikula <[email protected]>
drm/i915/mst: limit DP MST ESI service loop

Joonas Lahtinen <[email protected]>
drm/i915/gem: Fix NULL deref in I915_CONTEXT_PARAM_SSEU

Joonas Lahtinen <[email protected]>

    drm/i915/gem: Do not leak siblings[] on proto context error

Shahyan Soltani <[email protected]>
drm/amdgpu: fix lifetime issue of amdgpu_vm_get_task_info_pasid()

Kenneth Feng <[email protected]>
drm/amd/amdgpu: disable ASPM on VI if pcie dpm is disabled

Jani Nikula <[email protected]>
drm/i915/bios: range check LFP Data Block panel_type2

Joonas Lahtinen <[email protected]>
drm/i915: Return NULL on error in active_instance

Alex Deucher <[email protected]>
drm/amdgpu/sdma5.0: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/sdma5.2: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/sdma6.0: replace BUG_ON() with WARN_ON()

Alex Deucher <[email protected]>
drm/amdgpu/sdma7.0: replace BUG_ON() with WARN_ON()

Jani Nikula <[email protected]>

    drm/i915/hdcp: check streams[] bounds before overflow

Jani Nikula <[email protected]>
drm/i915/hdcp: require monotonically increasing seq_num_v

Bryam Vargas <[email protected]>
drm/virtio: bound EDID block reads to the response buffer

WenTao Liang <[email protected]>
drm/amd/display: detect_link_and_local_sink: DP alt mode timeout path leaks prev_sink reference

Thomas Zimmermann <[email protected]>
drm/amd/display: Handle struct drm_plane_state.ignore_damage_clips

Yongqiang Sun <[email protected]>
drm/amdkfd: fix 32-bit overflow in CWSR total size calculation

David Francis <[email protected]>
drm/amdkfd: Check bounds on CRIU restore queue type and mqd size

David Francis <[email protected]>
drm/amdkfd: Check bounds in allocate_event_notification_slot

David Francis <[email protected]>
drm/amdkfd: Use kvcalloc to allocate arrays

Icenowy Zheng <[email protected]>

    drm/imagination: acquire vm_ctx->lock before mapping memory to GPU VM

Luigi Santivetti <[email protected]>
drm/imagination: fix error checking of pvr_vm_context_lookup()

Shuvam Pandey <[email protected]>
drm/imagination: Fix user array stride in pvr_set_uobj_array()

Brajesh Gupta <[email protected]>
drm/imagination: Fix double call to drm_sched_entity_fini()

Nitin Gote <[email protected]>
drm/xe: Hold a dma-buf reference for imported BOs

Matthew Brost <[email protected]>
drm/xe: Fix PTE index in xe_vm_populate_pgtable() for chunked binds

Matthew Brost <[email protected]>
drm/xe: Return error on non-migratable faults requiring devmem

Pavel Ondračka <[email protected]>
drm/radeon: fix r100_copy_blit for large BOs

Wentao Liang <[email protected]>
drm/nouveau/acr: fix missing nvkm_done() in error path of nvkm_acr_oneinit()

Joonas Lahtinen <[email protected]>
drm/i915/gem: Add missing nospec on parallel submit slot

Jani Nikula <[email protected]>
drm/displayid: fix Tiled Display Topology ID size

Thomas Zimmermann <[email protected]>
drm/sysfb: Return errno code from drm_sysfb_get_visible_size()

Thomas Zimmermann <[email protected]>
drm/sysfb: Avoid possible truncation with calculating visible size

Junrui Luo <[email protected]>
drm/nouveau: fix reversed error cleanup order in ucopy functions

Mario Limonciello <[email protected]>
drm/amdgpu: validate CP_GFX_SHADOW chunk size in CS pass1

Timur Kristóf <[email protected]>
drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT

Jiqian Chen <[email protected]>
drm/amdgpu/gfx9: Fix Ring and IB test fail after mode2

Thomas Zimmermann <[email protected]>
drm/sysfb: Avoid truncating maximum stride

Thomas Zimmermann <[email protected]>
drm/sysfb: Do not page-align visible size of the framebuffer

Mario Limonciello <[email protected]>
drm/amdgpu: check amdgpu_vm_bo_find() result in GET_MAPPING_INFO

Timur Kristóf <[email protected]>
drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older

Timur Kristóf <[email protected]>
drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)

Asad Kamal <[email protected]>
drm/amdgpu/gfx: fix cleaner shader IB buffer overflow

Ashutosh Desai <[email protected]>
drm/dp/mst: fix OOB reads on 2-byte fields in sideband reply parsers

Alessio Belle <[email protected]>
drm/imagination: Fit paired fragment job in the correct CCCB

Ashutosh Desai <[email protected]>
drm/dp/mst: fix buffer overflows in sideband chunk accumulation

Ashutosh Desai <[email protected]>
drm/dp/mst: fix OOB reads in remote DPCD/I2C sideband reply parsers

Vitor Soares <[email protected]>
drm/bridge: cdns-dsi: Replace deprecated UNIVERSAL_DEV_PM_OPS()

Alessio Belle <[email protected]>
drm/imagination: Count paired job fence as dependency in prepare_job()

Chen Ni <[email protected]>
drm/rockchip: analogix_dp: Add missing error check for platform_get_resource()

Sergey Shtylyov <[email protected]>
drm/rockchip: cdn-dp: add missing check in cdn_dp_config_video()

Tomi Valkeinen <[email protected]>
drm/tidss: Fix missing drm_bridge_add() call

Biju Das <[email protected]>
drm: renesas: rzg2l_mipi_dsi: Move rzg2l_mipi_dsi_set_display_timing()

Biju Das <[email protected]>
drm: renesas: rzg2l_mipi_dsi: Increase reset deassertion delay

Chengfeng Ye <[email protected]>
bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()

Lorenzo Bianconi <[email protected]>
net: airoha: fix ETS channel derivation in airoha_tc_setup_qdisc_ets()

Minhong He <[email protected]>
mctp: check register_netdevice_notifier() error in mctp_device_init()

Clark Wang <[email protected]>
ptp: netc: explicitly clear TMR_OFF during initialization

Cen Zhang (Microsoft) <[email protected]>
rds: tcp: unregister sysctl before tearing down listen socket

Nikola Z. Ivanov <[email protected]>
ipv6: Change allocation flags to match rcu_read_lock section requirements

Paul Greenwalt <[email protected]>
ice: prevent tstamp ring allocation for non-PF VSI types

Marcin Szycik <[email protected]>
ice: fix LAG recipe to profile association

Vincent Chen <[email protected]>
ice: allow creating VFs when !CONFIG_ICE_SWITCHDEV

Li RongQing <[email protected]>
net: ipv6: fix dif and sdif mismatch in raw6_icmp_error

Hariprasad Kelam <[email protected]>
octeontx2-pf: tc: fix egress ratelimiting

Alexei Lazar <[email protected]>
net/mlx5e: Reject unsupported CB Shaper TSA in ETS validation

Alexei Lazar <[email protected]>
net/mlx5e: Report zero bandwidth for non-ETS traffic classes

Yael Chemla <[email protected]>
net/mlx5: E-Switch, fix zero num_dest in prio_tag egress vlan rule

Gal Pressman <[email protected]>
net/mlx5: Fix MCIA register buffer overflow on 32 dword reads

Gal Pressman <[email protected]>
net/mlx5: Refactor EEPROM query error handling to return status separately

Runyu Xiao <[email protected]>

    raw: annotate lockless match fields in raw_v4_match()

Aldo Ariel Panzardo <[email protected]>
net: qrtr: restrict socket creation to the initial network namespace

Chenguang Zhao <[email protected]>
hinic: remove unused ethtool RSS user configuration buffers

Eric Dumazet <[email protected]>
ppp: annotate data races in ppp_generic

Eric Dumazet <[email protected]>
ipv4: icmp: fill flow parameters in icmp_route_lookup decoy lookup

Suman Ghosh <[email protected]>
octeontx2-vf: set TC flower flag on MCAM entry allocation

Yun Zhou <[email protected]>
net: gre: fix lltx regression for GRE tunnels with SEQ/CSUM

vadik likholetov <[email protected]>
net: stmmac: enable the MAC on link up for all supported speeds

Nazim Amirul <[email protected]>
net: stmmac: reset residual action in L3L4 filters on delete

Nazim Amirul <[email protected]>
net: stmmac: fix l3l4 filter rejecting unsupported offload requests

Nazim Amirul <[email protected]>
net: stmmac: xgmac: fix l4 filter port overwrite on register update

Russell King (Oracle) <[email protected]>
net: stmmac: cores: remove many xxx_SHIFT definitions

Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Add hardware supported cross-timestamp

Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Enable TBS support for Agilex5

Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Agilex5 EMAC platform configuration

Russell King (Oracle) <[email protected]>
net: stmmac: remove xstats.pcs_* members

Xiang Mei (Microsoft) <[email protected]>
bpf: tcp: fix double sock release on batch realloc

José Expósito <[email protected]>
drm/tests: shmem: Set DMA mask to 64-bit in drm_gem_shmem

Cen Zhang (Microsoft) <[email protected]>
tipc: fix u16 MTU truncation in media and bearer MTU validation

Zhang Yi <[email protected]>
iomap: correct the range of a partial dirty clear

Shuicheng Lin <[email protected]>
drm/xe/vm: Fix SVM leak on resv obj alloc failure in xe_vm_create()

Raag Jadav <[email protected]>
drm/xe/i2c: Allow per domain unique id

Harshaka Narayana <[email protected]>
vmxnet3: fix BUG_ON in vmxnet3_get_hdr_len() for Geneve packets

Qing Luo <[email protected]>
sctp: auth: verify auth requirement when auth_chunk is NULL

Michael Walle <[email protected]>
net: dpaa: fix mode setting

Eric Dumazet <[email protected]>
net: hsr: fix memory leak on slave unregistration by removing synced VLANs

Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: fix vlan range dumps starting with pvid

Michael Bommarito <[email protected]>
amt: make the head writable before rewriting the L2 header

Michael Bommarito <[email protected]>
amt: re-read skb header pointers after every pull

Amir Goldstein <[email protected]>
ovl: check access to copy_file_range source with src mounter creds

Christian Brauner <[email protected]>
ovl: port ovl_copyfile() to cred guard

Christian Brauner <[email protected]>
ovl: add override_creds cleanup guard extension for overlayfs

Christian Brauner <[email protected]>
cred: add scoped_with_kernel_creds()

Julian Braha <[email protected]>
drm/panel: s6e3ha8: fix unmet dependency on DRM_DISPLAY_HELPER

Yichong Chen <[email protected]>
ovl: fix trusted xattr escape prefix matching

Shelley Yang <[email protected]>
wifi: brcmfmac: fix 802.1X-SHA256 call trace warning

Lorenzo Bianconi <[email protected]>
wifi: mt76: mt7996: fix possible NULL-pointer deref in mt7996_mcu_sta_bfer_eht()

Sean Wang <[email protected]>
wifi: mt76: mt7925: fix crash in reset link replay

Lorenzo Bianconi <[email protected]>
wifi: mt76: mt7996: check pointer returned by mt76_connac_get_he_phy_cap()

Lorenzo Bianconi <[email protected]>

    wifi: mt76: mt7925: fix possible NULL-pointer deref in mt7925_mcu_bss_he_tlv()

Lorenzo Bianconi <[email protected]>
wifi: mt76: connac: fix possible NULL-pointer deref in mt76_connac_mcu_uni_bss_he_tlv()

Ruoyu Wang <[email protected]>
wifi: mt76: mt7915: guard HE capability lookups

Guangshuo Li <[email protected]>
wifi: mt76: mt7925: guard link STA in decap offload

Eric Dumazet <[email protected]>

    ppp: annotate concurrent dev->stats accesses

Qingfang Deng <[email protected]>
ppp: don't store tx skb in the fastpath

Qingfang Deng <[email protected]>
ppp: enable TX scatter-gather

Helen Koike <[email protected]>
tipc: fix infinite loop in __tipc_nl_compat_dumpit

Xiang Mei (Microsoft) <[email protected]>
nexthop: initialize extack in nh_res_bucket_migrate()

Xiang Mei (Microsoft) <[email protected]>
gtp: check skb_pull_data() return in gtp1u_send_echo_resp()

Matthieu Baerts (NGI0) <[email protected]>
selftests: drv-net: increase timeout

Matthieu Baerts (NGI0) <[email protected]>
selftests: ovpn: increase timeout

Matthieu Baerts (NGI0) <[email protected]>
selftests: ovpn: add IPV6 and VETH configs

Matthieu Baerts (NGI0) <[email protected]>
selftests: openvswitch: add config file

Matthieu Baerts (NGI0) <[email protected]>
selftests: af_unix: add USER_NS config

Rishikesh Jethwani <[email protected]>
tls: device: push pending open record on splice EOF

Myeonghun Pak <[email protected]>
net: mctp i3c: clean up notifier and buses if driver register fails

Cen Zhang (Microsoft) <[email protected]>
sctp: validate stream count in sctp_process_strreset_inreq()

Nikhil P. Rao <[email protected]>
pds_core: check for workqueue allocation failure

Nikhil P. Rao <[email protected]>
pds_core: fix auxiliary device add/del races

Nikhil P. Rao <[email protected]>
pds_core: order completion reads after the ownership check

Nikhil P. Rao <[email protected]>
pds_core: yield the CPU while waiting for the adminq to drain

Nikhil P. Rao <[email protected]>
pds_core: fix use-after-free on workqueue during remove

Nikhil P. Rao <[email protected]>
pds_core: fix deadlock between reset thread and remove

HanQuan <[email protected]>
sctp: fix auth_chunk_list capacity check in sctp_auth_ep_add_chunkid

Chenguang Zhao <[email protected]>
net: txgbe: fix FDIR filter leak on remove

Kuniyuki Iwashima <[email protected]>
net: Call net_enable_timestamp() before failure in sk_clone().

Kuniyuki Iwashima <[email protected]>
soreuseport: Clear sk_reuseport_cb before failure in sk_clone().

Prashanth Kumar KR <[email protected]>
amd-xgbe: fix MAC_AUTO_SW handling in CL37 AN

Steven Price <[email protected]>
arm64: Correct value returned by ESR_ELx_FSC_ADDRSZ_nL()

Nikhil P. Rao <[email protected]>
pds_core: reject component parameter in legacy firmware update

Andrew Pope <[email protected]>
wifi: mac80211: recalculate TIM when a station enters power save

Li RongQing <[email protected]>
iommu/intel: Fix out-of-bounds memset in dmar_latency_disable()

Pengpeng Hou <[email protected]>
iommu/amd: Bound the early ACPI HID map

HE WEI (ギカク) <[email protected]>
wifi: mwifiex: bound uAP association event IEs to the event buffer

Enrico Zanda <[email protected]>
vhost-net: fix TX stall when vhost owns virtio-net header

Ruoyu Wang <[email protected]>
wan: wanxl: Only reset hardware after BAR mapping

Ruoyu Wang <[email protected]>
nfp: Check resource mutex allocation

Xiang Mei <[email protected]>
wifi: mac80211: tear down new links on vif update error path

Guanghui Feng <[email protected]>
iommu/amd: Wait for completion instead of returning early in iommu_completion_wait()

Wayen Yan <[email protected]>
net: airoha: Fix DMA direction for NPU mailbox buffer

Guangshuo Li <[email protected]>
dpaa2-eth: put MAC endpoint device on disconnect

Wayen Yan <[email protected]>
net: airoha: Fix potential use-after-free in airoha_ppe_deinit()

Guangshuo Li <[email protected]>
dpaa2-switch: put MAC endpoint device on disconnect

Xuanqiang Luo <[email protected]>
rxrpc: fix io_thread race in rxrpc_wake_up_io_thread()

Zhixing Chen <[email protected]>
gtp: parse extension headers before reading inner protocol

Aldo Ariel Panzardo <[email protected]>
rds: drop incoming messages that cross network namespace boundaries

Zhaolong Zhang <[email protected]>
bonding: fix devconf_all NULL dereference when IPv6 is disabled

David Lee <[email protected]>
net/packet: avoid fanout hook re-registration after unregister

Danielle Ratson <[email protected]>
netlink: specs: rt-link: convert bridge port flag attributes to u8

Michael Walle <[email protected]>
net: phy: marvell: fix return code

Pengpeng Hou <[email protected]>
Bluetooth: btusb: validate Realtek vendor event length

Daniel Golle <[email protected]>
regulator: mt6358: use regmap helper to read fixed LDO calibration

Pengpeng Hou <[email protected]>
hwmon: occ: validate poll response sensor blocks

Marco Baffo <[email protected]>
ovpn: use monotonic clock for peer keepalive timeouts

Marco Baffo <[email protected]>
ovpn: fix use after free in unlock_ovpn()

longlong yan <[email protected]>
selftests/net: ovpn: fix getaddrinfo memory leak in ovpn_parse_remote()

Qing Ming <[email protected]>
ovpn: avoid putting unrelated P2P peer on socket release

Yichong Chen <[email protected]>
smb: client: validate DFS referral PathConsumed

Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) add missed handle for ENOMEM

Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) fix EC read intervals

Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) fix looping over banks while reading from EC

Mostafa Saleh <[email protected]>
drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook()

Diego Fernando Mancera Gomez <[email protected]>
usb: atm: ueagle-atm: reject descriptors that confuse probe and disconnect

Shahar Tzarfati <[email protected]>
wifi: iwlwifi: mvm: fix read in wake packet notification handler

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: validate payload length in iwl_pnvm_complete_fn

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: fix pointer arithmetic in iwl_add_mcc_to_tas_block_list

Pagadala Yesu Anjaneyulu <[email protected]>
wifi: iwlwifi: mvm: validate SAR GEO response payload size

Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Use complete_all() to signal init_completion

Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Fix potential probe() deadlock

Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Don't use devres to unregister component

Shengjiu Wang <[email protected]>
ASoC: bt-sco: fix duplicate DAPM widget names for wideband DAI

Guangshuo Li <[email protected]>
ALSA: hda: cs35l41: validate and free ACPI mute object

Chen-Yu Tsai <[email protected]>
ASoC: sun4i-codec: Set quirks.playback_only for H616 codec

Pengpeng Hou <[email protected]>
ASoC: tas2781: bound firmware description string parsing

Guanghui Yang <[email protected]>
btrfs: free mapping node on duplicate reloc root insert

Leo Martins <[email protected]>
btrfs: don't propagate EXTENT_FLAG_LOGGING to split extent maps

Dave Chen <[email protected]>
btrfs: fix u32 to s64 type conversion in dirty_metadata_bytes accounting

You-Kai Zheng <[email protected]>
btrfs: declare btrfs_ioctl_search_args_v2::buf as __u8

Tristan Madani <[email protected]>
wifi: carl9170: fix buffer overflow in rx_stream failover path

Tristan Madani <[email protected]>
wifi: carl9170: fix OOB read from off-by-two in TX status handler

Tristan Madani <[email protected]>
wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read

Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB read from firmware IE lengths in connect event

Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler

Ruoyu Wang <[email protected]>
firewire: net: Fix fragmented datagram reassembly

Manivannan Sadhasivam <[email protected]>
wifi: ath12k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET

Manivannan Sadhasivam <[email protected]>
wifi: ath11k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET

Dmitry Morgun <[email protected]>
wifi: ath11k: fix potential buffer underflow in ath11k_hal_rx_msdu_list_get()

Wayen Yan <[email protected]>
watchdog: airoha: Prevent division by zero when clock frequency is zero

Tzung-Bi Shih <[email protected]>
watchdog: pretimeout: Fix UAF in watchdog_unregister_governor()

Guenter Roeck <[email protected]>
hwmon: (nzxt-kraken3) Stop device IO before calling hid_hw_stop

Guenter Roeck <[email protected]>
hwmon: (nzxt-smart2) Stop device IO before calling hid_hw_stop

Guenter Roeck <[email protected]>
hwmon: (gigabyte_waterforce) Stop device IO before calling hid_hw_stop

Guenter Roeck <[email protected]>
hwmon: (corsair-cpro) Stop device IO before calling hid_hw_stop

Edward Adam Davis <[email protected]>
hwmon: (corsair-psu) Stop device IO before calling hid_hw_stop

Gaole Zhang <[email protected]>
wifi: ath11k: fix NULL pointer dereference in ath11k_hal_srng_access_begin

Cheng Yongkang <[email protected]>
wifi: ath9k: hif_usb: don't dereference hif_dev after re-arming firmware request

Daniel Borkmann <[email protected]>
selftests/bpf: Keep verifier_map_ptr exercising ops pointer access

KP Singh <[email protected]>
selftests/bpf: Adjust verifier_map_ptr for the map's excl field

Xincheng Zhang <[email protected]>
usb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits

Sasha Levin <[email protected]>
Revert "drm/amd/display: Add missing kdoc for ALLM parameters"

Xie Bo <[email protected]>
RISC-V: KVM: Serialize virtual interrupt pending state updates

Georgi Valkov <[email protected]>
wifi: mwifiex: fix freeze for 60 seconds caused by request_firmware

Chia-Lin Kao (AceLan) <[email protected]>
usb: typec: ucsi: Add duplicate detection to nvidia registration path

Chia-Lin Kao (AceLan) <[email protected]>
usb: typec: ucsi: Detect and skip duplicate altmodes from buggy firmware

Chukun Pan <[email protected]>
USB: serial: option: add TDTECH MT5710-CN

Johan Hovold <[email protected]>
USB: serial: keyspan_pda: fix data loss on receive throttling

Sunho Park <[email protected]>
USB: serial: io_edgeport: cap received transmit credits

Tim Pambor <[email protected]>
USB: serial: ftdi_sio: add support for E+H FXA291

Muhammad Bilal <[email protected]>
usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer

Fan Wu <[email protected]>
usb: gadget: udc: bdc: free IRQ and drain func_wake_notify before teardown

Sonali Pradhan <[email protected]>
usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()

Johan Hovold <[email protected]>
USB: gadget: fsl-udc: fix dev_printk() device

Johan Hovold <[email protected]>
USB: gadget: fsl-udc: fix device name leak on probe failure

Johan Hovold <[email protected]>
USB: gadget: snps-udc: fix device name leak on probe failure

Melbin K Mathew <[email protected]>
usb: gadget: printer: fix infinite loop in printer_read()

Fan Wu <[email protected]>
usb: gadget: f_midi: cancel pending IN work before freeing the midi object

Jinchao Wang <[email protected]>
usb: gadget: dummy_hcd: prevent fifo_req reuse during giveback

Xu Yang <[email protected]>
usb: chipidea: fix usage_count leak when autosuspend_delay is negative

Huang Wei <[email protected]>
USB: storage: add NO_ATA_1X quirk for Longmai USB Key

Guangshuo Li <[email protected]>
usb: musb: omap2430: Do not put borrowed of_node in probe

Chia-Lin Kao (AceLan) <[email protected]>
usb: core: port: Deattach Type-C connector on component unbind

Huihui Huang <[email protected]>

    wifi: at76c50x-usb: avoid length underflow in at76_guess_freq()

Griffin Kroah-Hartman <[email protected]>
usb: core: sysfs: add lock to bos_descriptors_read()

Weiming Shi <[email protected]>
mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n

Xin Long <[email protected]>
sctp: fix auth_hmacs array size in struct sctp_cookie

Jamal Hadi Salim <[email protected]>
net/sched: act_tunnel_key: Defer dst_release to RCU callback

Ivan Vecera <[email protected]>
dpll: fix NULL pointer dereference in dpll_msg_add_pin_ref_sync()

Eric Dumazet <[email protected]>
tcp: fix TIME_WAIT socket reference leak on PSP policy failure

Lizhi Hou <[email protected]>
accel/amdxdna: Fix use-after-free of mm_struct in job scheduler

Emre Cecanpunar <[email protected]>
drm/i915/selftests: Fix GT PM sort comparators

Vinod Govindapillai <[email protected]>
drm/i915/wm: clear the plane ddb_y entries on plane disable

Xiang Mei (Microsoft) <[email protected]>
ksmbd: validate compound request size before reading StructureSize2

Qihang <[email protected]>
ksmbd: pin conn during async oplock break notification

Daniele Ceraolo Spurio <[email protected]>
drm/xe/wopcm: fix WOPCM size for LNL+

Matthew Brost <[email protected]>
drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves

Satyanarayana K V P <[email protected]>
drm/xe/vf: Shadow buffer management for CCS read/write operations

Satyanarayana K V P <[email protected]>
drm/xe/sa: Shadow buffer support in the sub-allocator pool

Michał Winiarski <[email protected]>
drm/xe: Allow the caller to pass guc_buf_cache size

Shuhao Fu <[email protected]>
can: j1939: fix lockless local-destination check

Mark Harris <[email protected]>
riscv: hwprobe: Avoid uninitialized read in hwprobe_get_cpus()

Vasily Gorbik <[email protected]>
s390/checksum: Fix csum_partial() without vector facility

Linmao Li <[email protected]>
drm/panthor: Check debugfs GEM lock initialization

Michal Luczaj <[email protected]>
bpf, sockmap: Reject unhashed UDP sockets on sockmap update

Shrikanth Hegde <[email protected]>
powerpc/vtime: Initialize starttime at boot for native accounting

Frederic Weisbecker <[email protected]>
powerpc/time: Prepare to stop elapsing in dynticks-idle

Rosen Penev <[email protected]>
powerpc/85xx: Add fsl,ifc to common device ids

Oliver Hartkopp <[email protected]>
can: raw: add locking for raw flags bitfield

Pengpeng Hou <[email protected]>
drm/i915/gt: use correct selftest config symbol

Huiwen He <[email protected]>
smb/client: handle overlapping allocated ranges in fallocate

Ruoyu Wang <[email protected]>
Bluetooth: hci_qca: Clear memdump state on invalid dump size

Pauli Virtanen <[email protected]>
Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds

Pauli Virtanen <[email protected]>
Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync

Pauli Virtanen <[email protected]>
Bluetooth: hci_sync: extend conn_hash lookup critical sections

Cen Zhang <[email protected]>
Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update

Xiang Mei <[email protected]>
Bluetooth: qca: fix NVM tag length underflow in TLV parser

Takashi Iwai <[email protected]>
ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC

Karol Wachowski <[email protected]>
accel/ivpu: Fix wrong register read in LNL failure diagnostics

Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning

Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts

Rosen Penev <[email protected]>

    ata: sata_dwc_460ex: use platform_get_irq()

Rosen Penev <[email protected]>
ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered

David Jeffery <[email protected]>
scsi: core: wake eh reliably when using scsi_schedule_eh

Robert Mader <[email protected]>
udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf()

Bryam Vargas <[email protected]>
net/iucv: take a reference on the socket found in afiucv_hs_rcv()

Weiming Shi <[email protected]>
ipv4: fib: free fib_alias with kfree_rcu() on insert error path

Norbert Szetei <[email protected]>
ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF

Rafael J. Wysocki <[email protected]>
cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq

Pushpendra Singh <[email protected]>
firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context

Uday Khare <[email protected]>
ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after lookup

Charles Keepax <[email protected]>
ASoC: cs42l43: Correct report for forced microphone jack

Vijendar Mukunda <[email protected]>
ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check

Vijendar Mukunda <[email protected]>
ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()

Vijendar Mukunda <[email protected]>
ASoC: amd: ps: disable MSI on resume in ACP PCI driver

Christian Hewitt <[email protected]>
ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop

Sebastian Ene <[email protected]>
firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation

Mostafa Saleh <[email protected]>
firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()

HE WEI (ギカク) <[email protected]>
wifi: cfg80211: bound element ID read when checking non-inheritance

Runyu Xiao <[email protected]>
wifi: brcmfmac: initialize SDIO data work before cleanup

Cen Zhang <[email protected]>
wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock

Zhao Li <[email protected]>
wifi: mac80211: avoid non-S1G AID fallback for S1G assoc

Zhao Li <[email protected]>
wifi: cfg80211: reject unsupported PMSR FTM location requests

Zhao Li <[email protected]>
wifi: cfg80211: validate PMSR FTM preamble range

Zhao Li <[email protected]>
wifi: cfg80211: validate PMSR measurement type data

Zhao Li <[email protected]>
wifi: nl80211: constrain MBSSID TX link ID range

Zhao Li <[email protected]>
wifi: nl80211: validate nested MBSSID IE blobs

Zhao Li <[email protected]>
wifi: cfg80211: derive S1G beacon TSF from S1G fields

Zhao Li <[email protected]>
wifi: nl80211: free RNR data on MBSSID mismatch

Peddolla Harshavardhan Reddy <[email protected]>
wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock

Xiang Mei <[email protected]>
wifi: p54: validate RX frame length in p54_rx_eeprom_readback()

Maoyi Xie <[email protected]>
wifi: mac80211: defer link RX stats percpu free to RCU

Dawei Feng <[email protected]>
wifi: libertas: fix memory leak in helper_firmware_cb()

Xiang Mei <[email protected]>
wifi: mac80211: fix fils_discovery double free on alloc failure

Xiang Mei <[email protected]>
wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc failure

Bryam Vargas <[email protected]>
wifi: mac80211_hwsim: clamp virtio RX length before skb_put

Christophe JAILLET <[email protected]>
wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()

Abdun Nihaal <[email protected]>
wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()

Cen Zhang <[email protected]>
wifi: cfg80211: cancel sched scan results work on unregister

Xiang Mei (Microsoft) <[email protected]>
xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert

Xiang Mei (Microsoft) <[email protected]>
xfrm6: clear dst.dev on error to avoid double netdev_put in xfrm6_fill_dst()

Chen YanJun <[email protected]>
xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()

Cen Zhang <[email protected]>
xfrm: clear mode callbacks after failed mode setup

Aleksandrova Alyona <[email protected]>
RDMA/irdma: Prevent overflows in memory contiguity checks

Malaya Kumar Rout <[email protected]>
selftests/alsa: Fix memory leak in find_controls error path

Xue Lei <[email protected]>
mtd: fix double free and WARN_ON in add_mtd_device() error paths

Ruoyu Wang <[email protected]>
RDMA/siw: publish QP after initialization

Danila Chernetsov <[email protected]>
RDMA/hns: Fix potential integer overflow in mhop hem cleanup

Ruoyu Wang <[email protected]>
RDMA/mana_ib: initialize err for empty send WR lists

Ruoyu Wang <[email protected]>
RDMA/erdma: initialize ret for empty receive WR lists

Jacob Moroni <[email protected]>
RDMA/irdma: Prevent user-triggered null deref on QP create

Jacob Moroni <[email protected]>
RDMA/irdma: Remove redundant legacy_mode checks

Jacob Moroni <[email protected]>
RDMA/irdma: Prevent rereg_mr for non-mem regions

Jacob Moroni <[email protected]>
RDMA/umem: Add pinned revocable dmabuf import interface

Or Gerlitz <[email protected]>
RDMA/cma: Fix hardware address comparison length in netevent callback

Antony Antony <[email protected]>
xfrm: reject optional IPTFS templates in outbound policies

Tejun Heo <[email protected]>
sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()

John Stultz <[email protected]>

    sched/ext: Avoid null ptr traversal when ->put_prev_task() is called with NULL next

Unnathi Chalicheemala <[email protected]>
firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()

Boris Burkov <[email protected]>
btrfs: fallback to transaction csum tree on a commit root csum miss

Filipe Manana <[email protected]>
btrfs: use bool type for btrfs_path members used as booleans

Filipe Manana <[email protected]>
btrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots()

Xiang Mei <[email protected]>
btrfs: reject free space cache with more entries than pages

Pengpeng Hou <[email protected]>
mtd: nand: mtk-ecc: stop on ECC idle timeouts

Pengpeng Hou <[email protected]>
mtd: mtdswap: remove debugfs stats file on teardown

Michael Bommarito <[email protected]>
IB/mad: Drop unmatched RMPP responses before reassembly

Seth Forshee <[email protected]>
firmware: arm_ffa: Respect firmware advertised RX/TX buffer size limits

Petr Wozniak <[email protected]>

    xfrm: fix stale skb->prev after async crypto steals a GSO segment

Petr Wozniak <[email protected]>
xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()

Eric Dumazet <[email protected]>
net: plumb drop reasons to __dev_queue_xmit()

Eric Dumazet <[email protected]>
net: dropreason: add SKB_DROP_REASON_RECURSION_LIMIT

Sumit Gupta <[email protected]>
arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234

Akhil R <[email protected]>
arm64: tegra: Remove fallback compatible for GPCDMA

Junxi Qian <[email protected]>
fuse: fix writeback array overflow when max_pages is one

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix logic error in packet reset

Seungjin Bae <[email protected]>
Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()

Chuck Lever <[email protected]>
xprtrdma: Clear receive-side ownership pointers on release

Mikko Perttunen <[email protected]>
crypto: tegra - Don't touch bo refcount in host1x bo pin/unpin

Mikko Perttunen <[email protected]>
gpu: host1x: Fix use-after-free in host1x_bo_clear_cached_mappings

Claudiu Beznea <[email protected]>
dmaengine: sh: rz-dmac: Move interrupt request after everything is set up

Oliver Hartkopp <[email protected]>
can: bcm: track a single source interface for ANYDEV timeout/throttle ops

Oliver Hartkopp <[email protected]>
can: bcm: fix data race on rx_stamp/rx_ifindex in bcm_rx_handler()

Oliver Hartkopp <[email protected]>
can: bcm: fix stale rx/tx ops after device removal

Oliver Hartkopp <[email protected]>
can: bcm: add missing device refcount for CAN filter removal

Oliver Hartkopp <[email protected]>
can: bcm: validate frame length in bcm_rx_setup() for RTR replies

Oliver Hartkopp <[email protected]>
can: bcm: extend bcm_tx_lock usage for data and timer updates

Oliver Hartkopp <[email protected]>
can: bcm: fix CAN frame rx/tx statistics

Oliver Hartkopp <[email protected]>
can: bcm: add locking when updating filter and timer values

Phil Rosenthal <[email protected]>
KVM: x86/mmu: Fix use-after-free on vendor module reload

Hyunwoo Kim <[email protected]>
KVM: nVMX: Hide shadow VMCS right after VMCLEAR

Venkatesh Srinivas <[email protected]>
KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN

Sean Christopherson <[email protected]>
KVM: x86: Check for invalid/obsolete root *after* making MMU pages available

Heiko Carstens <[email protected]>
seqlock: Allow UBSAN_ALIGNMENT to fail optimizing

Peter Zijlstra <[email protected]>
seqlock: Allow KASAN to fail optimizing

Peter Zijlstra <[email protected]>
seqlock: Cure some more scoped_seqlock() optimization fails

Kiryl Shutsemau <[email protected]>
fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race

Ryosuke Yasuoka <[email protected]>
drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker

Brian Witte <[email protected]>
netfilter: nf_tables: revert commit_mutex usage in reset path

Brian Witte <[email protected]>
netfilter: nft_quota: use atomic64_xchg for reset

Brian Witte <[email protected]>
netfilter: nft_counter: serialize reset with spinlock

Daniel Borkmann <[email protected]>
selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs

Daniel Borkmann <[email protected]>
bpf: Fix ld_{abs,ind} failure path analysis in subprogs

Guixiong Wei <[email protected]>
platform/x86/intel-uncore-freq: Fix current_freq_khz after CPU hotplug

-------------

Diffstat:

 Documentation/gpu/drm-mm.rst                       |   10 +-
 Documentation/netlink/specs/rt-link.yaml           |   40 +-
 MAINTAINERS                                        |   13 +
 Makefile                                           |    9 +-
 arch/arm64/boot/dts/nvidia/tegra234.dtsi           |   24 +-
 arch/arm64/boot/dts/nvidia/tegra264.dtsi           |    2 +-
 arch/arm64/boot/dts/qcom/lemans.dtsi               |    8 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |    8 +-
 arch/arm64/boot/dts/qcom/sc8180x.dtsi              |   12 +-
 arch/arm64/boot/dts/qcom/sc8280xp.dtsi             |   32 +-
 arch/arm64/boot/dts/qcom/sm6350.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/sm8350.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/sm8450.dtsi               |    4 +-
 arch/arm64/boot/dts/qcom/x1e80100.dtsi             |   77 +-
 arch/arm64/include/asm/esr.h                       |    2 +-
 arch/arm64/mm/hugetlbpage.c                        |    2 +-
 arch/loongarch/kernel/acpi.c                       |   27 +-
 arch/loongarch/kernel/kgdb.c                       |    3 +-
 arch/loongarch/kernel/machine_kexec.c              |    5 +-
 arch/loongarch/kernel/setup.c                      |    3 +-
 arch/loongarch/kernel/smp.c                        |    4 +-
 arch/powerpc/kernel/time.c                         |   43 +
 arch/powerpc/platforms/85xx/common.c               |    2 +
 arch/riscv/include/asm/kvm_host.h                  |   10 +-
 arch/riscv/kernel/sys_hwprobe.c                    |    1 +
 arch/riscv/kvm/aia.c                               |   35 +-
 arch/riscv/kvm/vcpu.c                              |   68 +-
 arch/riscv/kvm/vcpu_onereg.c                       |    8 +-
 arch/s390/lib/csum-partial.c                       |    2 +-
 arch/x86/boot/compressed/Makefile                  |    1 +
 arch/x86/kernel/cpu/resctrl/core.c                 |   32 +-
 arch/x86/kernel/cpu/resctrl/internal.h             |   18 +-
 arch/x86/kernel/cpu/resctrl/monitor.c              |   36 +-
 arch/x86/kvm/lapic.c                               |    2 +-
 arch/x86/kvm/mmu/mmu.c                             |   11 +-
 arch/x86/kvm/mmu/paging_tmpl.h                     |   10 +-
 arch/x86/kvm/svm/svm.c                             |    7 +-
 arch/x86/kvm/vmx/nested.c                          |   11 +-
 drivers/accel/amdxdna/amdxdna_ctx.c                |    8 +
 drivers/accel/ivpu/ivpu_hw_btrs.c                  |    2 +-
 drivers/android/binder/thread.rs                   |   14 +-
 drivers/ata/libata-core.c                          |   18 +
 drivers/ata/libata-scsi.c                          |    2 -
 drivers/ata/libata.h                               |    9 +
 drivers/ata/sata_dwc_460ex.c                       |   38 +-
 drivers/block/rbd.c                                |    7 +-
 drivers/block/ublk_drv.c                           |   52 +-
 drivers/bluetooth/btqca.c                          |    2 +-
 drivers/bluetooth/btusb.c                          |    4 +-
 drivers/bluetooth/hci_qca.c                        |    4 +
 drivers/cdrom/cdrom.c                              |    1 +
 drivers/comedi/drivers/comedi_parport.c            |   13 +-
 drivers/cpufreq/cpufreq.c                          |    3 +
 drivers/crypto/tegra/tegra-se-main.c               |    3 +-
 drivers/cxl/Kconfig                                |    4 +
 drivers/cxl/core/Makefile                          |    2 +-
 drivers/cxl/core/core.h                            |   31 +
 drivers/cxl/core/pci.c                             |  215 +---
 drivers/cxl/core/ras.c                             |  197 ++-
 drivers/cxl/core/trace.h                           |   24 +-
 drivers/cxl/cxl.h                                  |   22 +-
 drivers/cxl/cxlpci.h                               |   16 +
 drivers/dma-buf/udmabuf.c                          |    9 +-
 drivers/dma/dw-edma/dw-edma-pcie.c                 |    7 +-
 drivers/dma/sh/rz-dmac.c                           |   96 +-
 drivers/dpll/dpll_netlink.c                        |    3 +
 drivers/firewire/net.c                             |   37 +-
 drivers/firmware/arm_ffa/driver.c                  |   54 +-
 drivers/firmware/arm_scmi/notify.c                 |    6 +-
 drivers/firmware/stratix10-svc.c                   |   10 +-
 drivers/firmware/xilinx/zynqmp.c                   |    1 +
 drivers/gpu/Kconfig                                |   13 +
 drivers/gpu/Makefile                               |    4 +-
 drivers/gpu/buddy.c                                | 1347 ++++++++++++++++++++
 drivers/gpu/drm/Kconfig                            |    5 +-
 drivers/gpu/drm/Kconfig.debug                      |    1 -
 drivers/gpu/drm/Makefile                           |    1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c            |   13 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c           |   62 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             |    6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |   14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c            |    6 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c            |   10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c            |    3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c         |   13 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c            |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h     |   12 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c            |   54 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c            |   58 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c            |   17 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |   25 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c       |   79 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h       |   20 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c             |   22 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c             |   13 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c             |   13 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c              |    3 -
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c              |   49 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c            |   11 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c           |    2 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c           |    2 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c           |    4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c             |    4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c             |    4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c             |    4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c             |    4 +-
 drivers/gpu/drm/amd/amdgpu/soc24.c                 |   28 +
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c              |   15 +-
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c           |   12 +-
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c  |    6 +
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h  |    2 +
 drivers/gpu/drm/amd/amdkfd/kfd_events.c            |    3 +
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h              |    3 +-
 .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c |   24 +-
 drivers/gpu/drm/amd/amdkfd/kfd_queue.c             |   23 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  374 +++---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c |   81 +-
 .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c   |    9 +-
 .../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c   |    9 +-
 .../gpu/drm/amd/display/dc/link/link_detection.c   |    5 +-
 .../display/dc/resource/dce100/dce100_resource.c   |    7 +-
 .../amd/display/modules/info_packet/info_packet.c  |    2 -
 drivers/gpu/drm/amd/pm/amdgpu_pm.c                 |   26 +-
 drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c     |    7 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   |   11 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c   |   15 +-
 .../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c   |   28 +-
 drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c     |   11 +-
 drivers/gpu/drm/display/drm_dp_mst_topology.c      |   36 +-
 drivers/gpu/drm/drm_buddy.c                        | 1278 +------------------
 drivers/gpu/drm/drm_connector.c                    |   12 +-
 drivers/gpu/drm/drm_displayid_internal.h           |    2 +-
 drivers/gpu/drm/drm_gpusvm.c                       |    4 +-
 drivers/gpu/drm/drm_panel_backlight_quirks.c       |    9 +
 drivers/gpu/drm/i915/display/intel_bios.c          |   36 +-
 drivers/gpu/drm/i915/display/intel_dp.c            |    8 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c          |   12 +-
 drivers/gpu/drm/i915/display/skl_watermark.c       |    2 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c        |   25 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c            |    3 +-
 drivers/gpu/drm/i915/gt/intel_engine_user.c        |    2 +-
 drivers/gpu/drm/i915/gt/selftest_gt_pm.c           |    8 +-
 drivers/gpu/drm/i915/i915_active.c                 |    7 +-
 drivers/gpu/drm/i915/i915_scatterlist.c            |   10 +-
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.c      |   59 +-
 drivers/gpu/drm/i915/i915_ttm_buddy_manager.h      |    4 +-
 .../gpu/drm/i915/selftests/intel_memory_region.c   |   20 +-
 drivers/gpu/drm/imagination/pvr_context.c          |   22 +-
 drivers/gpu/drm/imagination/pvr_drv.c              |   13 +-
 drivers/gpu/drm/imagination/pvr_queue.c            |   65 +-
 drivers/gpu/drm/imagination/pvr_queue.h            |    2 +-
 drivers/gpu/drm/imagination/pvr_vm.c               |    2 +
 drivers/gpu/drm/nouveau/nouveau_exec.c             |    4 +-
 drivers/gpu/drm/nouveau/nouveau_uvmm.c             |    4 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c     |    1 +
 drivers/gpu/drm/panel/Kconfig                      |    1 +
 drivers/gpu/drm/panthor/panthor_device.c           |    5 +-
 drivers/gpu/drm/panthor/panthor_fw.c               |    1 +
 drivers/gpu/drm/radeon/r100.c                      |   13 +-
 drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c     |   18 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |    2 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.c              |    2 +
 drivers/gpu/drm/sysfb/drm_sysfb_helper.h           |    2 +-
 drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c      |   13 +-
 drivers/gpu/drm/sysfb/efidrm.c                     |    7 +-
 drivers/gpu/drm/sysfb/vesadrm.c                    |    6 +-
 drivers/gpu/drm/tests/Makefile                     |    1 -
 drivers/gpu/drm/tests/drm_exec_test.c              |    2 -
 drivers/gpu/drm/tests/drm_gem_shmem_test.c         |   16 +-
 drivers/gpu/drm/tests/drm_mm_test.c                |    2 -
 drivers/gpu/drm/tidss/tidss_encoder.c              |    2 +
 drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c   |    4 +-
 drivers/gpu/drm/ttm/tests/ttm_mock_manager.c       |   18 +-
 drivers/gpu/drm/ttm/tests/ttm_mock_manager.h       |    4 +-
 drivers/gpu/drm/ttm/ttm_pool.c                     |   34 +-
 drivers/gpu/drm/v3d/v3d_gem.c                      |   12 +
 drivers/gpu/drm/vc4/vc4_bo.c                       |   12 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c               |   14 +-
 drivers/gpu/drm/virtio/virtgpu_kms.c               |    5 +-
 drivers/gpu/drm/virtio/virtgpu_vq.c                |    6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c            |   22 +-
 drivers/gpu/drm/xe/xe_bo.c                         |   58 +-
 drivers/gpu/drm/xe/xe_bo.h                         |    3 +-
 drivers/gpu/drm/xe/xe_bo_types.h                   |    2 +
 drivers/gpu/drm/xe/xe_dma_buf.c                    |    2 +-
 drivers/gpu/drm/xe/xe_guc_buf.c                    |   44 +-
 drivers/gpu/drm/xe/xe_guc_buf.h                    |    1 +
 drivers/gpu/drm/xe/xe_i2c.c                        |    5 +-
 drivers/gpu/drm/xe/xe_migrate.c                    |   62 +-
 drivers/gpu/drm/xe/xe_migrate.h                    |    4 +
 drivers/gpu/drm/xe/xe_pt.c                         |   14 +-
 drivers/gpu/drm/xe/xe_res_cursor.h                 |   34 +-
 drivers/gpu/drm/xe/xe_sa.c                         |   67 +-
 drivers/gpu/drm/xe/xe_sa.h                         |   20 +-
 drivers/gpu/drm/xe/xe_sa_types.h                   |    3 +
 drivers/gpu/drm/xe/xe_sriov_vf_ccs.c               |   42 +-
 drivers/gpu/drm/xe/xe_sriov_vf_ccs.h               |    4 +-
 drivers/gpu/drm/xe/xe_svm.c                        |   18 +-
 drivers/gpu/drm/xe/xe_ttm_vram_mgr.c               |   71 +-
 drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h         |    4 +-
 drivers/gpu/drm/xe/xe_vm.c                         |   10 +-
 drivers/gpu/drm/xe/xe_wopcm.c                      |   15 +-
 drivers/gpu/host1x/bus.c                           |    4 +-
 drivers/gpu/tests/Makefile                         |    4 +
 .../drm_buddy_test.c => tests/gpu_buddy_test.c}    |  358 +++---
 .../{drm/lib/drm_random.c => tests/gpu_random.c}   |   18 +-
 .../{drm/lib/drm_random.h => tests/gpu_random.h}   |   18 +-
 drivers/hwmon/asus-ec-sensors.c                    |   18 +-
 drivers/hwmon/corsair-cpro.c                       |    1 +
 drivers/hwmon/corsair-psu.c                        |    1 +
 drivers/hwmon/gigabyte_waterforce.c                |    4 +-
 drivers/hwmon/nzxt-kraken3.c                       |    6 +-
 drivers/hwmon/nzxt-smart2.c                        |    2 +-
 drivers/hwmon/occ/common.c                         |   38 +-
 drivers/hwtracing/intel_th/core.c                  |   10 -
 drivers/hwtracing/intel_th/msu.c                   |    2 +
 drivers/i3c/master/mipi-i3c-hci/core.c             |   16 +-
 drivers/i3c/master/mipi-i3c-hci/hci.h              |    1 +
 drivers/infiniband/core/cma.c                      |    2 +-
 drivers/infiniband/core/mad.c                      |   30 +
 drivers/infiniband/core/umem_dmabuf.c              |   61 +
 drivers/infiniband/hw/erdma/erdma_qp.c             |    2 +-
 drivers/infiniband/hw/hns/hns_roce_hem.c           |    2 +-
 drivers/infiniband/hw/irdma/uk.c                   |    9 +-
 drivers/infiniband/hw/irdma/user.h                 |    1 -
 drivers/infiniband/hw/irdma/verbs.c                |   33 +-
 drivers/infiniband/hw/mana/wr.c                    |    2 +-
 drivers/infiniband/sw/siw/siw_verbs.c              |   44 +-
 drivers/input/misc/ims-pcu.c                       |   32 +-
 drivers/iommu/amd/init.c                           |    6 +
 drivers/iommu/amd/iommu.c                          |   22 +-
 drivers/iommu/intel/perf.c                         |    2 +-
 drivers/iommu/intel/svm.c                          |    2 +-
 drivers/md/dm-verity-fec.c                         |  110 +-
 drivers/md/dm-verity-fec.h                         |    6 +-
 drivers/md/dm.c                                    |   11 +-
 drivers/media/cec/platform/seco/seco-cec.c         |    6 +-
 drivers/media/common/videobuf2/videobuf2-core.c    |   12 +-
 drivers/media/dvb-frontends/rtl2832.c              |    4 +-
 drivers/media/dvb-frontends/rtl2832_sdr.c          |   19 +-
 drivers/media/i2c/alvium-csi2.c                    |   21 +-
 drivers/media/i2c/imx219.c                         |    2 +-
 drivers/media/pci/cx23885/cx23885-core.c           |   14 +-
 drivers/media/pci/dm1105/dm1105.c                  |    1 +
 drivers/media/pci/intel/ipu6/ipu6-isys-dwc-phy.c   |   24 +-
 drivers/media/pci/saa7134/saa7134-video.c          |   25 +-
 .../media/platform/amlogic/c3/isp/c3-isp-params.c  |    4 +
 drivers/media/platform/aspeed/aspeed-video.c       |    1 +
 .../platform/chips-media/wave5/wave5-vpu-enc.c     |   29 +-
 drivers/media/platform/marvell/cafe-driver.c       |    1 +
 drivers/media/platform/nuvoton/npcm-video.c        |   34 +-
 .../media/platform/nxp/imx8-isi/imx8-isi-core.c    |    2 +
 .../media/platform/nxp/imx8-isi/imx8-isi-core.h    |   16 +
 .../platform/nxp/imx8-isi/imx8-isi-crossbar.c      |    1 +
 drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c  |    9 +-
 drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c |   11 +-
 .../media/platform/nxp/imx8-isi/imx8-isi-pipe.c    |   20 +-
 drivers/media/platform/qcom/camss/camss-csid-680.c |   30 +-
 .../media/platform/qcom/camss/camss-csid-gen2.c    |   47 +-
 .../media/platform/qcom/camss/camss-csid-gen3.c    |   28 +-
 drivers/media/platform/qcom/iris/iris_probe.c      |    6 +-
 .../platform/renesas/rzg2l-cru/rzg2l-cru-regs.h    |    1 +
 .../media/platform/renesas/rzg2l-cru/rzg2l-video.c |   17 +-
 drivers/media/platform/st/stm32/stm32-dcmi.c       |    1 +
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c         |    6 +-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c |    6 +-
 .../media/platform/synopsys/hdmirx/snps_hdmirx.c   |    4 +-
 drivers/media/platform/ti/davinci/vpif_capture.c   |    2 +-
 drivers/media/platform/ti/vpe/vpe.c                |    3 +-
 drivers/media/platform/verisilicon/hantro_v4l2.c   |    6 +-
 drivers/media/radio/radio-si476x.c                 |    1 +
 drivers/media/test-drivers/vidtv/vidtv_bridge.c    |    4 +-
 drivers/media/test-drivers/vimc/vimc-core.c        |    1 +
 drivers/media/test-drivers/vivid/vivid-core.c      |    6 +-
 drivers/media/test-drivers/vivid/vivid-ctrls.c     |   15 +-
 drivers/media/test-drivers/vivid/vivid-vid-cap.c   |   38 +-
 drivers/media/test-drivers/vivid/vivid-vid-cap.h   |    1 +
 drivers/media/test-drivers/vivid/vivid-vid-out.c   |    6 +
 drivers/media/usb/airspy/airspy.c                  |    8 +-
 drivers/media/usb/cx231xx/cx231xx-cards.c          |   16 +-
 drivers/media/usb/msi2500/msi2500.c                |   32 +-
 drivers/media/usb/pwc/pwc-if.c                     |   13 +-
 drivers/media/v4l2-core/v4l2-ctrls-core.c          |   13 +
 drivers/media/v4l2-core/v4l2-ctrls-request.c       |   14 +-
 drivers/media/v4l2-core/v4l2-fwnode.c              |    6 +-
 drivers/media/v4l2-core/v4l2-subdev.c              |    4 +
 drivers/misc/mei/bus.c                             |   16 +-
 drivers/misc/nsm.c                                 |    3 +-
 drivers/mmc/host/vub300.c                          |   24 +-
 drivers/mtd/maps/vmu-flash.c                       |    8 +-
 drivers/mtd/mtdcore.c                              |   23 +-
 drivers/mtd/mtdswap.c                              |    5 +-
 drivers/mtd/nand/ecc-mtk.c                         |   16 +-
 drivers/net/amt.c                                  |  101 +-
 drivers/net/bonding/bond_main.c                    |    3 +-
 drivers/net/ethernet/airoha/airoha_eth.c           |    3 +-
 drivers/net/ethernet/airoha/airoha_npu.c           |    4 +-
 drivers/net/ethernet/airoha/airoha_ppe.c           |    1 +
 drivers/net/ethernet/amd/pds_core/adminq.c         |   12 +-
 drivers/net/ethernet/amd/pds_core/auxbus.c         |   17 +-
 drivers/net/ethernet/amd/pds_core/core.c           |   22 +-
 drivers/net/ethernet/amd/pds_core/devlink.c        |    6 +
 drivers/net/ethernet/amd/pds_core/main.c           |   14 +-
 drivers/net/ethernet/amd/xgbe/xgbe-mdio.c          |   11 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   |    1 +
 .../net/ethernet/freescale/dpaa2/dpaa2-switch.c    |    1 +
 drivers/net/ethernet/freescale/fman/fman_dtsec.c   |   17 +-
 drivers/net/ethernet/google/gve/gve.h              |    3 +
 drivers/net/ethernet/google/gve/gve_rx_dqo.c       |   34 +
 drivers/net/ethernet/hisilicon/hip04_eth.c         |   11 +-
 drivers/net/ethernet/huawei/hinic/hinic_dev.h      |    2 -
 drivers/net/ethernet/huawei/hinic/hinic_ethtool.c  |   21 -
 drivers/net/ethernet/intel/ice/ice.h               |    3 +
 drivers/net/ethernet/intel/ice/ice_eswitch.c       |    3 -
 drivers/net/ethernet/intel/ice/ice_lag.c           |    2 +-
 drivers/net/ethernet/intel/ice/ice_parser.c        |    3 +
 drivers/net/ethernet/intel/ice/ice_ptp.c           |    7 +-
 drivers/net/ethernet/intel/ice/ice_sriov.c         |   14 +-
 drivers/net/ethernet/intel/ice/ice_vf_lib.c        |    3 +-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.c    |    2 +-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.h    |    1 +
 .../net/ethernet/marvell/octeontx2/af/rvu_cn10k.c  |    9 +
 .../net/ethernet/marvell/octeontx2/af/rvu_rep.c    |    8 +
 .../ethernet/marvell/octeontx2/nic/otx2_flows.c    |    1 +
 .../net/ethernet/marvell/octeontx2/nic/otx2_tc.c   |   29 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c |   15 +
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   |   19 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |    4 +-
 .../ethernet/mellanox/mlx5/core/esw/acl/helper.c   |    2 +-
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |    4 +-
 drivers/net/ethernet/mellanox/mlx5/core/port.c     |   39 +-
 drivers/net/ethernet/microsoft/mana/gdma_main.c    |   78 +-
 drivers/net/ethernet/microsoft/mana/mana_en.c      |   13 +
 .../ethernet/netronome/nfp/nfpcore/nfp_resource.c  |    3 +
 drivers/net/ethernet/realtek/rtase/rtase.h         |    8 +
 drivers/net/ethernet/realtek/rtase/rtase_main.c    |  197 +++
 drivers/net/ethernet/stmicro/stmmac/common.h       |    3 -
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c  |   31 +
 .../net/ethernet/stmicro/stmmac/dwmac-loongson.c   |    5 +-
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  162 ++-
 drivers/net/ethernet/stmicro/stmmac/dwmac100.h     |    9 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac1000.h    |   16 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |   49 +-
 .../net/ethernet/stmicro/stmmac/dwmac1000_dma.c    |   16 +-
 .../net/ethernet/stmicro/stmmac/dwmac100_core.c    |    2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c |    3 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h       |   49 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |   53 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   |   44 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h   |   16 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c   |    2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h    |   10 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c    |   10 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     |   34 +-
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    |   45 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c |   75 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   92 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c    |   35 +
 drivers/net/ethernet/wangxun/txgbe/txgbe_main.c    |    1 +
 drivers/net/geneve.c                               |    3 +
 drivers/net/gtp.c                                  |   17 +-
 drivers/net/ipa/ipa_smp2p.c                        |   30 +-
 drivers/net/mctp/mctp-i3c.c                        |   11 +-
 drivers/net/mctp/mctp-serial.c                     |    2 +-
 drivers/net/ovpn/io.c                              |    4 +-
 drivers/net/ovpn/peer.c                            |   16 +-
 drivers/net/ovpn/tcp.c                             |    6 +-
 drivers/net/pcs/pcs-xpcs.c                         |   34 +-
 drivers/net/phy/marvell.c                          |    2 +-
 drivers/net/ppp/ppp_generic.c                      |  239 ++--
 drivers/net/ppp/pppoe.c                            |    1 +
 drivers/net/slip/slip.c                            |    4 +
 drivers/net/vmxnet3/vmxnet3_drv.c                  |   22 +-
 drivers/net/vxlan/vxlan_core.c                     |    3 +
 drivers/net/vxlan/vxlan_mdb.c                      |   30 +-
 drivers/net/wan/wanxl.c                            |    3 +-
 drivers/net/wireless/ath/ath11k/ahb.c              |    1 +
 drivers/net/wireless/ath/ath11k/dp_rx.c            |    3 +
 drivers/net/wireless/ath/ath11k/pci.c              |    4 +
 drivers/net/wireless/ath/ath11k/qmi.c              |   11 +-
 drivers/net/wireless/ath/ath12k/pci.c              |    4 +
 drivers/net/wireless/ath/ath6kl/txrx.c             |   12 +-
 drivers/net/wireless/ath/ath6kl/wmi.c              |   20 +
 drivers/net/wireless/ath/ath9k/hif_usb.c           |    7 +-
 drivers/net/wireless/ath/carl9170/rx.c             |    7 +-
 drivers/net/wireless/ath/carl9170/tx.c             |    2 +-
 drivers/net/wireless/atmel/at76c50x-usb.c          |    7 +-
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  |    1 +
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         |    2 +-
 .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |    8 +-
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |    2 +-
 drivers/net/wireless/intel/ipw2x00/ipw2100.c       |    8 +-
 drivers/net/wireless/intel/iwlwifi/fw/pnvm.c       |    9 +-
 drivers/net/wireless/intel/iwlwifi/fw/regulatory.c |    2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c        |    3 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c        |   10 +
 drivers/net/wireless/intersil/p54/txrx.c           |    8 +
 drivers/net/wireless/marvell/libertas/firmware.c   |    1 +
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   |   14 +-
 drivers/net/wireless/marvell/mwifiex/tdls.c        |    2 +-
 drivers/net/wireless/marvell/mwifiex/uap_event.c   |   24 +-
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c    |    6 +
 .../net/wireless/mediatek/mt76/mt76_connac_mcu.c   |    2 +
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c    |   18 +-
 drivers/net/wireless/mediatek/mt76/mt7921/mac.c    |   10 +-
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c    |   13 +-
 drivers/net/wireless/mediatek/mt76/mt7925/main.c   |    3 +
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c    |    2 +
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c    |   19 +-
 drivers/net/wireless/microchip/wilc1000/hif.c      |    5 +
 drivers/net/wireless/virtual/mac80211_hwsim.c      |    1 +
 drivers/pinctrl/renesas/pinctrl-rzg2l.c            |    8 +-
 drivers/platform/loongarch/loongson-laptop.c       |    1 +
 .../uncore-frequency/uncore-frequency-common.c     |    7 +-
 drivers/pmdomain/imx/imx93-blk-ctrl.c              |  126 +-
 drivers/ptp/ptp_netc.c                             |    1 +
 drivers/ptp/ptp_s390.c                             |    6 +-
 drivers/regulator/mt6358-regulator.c               |    2 +-
 drivers/remoteproc/xlnx_r5_remoteproc.c            |   50 +-
 drivers/scsi/hosts.c                               |    2 +
 drivers/scsi/scsi_error.c                          |   22 +-
 drivers/scsi/scsi_priv.h                           |    1 +
 drivers/staging/media/meson/vdec/vdec.c            |    4 +-
 drivers/staging/media/sunxi/cedrus/cedrus.c        |    6 +-
 drivers/staging/media/sunxi/cedrus/cedrus_h264.c   |    3 +
 drivers/staging/media/tegra-video/vi.c             |    4 +-
 drivers/staging/rtl8723bs/core/rtw_ieee80211.c     |    9 +-
 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c  |    2 +-
 drivers/thunderbolt/debugfs.c                      |    2 +
 drivers/thunderbolt/domain.c                       |   30 +
 drivers/thunderbolt/icm.c                          |    5 +
 drivers/thunderbolt/switch.c                       |   14 +
 drivers/thunderbolt/tb.c                           |   59 +-
 drivers/thunderbolt/tb.h                           |    2 +
 drivers/thunderbolt/xdomain.c                      |  100 +-
 drivers/tty/serial/8250/8250_mid.c                 |   14 +-
 drivers/tty/serial/sc16is7xx.c                     |   12 +
 drivers/uio/uio_hv_generic.c                       |    8 +-
 drivers/usb/atm/ueagle-atm.c                       |   17 +
 drivers/usb/chipidea/core.c                        |    1 +
 drivers/usb/core/port.c                            |    2 +
 drivers/usb/core/sysfs.c                           |    8 +-
 drivers/usb/gadget/function/f_midi.c               |    1 +
 drivers/usb/gadget/function/f_ncm.c                |   17 +-
 drivers/usb/gadget/function/f_printer.c            |   23 +-
 drivers/usb/gadget/function/f_tcm.c                |  192 ++-
 drivers/usb/gadget/function/tcm.h                  |   13 +
 drivers/usb/gadget/function/uvc_v4l2.c             |    2 +
 drivers/usb/gadget/udc/bdc/bdc_core.c              |   20 +
 drivers/usb/gadget/udc/bdc/bdc_udc.c               |    7 +-
 drivers/usb/gadget/udc/dummy_hcd.c                 |   40 +-
 drivers/usb/gadget/udc/fsl_udc_core.c              |   93 +-
 drivers/usb/gadget/udc/fsl_usb2_udc.h              |    1 +
 drivers/usb/gadget/udc/snps_udc_core.c             |    1 -
 drivers/usb/host/xhci-pci.c                        |    1 +
 drivers/usb/host/xhci.c                            |   15 +-
 drivers/usb/host/xhci.h                            |    1 +
 drivers/usb/musb/omap2430.c                        |    2 -
 drivers/usb/serial/ftdi_sio.c                      |    2 +
 drivers/usb/serial/ftdi_sio_ids.h                  |    5 +
 drivers/usb/serial/io_edgeport.c                   |    3 +-
 drivers/usb/serial/keyspan_pda.c                   |   44 +-
 drivers/usb/serial/option.c                        |    1 +
 drivers/usb/storage/unusual_devs.h                 |    7 +
 drivers/usb/typec/ucsi/ucsi.c                      |  158 ++-
 drivers/vdpa/vdpa_user/iova_domain.c               |   29 +-
 drivers/vdpa/vdpa_user/iova_domain.h               |    8 +-
 drivers/vdpa/vdpa_user/vduse_dev.c                 |  112 +-
 drivers/vhost/net.c                                |    8 +-
 drivers/video/Kconfig                              |    1 +
 drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c      |    2 +-
 drivers/watchdog/airoha_wdt.c                      |    3 +
 drivers/watchdog/s32g_wdt.c                        |    3 +-
 drivers/watchdog/watchdog_pretimeout.c             |    2 +
 fs/afs/dir_edit.c                                  |    2 +-
 fs/binfmt_elf_fdpic.c                              |    4 +
 fs/binfmt_misc.c                                   |    5 +-
 fs/btrfs/backref.c                                 |   16 +-
 fs/btrfs/block-group.c                             |    8 +-
 fs/btrfs/ctree.c                                   |   28 +-
 fs/btrfs/ctree.h                                   |   16 +-
 fs/btrfs/defrag.c                                  |    4 +-
 fs/btrfs/dev-replace.c                             |    4 +-
 fs/btrfs/extent-tree.c                             |    8 +-
 fs/btrfs/extent_io.c                               |    4 +-
 fs/btrfs/extent_map.c                              |    4 +-
 fs/btrfs/file-item.c                               |   38 +-
 fs/btrfs/free-space-cache.c                        |    7 +-
 fs/btrfs/free-space-tree.c                         |    4 +-
 fs/btrfs/inode-item.c                              |    2 +-
 fs/btrfs/inode.c                                   |    4 +-
 fs/btrfs/qgroup.c                                  |    4 +-
 fs/btrfs/raid-stripe-tree.c                        |    4 +-
 fs/btrfs/relocation.c                              |   10 +-
 fs/btrfs/scrub.c                                   |   20 +-
 fs/btrfs/send.c                                    |   14 +-
 fs/btrfs/tree-log.c                                |   20 +-
 fs/btrfs/volumes.c                                 |    6 +-
 fs/btrfs/xattr.c                                   |    2 +-
 fs/ceph/addr.c                                     |    9 +
 fs/ceph/caps.c                                     |    1 +
 fs/ceph/dir.c                                      |    7 +-
 fs/ceph/ioctl.c                                    |    6 +
 fs/crypto/inline_crypt.c                           |   57 +-
 fs/crypto/keysetup_v1.c                            |    8 +-
 fs/exec.c                                          |    2 +-
 fs/f2fs/super.c                                    |   25 +-
 fs/fuse/dev_uring.c                                |   22 +-
 fs/fuse/file.c                                     |    5 +-
 fs/iomap/buffered-io.c                             |   34 +-
 fs/nfsd/nfs4xdr.c                                  |    8 +-
 fs/nfsd/vfs.c                                      |   15 +-
 fs/nfsd/vfs.h                                      |    2 +-
 fs/overlayfs/copy_up.c                             |   12 +-
 fs/overlayfs/file.c                                |   47 +-
 fs/overlayfs/overlayfs.h                           |    5 +
 fs/overlayfs/xattrs.c                              |    2 +-
 fs/posix_acl.c                                     |    7 +
 fs/proc/namespaces.c                               |    4 +-
 fs/proc/task_mmu.c                                 |   14 +-
 fs/resctrl/ctrlmondata.c                           |    6 +-
 fs/resctrl/internal.h                              |   22 +-
 fs/resctrl/monitor.c                               |  200 +--
 fs/resctrl/rdtgroup.c                              |   75 +-
 fs/smb/client/misc.c                               |   34 +-
 fs/smb/client/smb2file.c                           |   21 +
 fs/smb/client/smb2inode.c                          |   23 +-
 fs/smb/client/smb2ops.c                            |   25 +-
 fs/smb/server/oplock.c                             |    6 +-
 fs/smb/server/smb2misc.c                           |    5 +
 fs/smb/server/smb2pdu.c                            |    9 +-
 fs/smb/server/smbacl.c                             |   42 +-
 fs/super.c                                         |   34 +-
 fs/xfs/scrub/cow_repair.c                          |  203 +--
 fs/xfs/scrub/trace.h                               |   28 +-
 include/drm/drm_buddy.h                            |  165 +--
 include/drm/drm_connector.h                        |    6 +-
 include/drm/drm_utils.h                            |    1 +
 include/linux/arm_ffa.h                            |    2 +-
 include/linux/audit.h                              |    6 +-
 include/linux/audit_arch.h                         |   12 +-
 include/linux/bootconfig.h                         |    3 +
 include/linux/cred.h                               |   15 +
 include/linux/firmware/xlnx-zynqmp.h               |   13 +
 include/linux/fscrypt.h                            |   18 +-
 include/linux/gpu_buddy.h                          |  177 +++
 include/linux/mlx5/mlx5_ifc.h                      |   13 +-
 include/linux/resctrl.h                            |   28 +-
 include/linux/seqlock.h                            |   10 +-
 include/linux/sunrpc/svcsock.h                     |    3 +
 include/linux/sunrpc/xdr.h                         |   19 +-
 include/linux/virtio.h                             |    6 +-
 include/linux/vtime.h                              |    6 +
 include/media/v4l2-async.h                         |    4 +-
 include/media/videobuf2-core.h                     |    8 +-
 include/net/bluetooth/rfcomm.h                     |    3 +
 include/net/cfg80211.h                             |    2 +-
 include/net/dropreason-core.h                      |    3 +
 include/net/ip6_tunnel.h                           |    2 +-
 include/net/netfilter/nf_tables.h                  |   32 -
 include/net/netfilter/nft_fib.h                    |    2 -
 include/net/netfilter/nft_meta.h                   |    3 -
 include/net/sctp/structs.h                         |    3 +-
 include/net/tcp.h                                  |    2 +
 include/rdma/ib_umem.h                             |   19 +
 include/scsi/scsi_host.h                           |    3 +
 include/uapi/linux/btrfs.h                         |    2 +-
 init/Kconfig                                       |    3 +
 init/main.c                                        |   45 -
 io_uring/rw.c                                      |   42 +-
 kernel/audit.c                                     |    2 +-
 kernel/audit.h                                     |   32 +-
 kernel/audit_fsnotify.c                            |   36 +-
 kernel/audit_tree.c                                |    2 +-
 kernel/audit_watch.c                               |   35 +-
 kernel/auditfilter.c                               |   17 +-
 kernel/auditsc.c                                   |    6 +-
 kernel/bpf/verifier.c                              |   17 +
 kernel/kexec_handover.c                            |   32 +-
 kernel/sched/ext.c                                 |    9 +-
 kernel/trace/ftrace.c                              |   13 +
 kernel/trace/trace.c                               |    2 +-
 kernel/trace/trace_eprobe.c                        |    3 +-
 kernel/trace/trace_events.c                        |    4 +-
 kernel/trace/trace_mmiotrace.c                     |    4 +-
 kernel/trace/trace_probe.c                         |   13 +-
 lib/bootconfig.c                                   |   65 +
 lib/compat_audit.c                                 |   12 +-
 lib/rhashtable.c                                   |    1 +
 mm/damon/core.c                                    |   13 +
 mm/huge_memory.c                                   |   12 +-
 mm/kmemleak.c                                      |    7 +-
 mm/sparse.c                                        |   32 +-
 net/bluetooth/hci_sync.c                           |   55 +-
 net/bluetooth/mgmt.c                               |   86 +-
 net/bluetooth/rfcomm/core.c                        |   17 +
 net/bluetooth/rfcomm/tty.c                         |    7 +-
 net/bridge/br_netlink_tunnel.c                     |    3 +-
 net/bridge/br_private.h                            |    6 +-
 net/bridge/br_vlan.c                               |   10 +-
 net/bridge/br_vlan_options.c                       |    3 +-
 net/bridge/netfilter/nft_meta_bridge.c             |   20 -
 net/bridge/netfilter/nft_reject_bridge.c           |    1 -
 net/can/bcm.c                                      |  528 ++++++--
 net/can/j1939/transport.c                          |   18 +-
 net/can/raw.c                                      |   66 +-
 net/ceph/auth_x.c                                  |    9 +-
 net/ceph/ceph_common.c                             |    4 +-
 net/ceph/mon_client.c                              |    4 +-
 net/ceph/osdmap.c                                  |   12 +-
 net/core/dev.c                                     |  111 +-
 net/core/filter.c                                  |    6 +-
 net/core/gro.c                                     |    4 +-
 net/core/sock.c                                    |   10 +-
 net/core/sock_map.c                                |    2 +
 net/hsr/hsr_slave.c                                |    2 +
 net/ipv4/datagram.c                                |    4 +-
 net/ipv4/fib_trie.c                                |    2 +-
 net/ipv4/icmp.c                                    |   18 +-
 net/ipv4/ip_gre.c                                  |    4 +-
 net/ipv4/ip_tunnel_core.c                          |    2 +-
 net/ipv4/netfilter/nft_dup_ipv4.c                  |    1 -
 net/ipv4/netfilter/nft_fib_ipv4.c                  |    2 -
 net/ipv4/netfilter/nft_reject_ipv4.c               |    1 -
 net/ipv4/nexthop.c                                 |    2 +-
 net/ipv4/raw.c                                     |   23 +-
 net/ipv4/tcp_bpf.c                                 |    2 +-
 net/ipv4/tcp_input.c                               |   56 +-
 net/ipv4/tcp_ipv4.c                                |   14 +-
 net/ipv4/tcp_minisocks.c                           |   12 +-
 net/ipv6/ila/ila_common.c                          |   12 +
 net/ipv6/ip6_gre.c                                 |    4 +-
 net/ipv6/netfilter/nft_dup_ipv6.c                  |    1 -
 net/ipv6/netfilter/nft_fib_ipv6.c                  |    2 -
 net/ipv6/netfilter/nft_reject_ipv6.c               |    1 -
 net/ipv6/raw.c                                     |    2 +-
 net/ipv6/route.c                                   |    4 +-
 net/ipv6/tcp_ipv6.c                                |    8 +-
 net/ipv6/xfrm6_policy.c                            |    1 +
 net/iucv/af_iucv.c                                 |   21 +-
 net/mac80211/cfg.c                                 |   11 +-
 net/mac80211/iface.c                               |    8 +-
 net/mac80211/link.c                                |    4 +
 net/mac80211/mlme.c                                |    6 +-
 net/mac80211/rx.c                                  |    2 +
 net/mac80211/sta_info.c                            |   15 +-
 net/mac802154/llsec.c                              |    5 +
 net/mac802154/scan.c                               |   11 +
 net/mctp/device.c                                  |    4 +-
 net/mpls/af_mpls.c                                 |    3 +
 net/mptcp/options.c                                |   12 +-
 net/mptcp/pm_userspace.c                           |    7 +-
 net/mptcp/protocol.c                               |    1 +
 net/netfilter/nf_conntrack_sip.c                   |   10 +-
 net/netfilter/nf_tables_api.c                      |  315 +----
 net/netfilter/nft_bitwise.c                        |  104 --
 net/netfilter/nft_byteorder.c                      |   11 -
 net/netfilter/nft_cmp.c                            |    3 -
 net/netfilter/nft_compat.c                         |   10 -
 net/netfilter/nft_connlimit.c                      |    1 -
 net/netfilter/nft_counter.c                        |   21 +-
 net/netfilter/nft_ct.c                             |   46 -
 net/netfilter/nft_dup_netdev.c                     |    1 -
 net/netfilter/nft_dynset.c                         |    1 -
 net/netfilter/nft_exthdr.c                         |   34 -
 net/netfilter/nft_fib.c                            |   51 +-
 net/netfilter/nft_fib_inet.c                       |    1 -
 net/netfilter/nft_fib_netdev.c                     |   30 +-
 net/netfilter/nft_flow_offload.c                   |    1 -
 net/netfilter/nft_fwd_netdev.c                     |    2 -
 net/netfilter/nft_hash.c                           |   36 -
 net/netfilter/nft_immediate.c                      |   12 -
 net/netfilter/nft_last.c                           |    1 -
 net/netfilter/nft_limit.c                          |    2 -
 net/netfilter/nft_log.c                            |    1 -
 net/netfilter/nft_lookup.c                         |   12 -
 net/netfilter/nft_masq.c                           |    3 -
 net/netfilter/nft_meta.c                           |   45 -
 net/netfilter/nft_nat.c                            |    2 -
 net/netfilter/nft_numgen.c                         |   22 -
 net/netfilter/nft_objref.c                         |    2 -
 net/netfilter/nft_osf.c                            |   25 -
 net/netfilter/nft_payload.c                        |   47 -
 net/netfilter/nft_queue.c                          |    2 -
 net/netfilter/nft_quota.c                          |   14 +-
 net/netfilter/nft_range.c                          |    1 -
 net/netfilter/nft_redir.c                          |    3 -
 net/netfilter/nft_reject_inet.c                    |    1 -
 net/netfilter/nft_reject_netdev.c                  |    1 -
 net/netfilter/nft_rt.c                             |    1 -
 net/netfilter/nft_socket.c                         |   26 -
 net/netfilter/nft_synproxy.c                       |    1 -
 net/netfilter/nft_tproxy.c                         |    1 -
 net/netfilter/nft_tunnel.c                         |   26 -
 net/netfilter/nft_xfrm.c                           |   27 -
 net/openvswitch/actions.c                          |   19 +-
 net/openvswitch/datapath.c                         |   25 +-
 net/openvswitch/datapath.h                         |    2 +-
 net/openvswitch/vport.c                            |    2 +-
 net/packet/af_packet.c                             |    6 +-
 net/phonet/pep.c                                   |    2 +
 net/qrtr/af_qrtr.c                                 |    8 +
 net/qrtr/ns.c                                      |    4 +-
 net/rds/recv.c                                     |   15 +
 net/rds/tcp.c                                      |    4 +-
 net/rxrpc/ar-internal.h                            |    6 +-
 net/sched/act_tunnel_key.c                         |   14 +-
 net/sctp/auth.c                                    |    2 +-
 net/sctp/protocol.c                                |   21 +-
 net/sctp/sm_make_chunk.c                           |    6 +
 net/sctp/sm_statefuns.c                            |    2 +-
 net/sctp/stream.c                                  |    6 +-
 net/sctp/sysctl.c                                  |    9 +-
 net/sunrpc/svcsock.c                               |   69 +-
 net/sunrpc/xdr.c                                   |  210 ++-
 net/sunrpc/xprtrdma/rpc_rdma.c                     |    4 +
 net/sunrpc/xprtrdma/verbs.c                        |   12 +-
 net/tipc/netlink.c                                 |    6 +-
 net/tipc/netlink_compat.c                          |    4 +
 net/tipc/socket.c                                  |    1 +
 net/tls/tls_device.c                               |    6 +-
 net/vmw_vsock/virtio_transport_common.c            |  165 ++-
 net/wireless/core.c                                |    4 +-
 net/wireless/core.h                                |    2 +-
 net/wireless/nl80211.c                             |   22 +-
 net/wireless/pmsr.c                                |   29 +-
 net/wireless/scan.c                                |   13 +-
 net/x25/af_x25.c                                   |    8 +-
 net/xfrm/xfrm_device.c                             |   12 +-
 net/xfrm/xfrm_iptfs.c                              |    1 +
 net/xfrm/xfrm_policy.c                             |    4 +-
 net/xfrm/xfrm_state.c                              |    7 +-
 net/xfrm/xfrm_user.c                               |    3 +-
 rust/bindings/lib.rs                               |    4 +
 rust/kernel/device.rs                              |   16 +-
 rust/kernel/time.rs                                |   11 +-
 rust/uapi/lib.rs                                   |    4 +
 security/landlock/domain.c                         |    8 +-
 security/landlock/domain.h                         |    5 +-
 security/landlock/ruleset.c                        |    7 +-
 sound/core/seq/seq_timer.c                         |   13 +-
 sound/core/timer.c                                 |   21 +-
 sound/hda/codecs/hdmi/hdmi.c                       |    3 +
 sound/hda/codecs/hdmi/hdmi_local.h                 |    9 +
 sound/hda/codecs/hdmi/intelhdmi.c                  |   36 +-
 sound/hda/codecs/realtek/alc269.c                  |    9 +
 sound/hda/codecs/side-codecs/cs35l41_hda.c         |   11 +-
 sound/soc/amd/ps/pci-ps.c                          |   33 +-
 sound/soc/codecs/bt-sco.c                          |   10 +-
 sound/soc/codecs/cs35l56-i2c.c                     |    4 +-
 sound/soc/codecs/cs35l56-spi.c                     |    4 +-
 sound/soc/codecs/cs35l56.c                         |   25 +-
 sound/soc/codecs/cs42l43-jack.c                    |    3 +-
 sound/soc/codecs/tas2562.c                         |    5 +-
 sound/soc/codecs/tas2781-fmwlib.c                  |   63 +-
 sound/soc/fsl/fsl_sai.c                            |   29 +-
 sound/soc/fsl/imx-card.c                           |   12 +-
 sound/soc/meson/aiu-fifo-spdif.c                   |    5 +
 sound/soc/sunxi/sun4i-codec.c                      |    1 +
 sound/usb/quirks.c                                 |    2 +
 tools/objtool/check.c                              |    1 +
 tools/testing/cxl/Kbuild                           |    2 +-
 tools/testing/selftests/alsa/mixer-test.c          |    1 +
 .../testing/selftests/bpf/progs/verifier_ld_ind.c  |  142 +++
 .../testing/selftests/bpf/progs/verifier_map_ptr.c |   36 +-
 tools/testing/selftests/drivers/net/settings       |    1 +
 tools/testing/selftests/drivers/ntsync/config      |    2 +-
 tools/testing/selftests/ftrace/ftracetest          |    1 +
 tools/testing/selftests/net/af_unix/config         |    1 +
 tools/testing/selftests/net/openvswitch/config     |   16 +
 tools/testing/selftests/net/ovpn/config            |    2 +
 tools/testing/selftests/net/ovpn/ovpn-cli.c        |    4 +-
 tools/testing/selftests/net/ovpn/settings          |    1 +
 776 files changed, 10812 insertions(+), 6601 deletions(-)
author maintainer
#1 lore raw

PATCH 1/675 platform/x86/intel-uncore-freq: Fix current_freq_khz after CPU hotplug

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guixiong Wei <[email protected]>

commit 6b63520ed14b17bbe9c2103debbd2152dde1fba3 upstream.

When the last CPU of a legacy uncore die goes offline, uncore_freq_remove_die_entry() clears control_cpu. During CPU hotplug re-add, uncore_freq_add_entry() still populates sysfs attributes before assigning the new control CPU. As a result, the current frequency read returns -ENXIO and current_freq_khz is omitted from the recreated sysfs group.

Assign control_cpu before the initial read paths and before create_attr_group() so sysfs recreation uses the new online CPU. If sysfs creation fails, restore control_cpu to -1 to keep the error path state consistent.

Fixes 4d73c6772ab7 ("platform/x86: intel-uncore-freq: Conditionally create attribute for read frequency")
---
 .../x86/intel/uncore-frequency/uncore-frequency-common.c   | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +6 -1
index 65897fae17dfba..6091b617480ff6 100644
@@ -274,15 +274,20 @@ int uncore_freq_add_entry(struct uncore_data *data, int cpu)
 		sprintf(data->name, "package_%02d_die_%02d", data->package_id, data->die_id);
 	}
 
+	/*
+	 * Set the control CPU before any read path so entry recreation after CPU
+	 * hotplug can populate read-only attributes from the new online CPU.
+	 */
+	data->control_cpu = cpu;
 	uncore_read(data, &data->initial_min_freq_khz, UNCORE_INDEX_MIN_FREQ);
 	uncore_read(data, &data->initial_max_freq_khz, UNCORE_INDEX_MAX_FREQ);
 
 	ret = create_attr_group(data, data->name);
 	if (ret) {
+		data->control_cpu = -1;
 		if (data->domain_id != UNCORE_DOMAIN_ID_INVALID)
 			ida_free(&intel_uncore_ida, data->instance_id);
 	} else {
-		data->control_cpu = cpu;
 		data->valid = true;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#2 lore raw

PATCH 2/675 bpf: Fix ld_{abs,ind} failure path analysis in subprogs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <[email protected]>

commit ee861486e377edc55361c08dcbceab3f6b6577bd upstream.

Usage of ld_{abs,ind} instructions got extended into subprogs some time ago via commit 09b28d76eac4 ("bpf: Add abnormal return checks."). These are only allowed in subprograms when the latter are BTF annotated and have scalar return types.

The code generator in bpf_gen_ld_abs() has an abnormal exit path (r0=0 + exit) from legacy cBPF times. While the enforcement is on scalar return types, the verifier must also simulate the path of abnormal exit if the packet data load via ld_{abs,ind} failed.

This is currently not the case. Fix it by having the verifier simulate both success and failure paths, and extend it in similar ways as we do for tail calls. The success path (r0=unknown, continue to next insn) is pushed onto stack for later validation and the r0=0 and return to the caller is done on the fall-through side.

[ Dropped visit_abnormal_return_insn changes: depends on 7.0 symbols from
e40f5a6bf88a ("bpf: correct stack liveness for tail calls");
Hunk1: adapted IS_ERR/PTR_ERR to !branch/-EFAULT to match push_stack() NULL-on-failure convention. ]

---
 kernel/bpf/verifier.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
kernel/bpf/verifier.c +17 -0
index d1c51d812f3b66..463455180a8e35 100644
@@ -17402,6 +17402,23 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
 	mark_reg_unknown(env, regs, BPF_REG_0);
 	/* ld_abs load up to 32-bit skb data. */
 	regs[BPF_REG_0].subreg_def = env->insn_idx + 1;
+	/*
+	 * See bpf_gen_ld_abs() which emits a hidden BPF_EXIT with r0=0
+	 * which must be explored by the verifier when in a subprog.
+	 */
+	if (env->cur_state->curframe) {
+		struct bpf_verifier_state *branch;
+
+		mark_reg_scratched(env, BPF_REG_0);
+		branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
+		if (!branch)
+			return -EFAULT;
+		mark_reg_known_zero(env, regs, BPF_REG_0);
+		err = prepare_func_exit(env, &env->insn_idx);
+		if (err)
+			return err;
+		env->insn_idx--;
+	}
 	return 0;
 }
 
Signature · 1 line
2.53.0
author maintainer
#3 lore raw

PATCH 3/675 selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <[email protected]>

commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream.

Extend the verifier_ld_ind BPF selftests with subprogs containing ld_{abs,ind} and craft the test in a way where the invalid register read is rejected in the fixed case. Also add a success case each, and add additional coverage related to the BTF return type enforcement.

# LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind [...]

  #611/1   verifier_ld_ind/ld_ind: check calling conv, r1:OK
  #611/2   verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK
  #611/3   verifier_ld_ind/ld_ind: check calling conv, r2:OK
  #611/4   verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK
  #611/5   verifier_ld_ind/ld_ind: check calling conv, r3:OK
  #611/6   verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK
  #611/7   verifier_ld_ind/ld_ind: check calling conv, r4:OK
  #611/8   verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK
  #611/9   verifier_ld_ind/ld_ind: check calling conv, r5:OK
  #611/10  verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK
  #611/11  verifier_ld_ind/ld_ind: check calling conv, r7:OK
  #611/12  verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK
  #611/13  verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK
  #611/14  verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK
  #611/15  verifier_ld_ind/ld_abs: subprog with both paths safe:OK
  #611/16  verifier_ld_ind/ld_ind: subprog with both paths safe:OK
  #611/17  verifier_ld_ind/ld_abs: reject void return subprog:OK
  #611/18  verifier_ld_ind/ld_ind: reject void return subprog:OK
  #611     verifier_ld_ind:OK

Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED

---
 .../selftests/bpf/progs/verifier_ld_ind.c     | 142 ++++++++++++++++++
 1 file changed, 142 insertions(+)
tools/testing/selftests/bpf/progs/verifier_ld_ind.c +142 -0
index c925ba9a2e74c2..09e81b99eecb4e 100644
@@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void)
 	: __clobber_all);
 }
 
+/*
+ * ld_{abs,ind} subprog that always sets r0=1 on the success path.
+ * bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper
+ * fails. The verifier must model this failure return so that callers
+ * account for r0=0 as a possible return value.
+ */
+__naked __noinline __used
+static int ldabs_subprog(void)
+{
+	asm volatile (
+	"r6 = r1;"
+	".8byte %[ld_abs];"
+	"r0 = 1;"
+	"exit;"
+	:
+	: __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
+	: __clobber_all);
+}
+
+__naked __noinline __used
+static int ldind_subprog(void)
+{
+	asm volatile (
+	"r6 = r1;"
+	"r7 = 0;"
+	".8byte %[ld_ind];"
+	"r0 = 1;"
+	"exit;"
+	:
+	: __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
+	: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_abs: subprog early exit on ld_abs failure")
+__failure __msg("R9 !read_ok")
+__naked void ld_abs_subprog_early_exit(void)
+{
+	asm volatile (
+	"call ldabs_subprog;"
+	"if r0 != 0 goto l_exit_%=;"
+	"r0 = r9;"
+	"l_exit_%=:"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_ind: subprog early exit on ld_ind failure")
+__failure __msg("R9 !read_ok")
+__naked void ld_ind_subprog_early_exit(void)
+{
+	asm volatile (
+	"call ldind_subprog;"
+	"if r0 != 0 goto l_exit_%=;"
+	"r0 = r9;"
+	"l_exit_%=:"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_abs: subprog with both paths safe")
+__success
+__naked void ld_abs_subprog_both_paths_safe(void)
+{
+	asm volatile (
+	"call ldabs_subprog;"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_ind: subprog with both paths safe")
+__success
+__naked void ld_ind_subprog_both_paths_safe(void)
+{
+	asm volatile (
+	"call ldind_subprog;"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+/*
+ * ld_{abs,ind} in subprogs require scalar (int) return type in BTF.
+ * A test with void return must be rejected.
+ */
+__naked __noinline __used
+static void ldabs_void_subprog(void)
+{
+	asm volatile (
+	"r6 = r1;"
+	".8byte %[ld_abs];"
+	"r0 = 1;"
+	"exit;"
+	:
+	: __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
+	: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_abs: reject void return subprog")
+__failure __msg("LD_ABS is only allowed in functions that return 'int'")
+__naked void ld_abs_void_subprog_reject(void)
+{
+	asm volatile (
+	"call ldabs_void_subprog;"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
+__naked __noinline __used
+static void ldind_void_subprog(void)
+{
+	asm volatile (
+	"r6 = r1;"
+	"r7 = 0;"
+	".8byte %[ld_ind];"
+	"r0 = 1;"
+	"exit;"
+	:
+	: __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
+	: __clobber_all);
+}
+
+SEC("socket")
+__description("ld_ind: reject void return subprog")
+__failure __msg("LD_ABS is only allowed in functions that return 'int'")
+__naked void ld_ind_void_subprog_reject(void)
+{
+	asm volatile (
+	"call ldind_void_subprog;"
+	"r0 = 0;"
+	"exit;"
+	::: __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";
Signature · 1 line
2.53.0
author maintainer
#4 lore raw

PATCH 4/675 netfilter: nft_counter: serialize reset with spinlock

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brian Witte <[email protected]>

[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ]

Add a global static spinlock to serialize counter fetch+reset operations, preventing concurrent dump-and-reset from underrunning values.

The lock is taken before fetching the total so that two parallel resets cannot both read the same counter values and then both subtract them.

A global lock is used for simplicity since resets are infrequent. If this becomes a bottleneck, it can be replaced with a per-net lock later.

Fixes bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
Fixes 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
Fixes 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
---
 net/netfilter/nft_counter.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
net/netfilter/nft_counter.c +16 -4
index 0d70325280cc57..169ae93688bcc5 100644
@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv {
 
 static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync);
 
+/* control plane only: sync fetch+reset */
+static DEFINE_SPINLOCK(nft_counter_lock);
+
 static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
 				       struct nft_regs *regs,
 				       const struct nft_pktinfo *pkt)
@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv,
 	}
 }
 
+static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv,
+					struct nft_counter_tot *total)
+{
+	spin_lock(&nft_counter_lock);
+	nft_counter_fetch(priv, total);
+	nft_counter_reset(priv, total);
+	spin_unlock(&nft_counter_lock);
+}
+
 static int nft_counter_do_dump(struct sk_buff *skb,
 			       struct nft_counter_percpu_priv *priv,
 			       bool reset)
 {
 	struct nft_counter_tot total;
 
-	nft_counter_fetch(priv, &total);
+	if (unlikely(reset))
+		nft_counter_fetch_and_reset(priv, &total);
+	else
+		nft_counter_fetch(priv, &total);
 
 	if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
 			 NFTA_COUNTER_PAD) ||
@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb,
 			 NFTA_COUNTER_PAD))
 		goto nla_put_failure;
 
-	if (reset)
-		nft_counter_reset(priv, &total);
-
 	return 0;
 
 nla_put_failure:
Signature · 1 line
2.53.0
author maintainer
#5 lore raw

PATCH 5/675 netfilter: nft_quota: use atomic64_xchg for reset

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brian Witte <[email protected]>

[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ]

Use atomic64_xchg() to atomically read and zero the consumed value on reset, which is simpler than the previous read+sub pattern and doesn't require lock serialization.

Fixes bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
Fixes 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
Fixes 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
---
 net/netfilter/nft_quota.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
net/netfilter/nft_quota.c +7 -6
index df0798da2329b9..cb6c0e04ff6755 100644
@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
 	u64 consumed, consumed_cap, quota;
 	u32 flags = priv->flags;
 
-	/* Since we inconditionally increment consumed quota for each packet
+	/* Since we unconditionally increment consumed quota for each packet
 	 * that we see, don't go over the quota boundary in what we send to
 	 * userspace.
 	 */
-	consumed = atomic64_read(priv->consumed);
+	if (reset) {
+		consumed = atomic64_xchg(priv->consumed, 0);
+		clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+	} else {
+		consumed = atomic64_read(priv->consumed);
+	}
 	quota = atomic64_read(&priv->quota);
 	if (consumed >= quota) {
 		consumed_cap = quota;
@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
 	    nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
 		goto nla_put_failure;
 
-	if (reset) {
-		atomic64_sub(consumed, priv->consumed);
-		clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
-	}
 	return 0;
 
 nla_put_failure:
Signature · 1 line
2.53.0
author maintainer
#6 lore raw

PATCH 6/675 netfilter: nf_tables: revert commit_mutex usage in reset path

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brian Witte <[email protected]>

[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ]

It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set' rule run at the same time.

Previous patches made it safe to run individual reset handlers concurrently so commit_mutex is no longer required to prevent this.

Fixes bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
Fixes 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
Fixes 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
---
 net/netfilter/nf_tables_api.c | 248 ++++++----------------------------
 1 file changed, 42 insertions(+), 206 deletions(-)
net/netfilter/nf_tables_api.c +42 -206
index 0842916c19f503..c82c16bd4257e4 100644
@@ -3908,23 +3908,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
 	return skb->len;
 }
 
-static int nf_tables_dumpreset_rules(struct sk_buff *skb,
-				     struct netlink_callback *cb)
-{
-	struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
-	int ret;
-
-	/* Mutex is held is to prevent that two concurrent dump-and-reset calls
-	 * do not underrun counters and quotas. The commit_mutex is used for
-	 * the lack a better lock, this is not transaction path.
-	 */
-	mutex_lock(&nft_net->commit_mutex);
-	ret = nf_tables_dump_rules(skb, cb);
-	mutex_unlock(&nft_net->commit_mutex);
-
-	return ret;
-}
-
 static int nf_tables_dump_rules_start(struct netlink_callback *cb)
 {
 	struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
@@ -3944,16 +3927,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
 			return -ENOMEM;
 		}
 	}
-	return 0;
-}
-
-static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb)
-{
-	struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
-
-	ctx->reset = true;
+	if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
+		ctx->reset = true;
 
-	return nf_tables_dump_rules_start(cb);
+	return 0;
 }
 
 static int nf_tables_dump_rules_done(struct netlink_callback *cb)
@@ -4019,6 +3996,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
 	u32 portid = NETLINK_CB(skb).portid;
 	struct net *net = info->net;
 	struct sk_buff *skb2;
+	bool reset = false;
+	char *buf;
 
 	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
 		struct netlink_dump_control c = {
@@ -4032,47 +4011,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
 		return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
 	}
 
-	skb2 = nf_tables_getrule_single(portid, info, nla, false);
-	if (IS_ERR(skb2))
-		return PTR_ERR(skb2);
-
-	return nfnetlink_unicast(skb2, net, portid);
-}
-
-static int nf_tables_getrule_reset(struct sk_buff *skb,
-				   const struct nfnl_info *info,
-				   const struct nlattr * const nla[])
-{
-	struct nftables_pernet *nft_net = nft_pernet(info->net);
-	u32 portid = NETLINK_CB(skb).portid;
-	struct net *net = info->net;
-	struct sk_buff *skb2;
-	char *buf;
-
-	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
-		struct netlink_dump_control c = {
-			.start= nf_tables_dumpreset_rules_start,
-			.dump = nf_tables_dumpreset_rules,
-			.done = nf_tables_dump_rules_done,
-			.module = THIS_MODULE,
-			.data = (void *)nla,
-		};
-
-		return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
-	}
-
-	if (!try_module_get(THIS_MODULE))
-		return -EINVAL;
-	rcu_read_unlock();
-	mutex_lock(&nft_net->commit_mutex);
-	skb2 = nf_tables_getrule_single(portid, info, nla, true);
-	mutex_unlock(&nft_net->commit_mutex);
-	rcu_read_lock();
-	module_put(THIS_MODULE);
+	if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
+		reset = true;
 
+	skb2 = nf_tables_getrule_single(portid, info, nla, reset);
 	if (IS_ERR(skb2))
 		return PTR_ERR(skb2);
 
+	if (!reset)
+		return nfnetlink_unicast(skb2, net, portid);
+
 	buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
 			nla_len(nla[NFTA_RULE_TABLE]),
 			(char *)nla_data(nla[NFTA_RULE_TABLE]),
@@ -6332,6 +6280,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 	nla_nest_end(skb, nest);
 	nlmsg_end(skb, nlh);
 
+	if (dump_ctx->reset && args.iter.count > args.iter.skip)
+		audit_log_nft_set_reset(table, cb->seq,
+					args.iter.count - args.iter.skip);
+
 	rcu_read_unlock();
 
 	if (args.iter.err && args.iter.err != -EMSGSIZE)
@@ -6347,26 +6299,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 	return -ENOSPC;
 }
 
-static int nf_tables_dumpreset_set(struct sk_buff *skb,
-				   struct netlink_callback *cb)
-{
-	struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
-	struct nft_set_dump_ctx *dump_ctx = cb->data;
-	int ret, skip = cb->args[0];
-
-	mutex_lock(&nft_net->commit_mutex);
-
-	ret = nf_tables_dump_set(skb, cb);
-
-	if (cb->args[0] > skip)
-		audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq,
-					cb->args[0] - skip);
-
-	mutex_unlock(&nft_net->commit_mutex);
-
-	return ret;
-}
-
 static int nf_tables_dump_set_start(struct netlink_callback *cb)
 {
 	struct nft_set_dump_ctx *dump_ctx = cb->data;
@@ -6613,8 +6545,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
 {
 	struct netlink_ext_ack *extack = info->extack;
 	struct nft_set_dump_ctx dump_ctx;
+	int rem, err = 0, nelems = 0;
+	struct net *net = info->net;
 	struct nlattr *attr;
-	int rem, err = 0;
+	bool reset = false;
+
+	if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
+		reset = true;
 
 	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
 		struct netlink_dump_control c = {
@@ -6624,7 +6561,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
 			.module = THIS_MODULE,
 		};
 
-		err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
+		err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
 		if (err)
 			return err;
 
@@ -6635,75 +6572,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
 	if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
 		return -EINVAL;
 
-	err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
+	err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
 	if (err)
 		return err;
 
 	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
-		err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false);
-		if (err < 0) {
-			NL_SET_BAD_ATTR(extack, attr);
-			break;
-		}
-	}
-
-	return err;
-}
-
-static int nf_tables_getsetelem_reset(struct sk_buff *skb,
-				      const struct nfnl_info *info,
-				      const struct nlattr * const nla[])
-{
-	struct nftables_pernet *nft_net = nft_pernet(info->net);
-	struct netlink_ext_ack *extack = info->extack;
-	struct nft_set_dump_ctx dump_ctx;
-	int rem, err = 0, nelems = 0;
-	struct nlattr *attr;
-
-	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
-		struct netlink_dump_control c = {
-			.start = nf_tables_dump_set_start,
-			.dump = nf_tables_dumpreset_set,
-			.done = nf_tables_dump_set_done,
-			.module = THIS_MODULE,
-		};
-
-		err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
-		if (err)
-			return err;
-
-		c.data = &dump_ctx;
-		return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
-	}
-
-	if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
-		return -EINVAL;
-
-	if (!try_module_get(THIS_MODULE))
-		return -EINVAL;
-	rcu_read_unlock();
-	mutex_lock(&nft_net->commit_mutex);
-	rcu_read_lock();
-
-	err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
-	if (err)
-		goto out_unlock;
-
-	nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
-		err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true);
+		err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset);
 		if (err < 0) {
 			NL_SET_BAD_ATTR(extack, attr);
 			break;
 		}
 		nelems++;
 	}
-	audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems);
-
-out_unlock:
-	rcu_read_unlock();
-	mutex_unlock(&nft_net->commit_mutex);
-	rcu_read_lock();
-	module_put(THIS_MODULE);
+	if (reset)
+		audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net),
+					nelems);
 
 	return err;
 }
@@ -8567,19 +8450,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static int nf_tables_dumpreset_obj(struct sk_buff *skb,
-				   struct netlink_callback *cb)
-{
-	struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
-	int ret;
-
-	mutex_lock(&nft_net->commit_mutex);
-	ret = nf_tables_dump_obj(skb, cb);
-	mutex_unlock(&nft_net->commit_mutex);
-
-	return ret;
-}
-
 static int nf_tables_dump_obj_start(struct netlink_callback *cb)
 {
 	struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
@@ -8596,16 +8466,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
 	if (nla[NFTA_OBJ_TYPE])
 		ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
 
-	return 0;
-}
-
-static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb)
-{
-	struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
-
-	ctx->reset = true;
+	if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
+		ctx->reset = true;
 
-	return nf_tables_dump_obj_start(cb);
+	return 0;
 }
 
 static int nf_tables_dump_obj_done(struct netlink_callback *cb)
@@ -8667,42 +8531,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,
 static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info,
 			    const struct nlattr * const nla[])
 {
-	u32 portid = NETLINK_CB(skb).portid;
-	struct sk_buff *skb2;
-
-	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
-		struct netlink_dump_control c = {
-			.start = nf_tables_dump_obj_start,
-			.dump = nf_tables_dump_obj,
-			.done = nf_tables_dump_obj_done,
-			.module = THIS_MODULE,
-			.data = (void *)nla,
-		};
-
-		return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
-	}
-
-	skb2 = nf_tables_getobj_single(portid, info, nla, false);
-	if (IS_ERR(skb2))
-		return PTR_ERR(skb2);
-
-	return nfnetlink_unicast(skb2, info->net, portid);
-}
-
-static int nf_tables_getobj_reset(struct sk_buff *skb,
-				  const struct nfnl_info *info,
-				  const struct nlattr * const nla[])
-{
-	struct nftables_pernet *nft_net = nft_pernet(info->net);
 	u32 portid = NETLINK_CB(skb).portid;
 	struct net *net = info->net;
 	struct sk_buff *skb2;
+	bool reset = false;
 	char *buf;
 
 	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
 		struct netlink_dump_control c = {
-			.start = nf_tables_dumpreset_obj_start,
-			.dump = nf_tables_dumpreset_obj,
+			.start = nf_tables_dump_obj_start,
+			.dump = nf_tables_dump_obj,
 			.done = nf_tables_dump_obj_done,
 			.module = THIS_MODULE,
 			.data = (void *)nla,
@@ -8711,18 +8549,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
 		return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
 	}
 
-	if (!try_module_get(THIS_MODULE))
-		return -EINVAL;
-	rcu_read_unlock();
-	mutex_lock(&nft_net->commit_mutex);
-	skb2 = nf_tables_getobj_single(portid, info, nla, true);
-	mutex_unlock(&nft_net->commit_mutex);
-	rcu_read_lock();
-	module_put(THIS_MODULE);
+	if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
+		reset = true;
 
+	skb2 = nf_tables_getobj_single(portid, info, nla, reset);
 	if (IS_ERR(skb2))
 		return PTR_ERR(skb2);
 
+	if (!reset)
+		return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
+
 	buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
 			nla_len(nla[NFTA_OBJ_TABLE]),
 			(char *)nla_data(nla[NFTA_OBJ_TABLE]),
@@ -10030,7 +9866,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
 		.policy		= nft_rule_policy,
 	},
 	[NFT_MSG_GETRULE_RESET] = {
-		.call		= nf_tables_getrule_reset,
+		.call		= nf_tables_getrule,
 		.type		= NFNL_CB_RCU,
 		.attr_count	= NFTA_RULE_MAX,
 		.policy		= nft_rule_policy,
@@ -10084,7 +9920,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
 		.policy		= nft_set_elem_list_policy,
 	},
 	[NFT_MSG_GETSETELEM_RESET] = {
-		.call		= nf_tables_getsetelem_reset,
+		.call		= nf_tables_getsetelem,
 		.type		= NFNL_CB_RCU,
 		.attr_count	= NFTA_SET_ELEM_LIST_MAX,
 		.policy		= nft_set_elem_list_policy,
@@ -10130,7 +9966,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
 		.policy		= nft_obj_policy,
 	},
 	[NFT_MSG_GETOBJ_RESET] = {
-		.call		= nf_tables_getobj_reset,
+		.call		= nf_tables_getobj,
 		.type		= NFNL_CB_RCU,
 		.attr_count	= NFTA_OBJ_MAX,
 		.policy		= nft_obj_policy,
Signature · 1 line
2.53.0
author maintainer
#7 lore raw

PATCH 7/675 drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ryosuke Yasuoka <[email protected]>

[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]

A probe-time deadlock can occur between the dequeue worker and drm_client_register(). During probe, drm_client_register() holds clientlist_mutex and calls the fbdev hotplug callback, which triggers an atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs() waiting for virtqueue space. The dequeue worker that would free that space calls virtio_gpu_cmd_get_display_info_cb(), which invokes drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting to acquire the same clientlist_mutex. Since wake_up() is only called after the resp_cb loop, the probe thread is never woken and both threads deadlock.

Fix this by removing the hotplug notification from virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info) is still updated synchronously in the callback.

For the init path, drm_client_register() already fires an initial hotplug when the client is registered, which picks up the connector state updated by display_info_cb.

For the runtime config_changed path, add a wait_event_timeout() in config_changed_work_func() so that display_info_cb updates the connector data before the hotplug notification is sent. Also replace drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since virtio-gpu never calls drm_kms_helper_poll_init() and thus drm_helper_hpd_irq_event() always returns false without doing anything.

---
 drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++-
 drivers/gpu/drm/virtio/virtgpu_vq.c  | 3 ---
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/virtio/virtgpu_kms.c +4 -1
index 1c15cbf326b78c..4a25347734fda4 100644
@@ -48,7 +48,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
 				virtio_gpu_cmd_get_edids(vgdev);
 			virtio_gpu_cmd_get_display_info(vgdev);
 			virtio_gpu_notify(vgdev);
-			drm_helper_hpd_irq_event(vgdev->ddev);
+			wait_event_timeout(vgdev->resp_wq,
+					   !vgdev->display_info_pending,
+					   5 * HZ);
+			drm_kms_helper_hotplug_event(vgdev->ddev);
 		}
 		events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
 	}
drivers/gpu/drm/virtio/virtgpu_vq.c +0 -3
index 8181b22b9b46a1..412384e16daea4 100644
@@ -839,9 +839,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
 	vgdev->display_info_pending = false;
 	spin_unlock(&vgdev->display_info_lock);
 	wake_up(&vgdev->resp_wq);
-
-	if (!drm_helper_hpd_irq_event(vgdev->ddev))
-		drm_kms_helper_hotplug_event(vgdev->ddev);
 }
 
 static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
Signature · 1 line
2.53.0
author maintainer
#8 lore raw

PATCH 8/675 fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kiryl Shutsemau <[email protected]>

commit 04718f7c9290f95385f0dd328758753dc1c36dec upstream.

Patch series "userfaultfd/pagemap: pre-existing fixes".

These are pre-existing bug fixes that were carried at the front of the userfaultfd RWP working-set-tracking series up to v5 [1]. Per review feedback that fixes should not sit in the middle of a feature series, they are split out and sent on their own; the RWP series is reposted rebased on top of this.

All six were flagged by the Sashiko AI review of the RWP series and carry

independent of RWP, apply to mm-new directly, and carry Cc: stable@.

1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in
make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates when PAGEMAP_SCAN write-protects a hugetlb PTE.

2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range
against HPAGE_SIZE rather than the hstate page size, so it never write-protects gigantic hugetlb pages.

3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an
unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole() calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb vma lock for read, and hugetlb_change_protection() then takes it for write. Install the marker inline instead.

4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp
on a device-private PMD permission downgrade, silently losing the uffd-wp marker.

5: userfaultfd: must_wait() applies pte_write() to a locklessly read
PTE without checking pte_present(), so swap/migration entries decode random offset bits and a thread can stay parked on a stale fault.

6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to
mk_vma_flags() unconditionally, an out-of-bounds write into the single-word vma_flags_t on 32-bit. Build the mask from config-gated per-mode masks so an unavailable bit is never materialised.

This patch (of 6):

make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by calling huge_ptep_modify_prot_commit() with a ptent snapshot that was fetched without the corresponding huge_ptep_modify_prot_start(). The start helper is what atomically clears the entry so the kernel-owned snapshot stays consistent until the commit; without it, the hardware may set Dirty or Accessed in the live PTE between the original read and the commit, and huge_ptep_modify_prot_commit() (whose generic implementation just calls set_huge_pte_at()) then writes the stale snapshot back over the live hardware bits, losing the update.

The non-hugetlb sibling make_uffd_wp_pte() does this correctly via ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern for the present-PTE branch. The migration case stays as-is -- migration entries are non-present, so there's no hardware update to race against.

Fixes 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
Cc David Hildenbrand <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Mike Rapoport <[email protected]>
Cc Peter Xu <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
Cc Vlastimil Babka <[email protected]>
Cc Balbir Singh <[email protected]>

[ kas: adapt to the pre-softleaf idiom; apply the
huge_ptep_modify_prot_start()/commit() fix to the present-PTE (!huge_pte_none()) branch ]

---
 fs/proc/task_mmu.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
fs/proc/task_mmu.c +9 -5
index 38b9d47426ca99..858b11009c269e 100644
@@ -2485,15 +2485,19 @@ static void make_uffd_wp_huge_pte(struct vm_area_struct *vma,
 
 	psize = huge_page_size(hstate_vma(vma));
 
-	if (is_hugetlb_entry_migration(ptent))
+	if (is_hugetlb_entry_migration(ptent)) {
 		set_huge_pte_at(vma->vm_mm, addr, ptep,
 				pte_swp_mkuffd_wp(ptent), psize);
-	else if (!huge_pte_none(ptent))
-		huge_ptep_modify_prot_commit(vma, addr, ptep, ptent,
-					     huge_pte_mkuffd_wp(ptent));
-	else
+	} else if (!huge_pte_none(ptent)) {
+		pte_t old_pte, new_pte;
+
+		old_pte = huge_ptep_modify_prot_start(vma, addr, ptep);
+		new_pte = huge_pte_mkuffd_wp(old_pte);
+		huge_ptep_modify_prot_commit(vma, addr, ptep, old_pte, new_pte);
+	} else {
 		set_huge_pte_at(vma->vm_mm, addr, ptep,
 				make_pte_marker(PTE_MARKER_UFFD_WP), psize);
+	}
 }
 #endif /* CONFIG_HUGETLB_PAGE */
 
Signature · 1 line
2.53.0
author maintainer
#9 lore raw

PATCH 9/675 seqlock: Cure some more scoped_seqlock() optimization fails

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit 90dfeef1cd38dff19f8b3a752d13bfd79f0f7694 upstream.

Arnd reported an x86 randconfig using gcc-15 tripped over __scoped_seqlock_bug(). Turns out GCC chose not to inline the scoped_seqlock helper functions and as such was not able to optimize properly.

[ mingo: Clang fails the build too in some circumstances. ]

---
 include/linux/seqlock.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/seqlock.h +2 -2
@@ -1224,7 +1224,7 @@ struct ss_tmp {
 	spinlock_t	*lock_irqsave;
 };
 
-static inline void __scoped_seqlock_cleanup(struct ss_tmp *sst)
+static __always_inline void __scoped_seqlock_cleanup(struct ss_tmp *sst)
 {
 	if (sst->lock)
 		spin_unlock(sst->lock);
@@ -1249,7 +1249,7 @@ static inline void __scoped_seqlock_bug(
 extern void __scoped_seqlock_bug(void);
 #endif
 
-static inline void
+static __always_inline void
 __scoped_seqlock_next(struct ss_tmp *sst, seqlock_t *lock, enum ss_state target)
 {
 	switch (sst->state) {
author maintainer
#10 lore raw

PATCH 10/675 seqlock: Allow KASAN to fail optimizing

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peter Zijlstra <[email protected]>

commit b94d45b6bbb42571ec225d3be0e7457c8765a5b4 upstream.

Some KASAN builds are failing to properly optimize this code -- luckily we don't care about core quality for KASAN builds, so just exclude it.

---
 include/linux/seqlock.h |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/seqlock.h +4 -1
@@ -1234,11 +1234,14 @@ static __always_inline void __scoped_seq
 
 extern void __scoped_seqlock_invalid_target(void);
 
-#if defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 90000
+#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 90000) || defined(CONFIG_KASAN)
 /*
  * For some reason some GCC-8 architectures (nios2, alpha) have trouble
  * determining that the ss_done state is impossible in __scoped_seqlock_next()
  * below.
+ *
+ * Similarly KASAN is known to confuse compilers enough to break this. But we
+ * don't care about code quality for KASAN builds anyway.
  */
 static inline void __scoped_seqlock_bug(void) { }
 #else
author maintainer
#11 lore raw

PATCH 11/675 seqlock: Allow UBSAN_ALIGNMENT to fail optimizing

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Heiko Carstens <[email protected]>

commit 88331c4ec23a28c1006ec532fa64763d4c695e90 upstream.

With gcc-15 and gcc-16 with UBSAN_ALIGNMENT enabled the compiler fails to inline and optimize __scoped_seqlock_bug() away on s390:

s390x-16.1.0-ld: kernel/sched/build_policy.o: in function `__scoped_seqlock_next':
/.../seqlock.h:1286:(.text+0x22030): undefined reference to `__scoped_seqlock_bug'

Fix this by adding UBSAN_ALIGNMENT to the list of config options where a not inlined empty __scoped_seqlock_bug() is allowed.

---
 include/linux/seqlock.h |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
include/linux/seqlock.h +4 -3
@@ -1234,14 +1234,15 @@ static __always_inline void __scoped_seq
 
 extern void __scoped_seqlock_invalid_target(void);
 
-#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 90000) || defined(CONFIG_KASAN)
+#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 90000) || \
+	defined(CONFIG_KASAN) || defined(CONFIG_UBSAN_ALIGNMENT)
 /*
  * For some reason some GCC-8 architectures (nios2, alpha) have trouble
  * determining that the ss_done state is impossible in __scoped_seqlock_next()
  * below.
  *
- * Similarly KASAN is known to confuse compilers enough to break this. But we
- * don't care about code quality for KASAN builds anyway.
+ * Similarly KASAN and UBSAN_ALIGNMENT are known to confuse compilers enough
+ * to break this. But we don't care about code quality for such builds anyway.
  */
 static inline void __scoped_seqlock_bug(void) { }
 #else
author maintainer
#12 lore raw

PATCH 12/675 KVM: x86: Check for invalid/obsolete root *after* making MMU pages available

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <[email protected]>

commit 2abd5287f08319fa35764566b15c6e22cb1068db upstream.

Check for a "stale" page fault, i.e. for an invalid and/or obsolete root, after making MMU pages available for the shadow MMU. If reclaiming shadow pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to map memory into an invalid root. On its own, populating an invalid root is "fine", but because child shadow pages inherit their parent's role, any children created during the map/fetch will be created as invalid pages, thus violating KVM's invariant that invalid pages are never on the list of active MMU pages.

Note, the underlying flaw has existed since KVM first started tracking invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root pagetables"), but the true badness only came along in 2020 (Linux 5.9) with the invariant that invalid shadow pages can't be on the list of active pages.

Note #2, inheriting role.invalid when creating child shadow pages is also far from ideal; that flaw will be addressed separately.

Fixes f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages")
---
 arch/x86/kvm/mmu/mmu.c         |    9 +++++----
 arch/x86/kvm/mmu/paging_tmpl.h |   10 ++++++----
 2 files changed, 11 insertions(+), 8 deletions(-)
arch/x86/kvm/mmu/mmu.c +5 -4
@@ -4806,16 +4806,17 @@ static int direct_page_fault(struct kvm_
 	if (r != RET_PF_CONTINUE)
 		return r;
 
-	r = RET_PF_RETRY;
 	write_lock(&vcpu->kvm->mmu_lock);
 
-	if (is_page_fault_stale(vcpu, fault))
-		goto out_unlock;
-
 	r = make_mmu_pages_available(vcpu);
 	if (r)
 		goto out_unlock;
 
+	if (is_page_fault_stale(vcpu, fault)) {
+		r = RET_PF_RETRY;
+		goto out_unlock;
+	}
+
 	r = direct_map(vcpu, fault);
 
 out_unlock:
arch/x86/kvm/mmu/paging_tmpl.h +6 -4
@@ -827,15 +827,17 @@ static int FNAME(page_fault)(struct kvm_
 	}
 #endif
 
-	r = RET_PF_RETRY;
 	write_lock(&vcpu->kvm->mmu_lock);
 
-	if (is_page_fault_stale(vcpu, fault))
-		goto out_unlock;
-
 	r = make_mmu_pages_available(vcpu);
 	if (r)
 		goto out_unlock;
+
+	if (is_page_fault_stale(vcpu, fault)) {
+		r = RET_PF_RETRY;
+		goto out_unlock;
+	}
+
 	r = FNAME(fetch)(vcpu, fault, &walker);
 
 out_unlock:
author maintainer
#13 lore raw

PATCH 13/675 KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Venkatesh Srinivas <[email protected]>

commit e800decd9c0ac4349bcd8f8f9b29fd21fe93165e upstream.

On Intel platforms with a VMX preemption timer and APICv, if a VMM calls KVM_GET_LAPIC before KVM_GET_MSRS to save the vCPU state, it is possible to lose a pending timer interrupt.

If the thread running these ioctls is migrated to another core after calling KVM_GET_LAPIC but before KVM_GET_MSRS and the guest is using their LAPIC timer in TSC-deadline mode, not only does the save LAPIC state not carry the pending interrupt, the TSCDEADLINE MSR will be zeroed.

After migration across CPUs, KVM_GET_MSRS calls vcpu_load, posting the interrupt and clearing the MSR:
vcpu_load() ->
kvm_arch_vcpu_load() ->

    kvm_lapic_restart_hv_timer() ->
      start_hv_timer() ->
        apic_timer_expired() ->
          kvm_apic_inject_pending_timer_irqs()
            . post interrupt into the LAPIC state
            . clear IA32_TSCDEADLINE

The saved LAPIC state will be missing the pending interrupt and the saved MSR will be zero. Oops.

Fix by only posting an interrupt when we're attempting to enter the guest (vcpu->wants_to_run == true), not for vcpu_load from other paths.

Message-ID: <[email protected]>

Fixes ae95f566b3d2 ("KVM: X86: TSCDEADLINE MSR emulation fastpath", 2020-05-15)
---
 arch/x86/kvm/lapic.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -2065,7 +2065,7 @@ static void apic_timer_expired(struct kv
 	if (apic_lvtt_tscdeadline(apic) || ktimer->hv_timer_in_use)
 		ktimer->expired_tscdeadline = ktimer->tscdeadline;
 
-	if (!from_timer_fn && apic->apicv_active) {
+	if (!from_timer_fn && apic->apicv_active && vcpu->wants_to_run) {
 		WARN_ON(kvm_get_running_vcpu() != vcpu);
 		kvm_apic_inject_pending_timer_irqs(apic);
 		return;
author maintainer
#14 lore raw

PATCH 14/675 KVM: nVMX: Hide shadow VMCS right after VMCLEAR

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hyunwoo Kim <[email protected]>

commit 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 upstream.

free_nested() frees the shadow VMCS while vmcs01 still points to it. But because it is asynchronous with respect to loaded_vmcs_clear(), the vCPU might migrate before the pointer is cleared and __loaded_vmcs_clear() may then execute VMCLEAR.

The VMCS needs to stay attached until its explicit VMCLEAR completes, but then it can be hidden and the page safely freed.

Fixes 355f4fb1405e ("kvm: nVMX: VMCLEAR an active shadow VMCS after last use")
---
 arch/x86/kvm/vmx/nested.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/nested.c +9 -2
@@ -333,6 +333,7 @@ static void nested_put_vmcs12_pages(stru
 static void free_nested(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	struct vmcs *shadow_vmcs;
 
 	if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01))
 		vmx_switch_vmcs(vcpu, &vmx->vmcs01);
@@ -350,9 +351,15 @@ static void free_nested(struct kvm_vcpu
 	vmx->nested.current_vmptr = INVALID_GPA;
 	if (enable_shadow_vmcs) {
 		vmx_disable_shadow_vmcs(vmx);
-		vmcs_clear(vmx->vmcs01.shadow_vmcs);
-		free_vmcs(vmx->vmcs01.shadow_vmcs);
+
+		/*
+		 * Keep the pointer visible until after VMCLEAR, so migration
+		 * can clear an active shadow VMCS on the old CPU.
+		 */
+		shadow_vmcs = vmx->vmcs01.shadow_vmcs;
+		vmcs_clear(shadow_vmcs);
 		vmx->vmcs01.shadow_vmcs = NULL;
+		free_vmcs(shadow_vmcs);
 	}
 	kfree(vmx->nested.cached_vmcs12);
 	vmx->nested.cached_vmcs12 = NULL;
author maintainer
#15 lore raw

PATCH 15/675 KVM: x86/mmu: Fix use-after-free on vendor module reload

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Phil Rosenthal <[email protected]>

commit 52f2f7c30126037975389aa04d24c506a5177c35 upstream.

mmu_destroy_caches() destroys pte_list_desc_cache and mmu_page_header_cache, but leaves both pointers unchanged. The pointers live in kvm.ko, and therefore survive when a vendor module is unloaded while kvm.ko remains loaded.

If creation of pte_list_desc_cache fails during a subsequent vendor module load, its assignment sets pte_list_desc_cache to NULL and the error path calls mmu_destroy_caches(). mmu_page_header_cache still points to the cache destroyed during the preceding vendor module unload. Passing that stale pointer to kmem_cache_destroy() causes a slab use-after-free.

Reproduce the issue on a v7.1.3 kernel with CONFIG_KASAN=y, CONFIG_KASAN_GENERIC=y, CONFIG_KVM=m, and CONFIG_KVM_INTEL=m. A one-shot test hook forces pte_list_desc_cache to NULL on the second invocation of kvm_mmu_vendor_module_init():

1. Load kvm.ko and kvm-intel.ko, creating both caches.
2. Unload only kvm_intel, leaving kvm.ko loaded.
3. Reload kvm_intel and force initialization through the -ENOMEM path.

KASAN reports:

  BUG: KASAN: slab-use-after-free in
  kvm_mmu_vendor_module_init+0x5b/0x170 [kvm]
  ...
  kmem_cache_destroy+0x21/0x1d0
  kvm_mmu_vendor_module_init+0x5b/0x170 [kvm]
  ...
  Allocated by task 16817:
  __kmem_cache_create_args+0x12c/0x3b0
  __kmem_cache_create.constprop.0+0xb6/0xf0 [kvm]
  kvm_mmu_vendor_module_init+0x13b/0x170 [kvm]
  ...
  Freed by task 16820:
  kmem_cache_destroy+0x117/0x1d0
  kvm_mmu_vendor_module_exit+0x21/0x30 [kvm]

Clear both pointers immediately after destroying their caches so that the stored state reflects the caches' lifetime and repeated cleanup is safe.

With the fix applied, the same injected vendor module reload fails with -ENOMEM as expected and produces no KASAN report.

Fixes cb498ea2ce1d ("KVM: Portability: Combine kvm_init and kvm_init_x86")

Message-ID: <[email protected]>

---
 arch/x86/kvm/mmu/mmu.c |    2 ++
 1 file changed, 2 insertions(+)
arch/x86/kvm/mmu/mmu.c +2 -0
@@ -7393,7 +7393,9 @@ void kvm_mmu_invalidate_mmio_sptes(struc
 static void mmu_destroy_caches(void)
 {
 	kmem_cache_destroy(pte_list_desc_cache);
+	pte_list_desc_cache = NULL;
 	kmem_cache_destroy(mmu_page_header_cache);
+	mmu_page_header_cache = NULL;
 }
 
 static void kvm_wake_nx_recovery_thread(struct kvm *kvm)
author maintainer
#16 lore raw

PATCH 16/675 can: bcm: add locking when updating filter and timer values

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 749179c2e25b95d22499ed29096b3e02d6dfd2b4 upstream.

KCSAN detected a simultaneous access to timer values that can be overwritten in bcm_rx_setup() when updating timer and filter content while bcm_rx_handler(), bcm_rx_timeout_handler() or bcm_rx_thr_handler() run concurrently on incoming CAN traffic.

Protect the timer (ival1/ival2/kt_ival1/kt_ival2/kt_lastmsg) and filter (nframes/flags/frames/last_frames) updates in bcm_rx_setup() with a new per-op bcm_rx_update_lock, taken with the matching scope in the RX handlers. memcpy_from_msg() is staged into a temporary buffer before the lock is taken, since it can sleep and must not run under a spinlock.

hrtimer_cancel() is always called without bcm_rx_update_lock held, since bcm_rx_timeout_handler()/bcm_rx_thr_handler() take the same lock and a running callback would otherwise deadlock against the canceller.

Also close a related race: bcm_rx_setup() cleared the RTR flag in the stored reply frame's can_id as a separate, unprotected step after the frame content was already installed, so a concurrent bcm_rx_handler() could transmit a stale reply with CAN_RTR_FLAG still set. Fold that normalization into the initial frame preparation instead (on the staged buffer for updates, directly on op->frames pre-registration for new ops), so the installed frame is always atomically self-consistent.

bcm_rx_handler()'s RX_RTR_FRAME check now takes a lock-protected snapshot of op->flags before deciding whether to call bcm_can_tx(), but does not hold the lock across that call.

Also take a lock-protected snapshot of the currframe in bcm_can_tx() to avoid partly overwrites by content updates in bcm_tx_setup(). Finally check if a TX_RESET_MULTI_IDX/SETTIMER might have reset op->currframe between the two locked sections in bcm_can_tx().

Omit calling hrtimer_forward() with zero interval in bcm_rx_thr_handler(). kt_ival2 may have been concurrently cleared by bcm_rx_setup() before it cancels this timer, so check kt_ival2 inside the bcm_rx_update_lock.

---
 net/can/bcm.c | 176 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 133 insertions(+), 43 deletions(-)
net/can/bcm.c +133 -43
index a40519638a262b..cfc495106aac4d 100644
@@ -128,6 +128,7 @@ struct bcm_op {
 	struct sock *sk;
 	struct net_device *rx_reg_dev;
 	spinlock_t bcm_tx_lock; /* protect currframe/count in runtime updates */
+	spinlock_t bcm_rx_update_lock; /* protect filter/timer data updates */
 };
 
 struct bcm_sock {
@@ -292,21 +293,27 @@ static int bcm_proc_show(struct seq_file *m, void *v)
  * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
  *              of the given bcm tx op
  */
-static void bcm_can_tx(struct bcm_op *op)
+static void bcm_can_tx(struct bcm_op *op, struct canfd_frame *cf)
 {
 	struct sk_buff *skb;
 	struct net_device *dev;
-	struct canfd_frame *cf;
+	struct canfd_frame cframe;
+	bool cyclic = !cf;
+	unsigned int idx = 0;
 	int err;
 
 	/* no target device? => exit */
 	if (!op->ifindex)
 		return;
 
-	/* read currframe under lock protection */
-	spin_lock_bh(&op->bcm_tx_lock);
-	cf = op->frames + op->cfsiz * op->currframe;
-	spin_unlock_bh(&op->bcm_tx_lock);
+	if (cyclic) {
+		/* read currframe under lock protection */
+		spin_lock_bh(&op->bcm_tx_lock);
+		idx = op->currframe;
+		memcpy(&cframe, op->frames + op->cfsiz * idx, op->cfsiz);
+		cf = &cframe;
+		spin_unlock_bh(&op->bcm_tx_lock);
+	}
 
 	dev = dev_get_by_index(sock_net(op->sk), op->ifindex);
 	if (!dev) {
@@ -335,14 +342,20 @@ static void bcm_can_tx(struct bcm_op *op)
 	if (!err)
 		op->frames_abs++;
 
-	op->currframe++;
+	/* only advance the cyclic sequence if nothing reset currframe while
+	 * we were sending - a concurrent TX_RESET_MULTI_IDX means this
+	 * frame's bookkeeping belongs to a sequence that no longer exists
+	 */
+	if (!cyclic || op->currframe == idx) {
+		op->currframe++;
 
-	/* reached last frame? */
-	if (op->currframe >= op->nframes)
-		op->currframe = 0;
+		/* reached last frame? */
+		if (op->currframe >= op->nframes)
+			op->currframe = 0;
 
-	if (op->count > 0)
-		op->count--;
+		if (op->count > 0)
+			op->count--;
+	}
 
 	spin_unlock_bh(&op->bcm_tx_lock);
 out:
@@ -456,7 +469,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
 	struct bcm_msg_head msg_head;
 
 	if (op->kt_ival1 && (op->count > 0)) {
-		bcm_can_tx(op);
+		bcm_can_tx(op, NULL);
 		if (!op->count && (op->flags & TX_COUNTEVT)) {
 
 			/* create notification to user */
@@ -473,7 +486,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
 		}
 
 	} else if (op->kt_ival2) {
-		bcm_can_tx(op);
+		bcm_can_tx(op, NULL);
 	}
 
 	return bcm_tx_set_expiry(op, &op->timer) ?
@@ -617,6 +630,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
 	struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
 	struct bcm_msg_head msg_head;
 
+	spin_lock_bh(&op->bcm_rx_update_lock);
+
 	/* if user wants to be informed, when cyclic CAN-Messages come back */
 	if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
 		/* clear received CAN frames to indicate 'nothing received' */
@@ -633,6 +648,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
 	msg_head.can_id  = op->can_id;
 	msg_head.nframes = 0;
 
+	spin_unlock_bh(&op->bcm_rx_update_lock);
+
 	bcm_send_to_user(op, &msg_head, NULL, 0);
 
 	return HRTIMER_NORESTART;
@@ -681,15 +698,26 @@ static int bcm_rx_thr_flush(struct bcm_op *op)
 static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer)
 {
 	struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer);
+	enum hrtimer_restart ret;
 
-	if (bcm_rx_thr_flush(op)) {
+	spin_lock_bh(&op->bcm_rx_update_lock);
+
+	/* kt_ival2 may have been concurrently cleared by bcm_rx_setup()
+	 * before it cancels this timer - never forward with a zero
+	 * interval in that case.
+	 */
+	if (bcm_rx_thr_flush(op) && op->kt_ival2) {
 		hrtimer_forward_now(hrtimer, op->kt_ival2);
-		return HRTIMER_RESTART;
+		ret = HRTIMER_RESTART;
 	} else {
 		/* rearm throttle handling */
 		op->kt_lastmsg = 0;
-		return HRTIMER_NORESTART;
+		ret = HRTIMER_NORESTART;
 	}
+
+	spin_unlock_bh(&op->bcm_rx_update_lock);
+
+	return ret;
 }
 
 /*
@@ -699,8 +727,10 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 {
 	struct bcm_op *op = (struct bcm_op *)data;
 	const struct canfd_frame *rxframe = (struct canfd_frame *)skb->data;
+	struct canfd_frame rtrframe;
 	unsigned int i;
 	unsigned char traffic_flags;
+	bool rtr_frame;
 
 	if (op->can_id != rxframe->can_id)
 		return;
@@ -724,9 +754,18 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 	/* update statistics */
 	op->frames_abs++;
 
-	if (op->flags & RX_RTR_FRAME) {
+	/* snapshot the flag under lock: op->flags/op->frames may be updated
+	 * concurrently by bcm_rx_setup().
+	 */
+	spin_lock_bh(&op->bcm_rx_update_lock);
+	rtr_frame = op->flags & RX_RTR_FRAME;
+	if (rtr_frame)
+		memcpy(&rtrframe, op->frames, op->cfsiz);
+	spin_unlock_bh(&op->bcm_rx_update_lock);
+
+	if (rtr_frame) {
 		/* send reply for RTR-request (placed in op->frames[0]) */
-		bcm_can_tx(op);
+		bcm_can_tx(op, &rtrframe);
 		return;
 	}
 
@@ -738,6 +777,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 			traffic_flags |= RX_OWN;
 	}
 
+	spin_lock_bh(&op->bcm_rx_update_lock);
+
 	if (op->flags & RX_FILTER_ID) {
 		/* the easiest case */
 		bcm_rx_update_and_send(op, op->last_frames, rxframe,
@@ -773,6 +814,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 
 rx_starttimer:
 	bcm_rx_starttimer(op);
+
+	spin_unlock_bh(&op->bcm_rx_update_lock);
 }
 
 /*
@@ -1115,7 +1158,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		list_add_rcu(&op->list, &bo->tx_ops);
 
 	if (op->flags & TX_ANNOUNCE)
-		bcm_can_tx(op);
+		bcm_can_tx(op, NULL);
 
 	if (op->flags & STARTTIMER)
 		bcm_tx_start_timer(op);
@@ -1129,6 +1172,24 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	return err;
 }
 
+static void bcm_rx_setup_rtr_check(struct bcm_msg_head *msg_head,
+				   struct bcm_op *op, void *new_frames)
+{
+	/* funny feature in RX(!)_SETUP only for RTR-mode:
+	 * copy can_id into frame BUT without RTR-flag to
+	 * prevent a full-load-loopback-test ... ;-]
+	 * normalize this on the staged buffer, before it is
+	 * ever installed into op->frames.
+	 */
+	if (msg_head->flags & RX_RTR_FRAME) {
+		struct canfd_frame *frame0 = new_frames;
+
+		if ((msg_head->flags & TX_CP_CAN_ID) ||
+		    frame0->can_id == op->can_id)
+			frame0->can_id = op->can_id & ~CAN_RTR_FLAG;
+	}
+}
+
 /*
  * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
  */
@@ -1163,6 +1224,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	/* check the given can_id */
 	op = bcm_find_op(&bo->rx_ops, msg_head, ifindex);
 	if (op) {
+		void *new_frames = NULL;
+
 		/* update existing BCM operation */
 
 		/*
@@ -1174,19 +1237,48 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			return -E2BIG;
 
 		if (msg_head->nframes) {
-			/* update CAN frames content */
-			err = memcpy_from_msg(op->frames, msg,
+			/* get new CAN frames content before locking */
+			new_frames = kmalloc(msg_head->nframes * op->cfsiz,
+					     GFP_KERNEL);
+			if (!new_frames)
+				return -ENOMEM;
+
+			err = memcpy_from_msg(new_frames, msg,
 					      msg_head->nframes * op->cfsiz);
-			if (err < 0)
+			if (err < 0) {
+				kfree(new_frames);
 				return err;
+			}
 
-			/* clear last_frames to indicate 'nothing received' */
-			memset(op->last_frames, 0, msg_head->nframes * op->cfsiz);
+			bcm_rx_setup_rtr_check(msg_head, op, new_frames);
 		}
 
+		spin_lock_bh(&op->bcm_rx_update_lock);
 		op->nframes = msg_head->nframes;
 		op->flags = msg_head->flags;
 
+		if (msg_head->nframes) {
+			/* update CAN frames content */
+			memcpy(op->frames, new_frames,
+			       msg_head->nframes * op->cfsiz);
+
+			/* clear last_frames to indicate 'nothing received' */
+			memset(op->last_frames, 0,
+			       msg_head->nframes * op->cfsiz);
+		}
+
+		if (msg_head->flags & SETTIMER) {
+			op->ival1 = msg_head->ival1;
+			op->ival2 = msg_head->ival2;
+			op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
+			op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
+			op->kt_lastmsg = 0;
+		}
+		spin_unlock_bh(&op->bcm_rx_update_lock);
+
+		/* free temporary frames / kfree(NULL) is safe */
+		kfree(new_frames);
+
 		/* Only an update -> do not call can_rx_register() */
 		do_rx_register = 0;
 
@@ -1197,6 +1289,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			return -ENOMEM;
 
 		spin_lock_init(&op->bcm_tx_lock);
+		spin_lock_init(&op->bcm_rx_update_lock);
 		op->can_id = msg_head->can_id;
 		op->nframes = msg_head->nframes;
 		op->cfsiz = CFSIZ(msg_head->flags);
@@ -1238,6 +1331,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 				kfree(op);
 				return err;
 			}
+
+			bcm_rx_setup_rtr_check(msg_head, op, op->frames);
 		}
 
 		/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1262,29 +1357,22 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	/* check flags */
 
 	if (op->flags & RX_RTR_FRAME) {
-		struct canfd_frame *frame0 = op->frames;
-
 		/* no timers in RTR-mode */
 		hrtimer_cancel(&op->thrtimer);
 		hrtimer_cancel(&op->timer);
-
-		/*
-		 * funny feature in RX(!)_SETUP only for RTR-mode:
-		 * copy can_id into frame BUT without RTR-flag to
-		 * prevent a full-load-loopback-test ... ;-]
-		 */
-		if ((op->flags & TX_CP_CAN_ID) ||
-		    (frame0->can_id == op->can_id))
-			frame0->can_id = op->can_id & ~CAN_RTR_FLAG;
-
 	} else {
 		if (op->flags & SETTIMER) {
 
-			/* set timer value */
-			op->ival1 = msg_head->ival1;
-			op->ival2 = msg_head->ival2;
-			op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
-			op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
+			/* set timers (locked) for newly created op */
+			if (do_rx_register) {
+				spin_lock_bh(&op->bcm_rx_update_lock);
+				op->ival1 = msg_head->ival1;
+				op->ival2 = msg_head->ival2;
+				op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
+				op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
+				op->kt_lastmsg = 0;
+				spin_unlock_bh(&op->bcm_rx_update_lock);
+			}
 
 			/* disable an active timer due to zero value? */
 			if (!op->kt_ival1)
@@ -1294,9 +1382,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			 * In any case cancel the throttle timer, flush
 			 * potentially blocked msgs and reset throttle handling
 			 */
-			op->kt_lastmsg = 0;
 			hrtimer_cancel(&op->thrtimer);
+
+			spin_lock_bh(&op->bcm_rx_update_lock);
 			bcm_rx_thr_flush(op);
+			spin_unlock_bh(&op->bcm_rx_update_lock);
 		}
 
 		if ((op->flags & STARTTIMER) && op->kt_ival1)
Signature · 1 line
2.53.0
author maintainer
#17 lore raw

PATCH 17/675 can: bcm: fix CAN frame rx/tx statistics

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit e6c24ba95fc3f1b5e1dcd28b1c6e59ef61a9daa5 upstream.

KCSAN detected a data race within the bcm_rx_handler() when two CAN frames have been simultaneously received and processed in a single rx op by two different CPUs.

Use atomic operations with (signed) long data types to access the statistics in the hot path to fix the KCSAN complaint.

Additionally simplify the update and check of statistics overflow by using the atomic operations in separate bcm_update_[rx|tx]_stats() functions. The rx variant runs under bcm_rx_update_lock to prevent races when resetting the two rx counters; the tx variant runs under bcm_tx_lock and only needs to guard its own counter's overflow.

As the rx path resets its values already at LONG_MAX / 100, there is no conflict between the two locking domains (bcm_rx_update_lock vs. bcm_tx_lock) even for ops that use both paths.

The rx statistics update and the frames_filtered update in bcm_rx_changed() were previously performed in two separate bcm_rx_update_lock sections. For an rx op subscribed on all interfaces (ifindex == 0), bcm_rx_handler() can run concurrently on different CPUs, so a counter reset by one CPU between these two sections could leave frames_filtered larger than frames_abs on another CPU, producing a bogus (even negative) reduction percentage in procfs. Update the statistics in the same critical section as bcm_rx_changed() to close this gap, which also removes the now unneeded extra lock/unlock pair around the traffic_flags calculation.

---
 net/can/bcm.c | 69 ++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 23 deletions(-)
net/can/bcm.c +46 -23
index cfc495106aac4d..1d4323cdf48a47 100644
@@ -111,7 +111,7 @@ struct bcm_op {
 	int ifindex;
 	canid_t can_id;
 	u32 flags;
-	unsigned long frames_abs, frames_filtered;
+	atomic_long_t frames_abs, frames_filtered;
 	struct bcm_timeval ival1, ival2;
 	struct hrtimer timer, thrtimer;
 	ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
@@ -228,10 +228,13 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 
 	list_for_each_entry_rcu(op, &bo->rx_ops, list) {
 
-		unsigned long reduction;
+		long reduction, frames_filtered, frames_abs;
+
+		frames_filtered = atomic_long_read(&op->frames_filtered);
+		frames_abs = atomic_long_read(&op->frames_abs);
 
 		/* print only active entries & prevent division by zero */
-		if (!op->frames_abs)
+		if (!frames_abs)
 			continue;
 
 		seq_printf(m, "rx_op: %03X %-5s ", op->can_id,
@@ -253,9 +256,9 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 				   (long long)ktime_to_us(op->kt_ival2));
 
 		seq_printf(m, "# recv %ld (%ld) => reduction: ",
-			   op->frames_filtered, op->frames_abs);
+			   frames_filtered, frames_abs);
 
-		reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
+		reduction = 100 - (frames_filtered * 100) / frames_abs;
 
 		seq_printf(m, "%s%ld%%\n",
 			   (reduction == 100) ? "near " : "", reduction);
@@ -279,7 +282,8 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 			seq_printf(m, "t2=%lld ",
 				   (long long)ktime_to_us(op->kt_ival2));
 
-		seq_printf(m, "# sent %ld\n", op->frames_abs);
+		seq_printf(m, "# sent %ld\n",
+			   atomic_long_read(&op->frames_abs));
 	}
 	seq_putc(m, '\n');
 
@@ -289,6 +293,24 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 }
 #endif /* CONFIG_PROC_FS */
 
+static void bcm_update_rx_stats(struct bcm_op *op)
+{
+	/* prevent overflow of the reduction% calculation in bcm_proc_show() */
+	if (atomic_long_inc_return(&op->frames_abs) > LONG_MAX / 100) {
+		atomic_long_set(&op->frames_filtered, 0);
+		atomic_long_set(&op->frames_abs, 0);
+	}
+}
+
+static void bcm_update_tx_stats(struct bcm_op *op)
+{
+	/* tx_op has no reduction% calculation - use the full range and
+	 * just keep the displayed counter non-negative on overflow
+	 */
+	if (atomic_long_inc_return(&op->frames_abs) == LONG_MAX)
+		atomic_long_set(&op->frames_abs, 0);
+}
+
 /*
  * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
  *              of the given bcm tx op
@@ -340,7 +362,7 @@ static void bcm_can_tx(struct bcm_op *op, struct canfd_frame *cf)
 	spin_lock_bh(&op->bcm_tx_lock);
 
 	if (!err)
-		op->frames_abs++;
+		bcm_update_tx_stats(op);
 
 	/* only advance the cyclic sequence if nothing reset currframe while
 	 * we were sending - a concurrent TX_RESET_MULTI_IDX means this
@@ -500,12 +522,9 @@ static void bcm_rx_changed(struct bcm_op *op, struct canfd_frame *data)
 {
 	struct bcm_msg_head head;
 
-	/* update statistics */
-	op->frames_filtered++;
-
-	/* prevent statistics overflow */
-	if (op->frames_filtered > ULONG_MAX/100)
-		op->frames_filtered = op->frames_abs = 0;
+	/* update statistics (frames_filtered <= frames_abs) */
+	if (atomic_long_read(&op->frames_abs))
+		atomic_long_inc(&op->frames_filtered);
 
 	/* this element is not throttled anymore */
 	data->flags &= ~RX_THR;
@@ -751,24 +770,30 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 	op->rx_stamp = skb->tstamp;
 	/* save originator for recvfrom() */
 	op->rx_ifindex = skb->dev->ifindex;
-	/* update statistics */
-	op->frames_abs++;
 
-	/* snapshot the flag under lock: op->flags/op->frames may be updated
-	 * concurrently by bcm_rx_setup().
-	 */
+	/* op->flags/op->frames may be updated concurrently by bcm_rx_setup() */
 	spin_lock_bh(&op->bcm_rx_update_lock);
+
 	rtr_frame = op->flags & RX_RTR_FRAME;
-	if (rtr_frame)
+	if (rtr_frame) {
+		bcm_update_rx_stats(op);
+		/* snapshot RTR content under lock */
 		memcpy(&rtrframe, op->frames, op->cfsiz);
-	spin_unlock_bh(&op->bcm_rx_update_lock);
+		spin_unlock_bh(&op->bcm_rx_update_lock);
 
-	if (rtr_frame) {
 		/* send reply for RTR-request (placed in op->frames[0]) */
 		bcm_can_tx(op, &rtrframe);
 		return;
 	}
 
+	/* update statistics in the same critical section as bcm_rx_changed()
+	 * below: frames_filtered must never be checked/incremented against a
+	 * frames_abs snapshot from a concurrent bcm_rx_handler() call on
+	 * another CPU for the same (wildcard) op, or frames_filtered can end
+	 * up larger than frames_abs.
+	 */
+	bcm_update_rx_stats(op);
+
 	/* compute flags to distinguish between own/local/remote CAN traffic */
 	traffic_flags = 0;
 	if (skb->sk) {
@@ -777,8 +802,6 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 			traffic_flags |= RX_OWN;
 	}
 
-	spin_lock_bh(&op->bcm_rx_update_lock);
-
 	if (op->flags & RX_FILTER_ID) {
 		/* the easiest case */
 		bcm_rx_update_and_send(op, op->last_frames, rxframe,
Signature · 1 line
2.53.0
author maintainer
#18 lore raw

PATCH 18/675 can: bcm: extend bcm_tx_lock usage for data and timer updates

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 12ce799f7ab1e05bd8fbf79e46f403bfe5597ebc upstream.

Stage new CAN frame content for an existing tx op into a kmalloc()'d buffer and validate it there, mirroring the approach already used in bcm_rx_setup(). Only copy the validated data into op->frames while holding op->bcm_tx_lock, so bcm_can_tx() and bcm_tx_timeout_handler() can no longer observe a partially updated or unvalidated frame.

Add a missing error path for memcpy_from_msg() when copying CAN frame data from userspace.

Also move the kt_ival1/kt_ival2/ival1/ival2 updates in bcm_tx_setup() under op->bcm_tx_lock, and read kt_ival1/kt_ival2/count under the same lock in bcm_tx_set_expiry() and bcm_tx_timeout_handler(), closing the torn 64-bit ktime_t read on 32-bit platforms.

---
 net/can/bcm.c | 104 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 75 insertions(+), 29 deletions(-)
net/can/bcm.c +75 -29
index 1d4323cdf48a47..d7f91afda3c85d 100644
@@ -127,7 +127,7 @@ struct bcm_op {
 	struct canfd_frame last_sframe;
 	struct sock *sk;
 	struct net_device *rx_reg_dev;
-	spinlock_t bcm_tx_lock; /* protect currframe/count in runtime updates */
+	spinlock_t bcm_tx_lock; /* protect tx data and timer updates */
 	spinlock_t bcm_rx_update_lock; /* protect filter/timer data updates */
 };
 
@@ -467,12 +467,18 @@ static bool bcm_tx_set_expiry(struct bcm_op *op, struct hrtimer *hrt)
 {
 	ktime_t ival;
 
+	spin_lock_bh(&op->bcm_tx_lock);
+
 	if (op->kt_ival1 && op->count)
 		ival = op->kt_ival1;
-	else if (op->kt_ival2)
+	else if (op->kt_ival2) {
 		ival = op->kt_ival2;
-	else
+	} else {
+		spin_unlock_bh(&op->bcm_tx_lock);
 		return false;
+	}
+
+	spin_unlock_bh(&op->bcm_tx_lock);
 
 	hrtimer_set_expires(hrt, ktime_add(ktime_get(), ival));
 	return true;
@@ -489,25 +495,47 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
 {
 	struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);
 	struct bcm_msg_head msg_head;
+	bool tx_ival1, tx_ival2;
+
+	/* snapshot kt_ival1/kt_ival2/count under lock to avoid torn
+	 * ktime_t reads racing with concurrent bcm_tx_setup() updates
+	 */
+	spin_lock_bh(&op->bcm_tx_lock);
+	tx_ival1 = op->kt_ival1 && (op->count > 0);
+	tx_ival2 = !!op->kt_ival2;
+	spin_unlock_bh(&op->bcm_tx_lock);
+
+	if (tx_ival1) {
+		u32 flags, count;
+		struct bcm_timeval ival1, ival2;
 
-	if (op->kt_ival1 && (op->count > 0)) {
 		bcm_can_tx(op, NULL);
-		if (!op->count && (op->flags & TX_COUNTEVT)) {
 
+		/* snapshot variables under lock to avoid torn reads racing
+		 * with concurrent bcm_tx_setup() updates
+		 */
+		spin_lock_bh(&op->bcm_tx_lock);
+		flags = op->flags;
+		count = op->count;
+		ival1 = op->ival1;
+		ival2 = op->ival2;
+		spin_unlock_bh(&op->bcm_tx_lock);
+
+		if (!count && (flags & TX_COUNTEVT)) {
 			/* create notification to user */
 			memset(&msg_head, 0, sizeof(msg_head));
 			msg_head.opcode  = TX_EXPIRED;
-			msg_head.flags   = op->flags;
-			msg_head.count   = op->count;
-			msg_head.ival1   = op->ival1;
-			msg_head.ival2   = op->ival2;
+			msg_head.flags   = flags;
+			msg_head.count   = count;
+			msg_head.ival1   = ival1;
+			msg_head.ival2   = ival2;
 			msg_head.can_id  = op->can_id;
 			msg_head.nframes = 0;
 
 			bcm_send_to_user(op, &msg_head, NULL, 0);
 		}
 
-	} else if (op->kt_ival2) {
+	} else if (tx_ival2) {
 		bcm_can_tx(op, NULL);
 	}
 
@@ -1031,6 +1059,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	/* check the given can_id */
 	op = bcm_find_op(&bo->tx_ops, msg_head, ifindex);
 	if (op) {
+		void *new_frames;
+
 		/* update existing BCM operation */
 
 		/*
@@ -1041,11 +1071,23 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		if (msg_head->nframes > op->nframes)
 			return -E2BIG;
 
-		/* update CAN frames content */
+		/* get new CAN frames content into a staging buffer before
+		 * locking: validate and normalize the frames there so that
+		 * bcm_can_tx() / bcm_tx_timeout_handler() never observe a
+		 * partially updated or unvalidated frame in op->frames
+		 */
+		new_frames = kmalloc(msg_head->nframes * op->cfsiz, GFP_KERNEL);
+		if (!new_frames)
+			return -ENOMEM;
+
 		for (i = 0; i < msg_head->nframes; i++) {
 
-			cf = op->frames + op->cfsiz * i;
+			cf = new_frames + op->cfsiz * i;
 			err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz);
+			if (err < 0) {
+				kfree(new_frames);
+				return err;
+			}
 
 			if (op->flags & CAN_FD_FRAME) {
 				if (cf->len > 64)
@@ -1055,36 +1097,38 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 					err = -EINVAL;
 			}
 
-			if (err < 0)
+			if (err < 0) {
+				kfree(new_frames);
 				return err;
+			}
 
 			if (msg_head->flags & TX_CP_CAN_ID) {
 				/* copy can_id into frame */
 				cf->can_id = msg_head->can_id;
 			}
 		}
+
+		spin_lock_bh(&op->bcm_tx_lock);
+
+		/* update CAN frames content */
+		memcpy(op->frames, new_frames, msg_head->nframes * op->cfsiz);
+
 		op->flags = msg_head->flags;
 
-		/* only lock for unlikely count/nframes/currframe changes */
 		if (op->nframes != msg_head->nframes ||
-		    op->flags & TX_RESET_MULTI_IDX ||
-		    op->flags & SETTIMER) {
-
-			spin_lock_bh(&op->bcm_tx_lock);
+		    op->flags & TX_RESET_MULTI_IDX) {
+			/* potentially update changed nframes */
+			op->nframes = msg_head->nframes;
+			/* restart multiple frame transmission */
+			op->currframe = 0;
+		}
 
-			if (op->nframes != msg_head->nframes ||
-			    op->flags & TX_RESET_MULTI_IDX) {
-				/* potentially update changed nframes */
-				op->nframes = msg_head->nframes;
-				/* restart multiple frame transmission */
-				op->currframe = 0;
-			}
+		if (op->flags & SETTIMER)
+			op->count = msg_head->count;
 
-			if (op->flags & SETTIMER)
-				op->count = msg_head->count;
+		spin_unlock_bh(&op->bcm_tx_lock);
 
-			spin_unlock_bh(&op->bcm_tx_lock);
-		}
+		kfree(new_frames);
 
 	} else {
 		/* insert new BCM operation for the given can_id */
@@ -1160,10 +1204,12 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 
 	if (op->flags & SETTIMER) {
 		/* set timer values */
+		spin_lock_bh(&op->bcm_tx_lock);
 		op->ival1 = msg_head->ival1;
 		op->ival2 = msg_head->ival2;
 		op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
 		op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
+		spin_unlock_bh(&op->bcm_tx_lock);
 
 		/* disable an active timer due to zero values? */
 		if (!op->kt_ival1 && !op->kt_ival2)
Signature · 1 line
2.53.0
author maintainer
#19 lore raw

PATCH 19/675 can: bcm: validate frame length in bcm_rx_setup() for RTR replies

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 62ec41f364648be79d54d94d0d240ee326948afd upstream.

bcm_tx_setup() validates cf->len against the CAN/CAN FD DLC limits before installing frames for TX_SETUP, but bcm_rx_setup() never did the same for the RTR-reply frame configured via RX_SETUP with RX_RTR_FRAME.

---
 net/can/bcm.c | 59 +++++++++++++++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 18 deletions(-)
net/can/bcm.c +41 -18
index d7f91afda3c85d..2de64d7a99a216 100644
@@ -1241,22 +1241,37 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	return err;
 }
 
-static void bcm_rx_setup_rtr_check(struct bcm_msg_head *msg_head,
-				   struct bcm_op *op, void *new_frames)
+static int bcm_rx_setup_rtr_check(struct bcm_msg_head *msg_head,
+				  struct bcm_op *op, void *new_frames)
 {
+	struct canfd_frame *frame0 = new_frames;
+
+	if (!(msg_head->flags & RX_RTR_FRAME))
+		return 0;
+
+	/* this frame is sent out as-is by bcm_can_tx() whenever a matching
+	 * remote request is received, so validate its length the same way
+	 * bcm_tx_setup() validates TX_SETUP frames before installing it
+	 */
+	if (msg_head->flags & CAN_FD_FRAME) {
+		if (frame0->len > 64)
+			return -EINVAL;
+	} else {
+		if (frame0->len > 8)
+			return -EINVAL;
+	}
+
 	/* funny feature in RX(!)_SETUP only for RTR-mode:
 	 * copy can_id into frame BUT without RTR-flag to
 	 * prevent a full-load-loopback-test ... ;-]
 	 * normalize this on the staged buffer, before it is
 	 * ever installed into op->frames.
 	 */
-	if (msg_head->flags & RX_RTR_FRAME) {
-		struct canfd_frame *frame0 = new_frames;
+	if ((msg_head->flags & TX_CP_CAN_ID) ||
+	    frame0->can_id == op->can_id)
+		frame0->can_id = op->can_id & ~CAN_RTR_FLAG;
 
-		if ((msg_head->flags & TX_CP_CAN_ID) ||
-		    frame0->can_id == op->can_id)
-			frame0->can_id = op->can_id & ~CAN_RTR_FLAG;
-	}
+	return 0;
 }
 
 /*
@@ -1319,7 +1334,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 				return err;
 			}
 
-			bcm_rx_setup_rtr_check(msg_head, op, new_frames);
+			err = bcm_rx_setup_rtr_check(msg_head, op, new_frames);
+			if (err < 0) {
+				kfree(new_frames);
+				return err;
+			}
 		}
 
 		spin_lock_bh(&op->bcm_rx_update_lock);
@@ -1392,16 +1411,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		if (msg_head->nframes) {
 			err = memcpy_from_msg(op->frames, msg,
 					      msg_head->nframes * op->cfsiz);
-			if (err < 0) {
-				if (op->frames != &op->sframe)
-					kfree(op->frames);
-				if (op->last_frames != &op->last_sframe)
-					kfree(op->last_frames);
-				kfree(op);
-				return err;
-			}
+			if (err < 0)
+				goto free_op;
 
-			bcm_rx_setup_rtr_check(msg_head, op, op->frames);
+			err = bcm_rx_setup_rtr_check(msg_head, op, op->frames);
+			if (err < 0)
+				goto free_op;
 		}
 
 		/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1500,6 +1515,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	}
 
 	return msg_head->nframes * op->cfsiz + MHSIZ;
+
+free_op:
+	if (op->frames != &op->sframe)
+		kfree(op->frames);
+	if (op->last_frames != &op->last_sframe)
+		kfree(op->last_frames);
+	kfree(op);
+	return err;
 }
 
 /*
Signature · 1 line
2.53.0
author maintainer
#20 lore raw

PATCH 20/675 can: bcm: add missing device refcount for CAN filter removal

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit d59948293ea34b6337ce2b5febab8510de70048c upstream.

sashiko-bot remarked a problem with a concurrent device unregistration in isotp.c which also is present in the bcm.c code. A former fix for raw.c commit c275a176e4b6 ("can: raw: add missing refcount for memory leak fix") introduced a netdevice_tracker which solves the issue for bcm.c too.

bcm_release(), bcm_delete_rx_op() and bcm_notifier() relied on dev_get_by_index(ifindex) to re-find the device for an rx_op before unregistering its filter. If a concurrent NETDEV_UNREGISTER has already unlisted the device from the ifindex table, that lookup fails and can_rx_unregister() is silently skipped, leaving a stale CAN filter pointing at the soon-to-be-freed bcm_op/socket.

Hold a netdev_hold()/netdev_put() tracked reference on op->rx_reg_dev from the moment the rx filter is registered in bcm_rx_setup() until it is unregistered in bcm_rx_unreg(), and use that reference directly in bcm_release() and bcm_delete_rx_op() instead of re-looking the device up by ifindex.

---
 net/can/bcm.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)
net/can/bcm.c +24 -20
index 2de64d7a99a216..ca0dd2229f5b86 100644
@@ -932,6 +932,7 @@ static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
 
 		/* mark as removed subscription */
 		op->rx_reg_dev = NULL;
+		dev_put(dev);
 	} else
 		printk(KERN_ERR "can-bcm: bcm_rx_unreg: registered device "
 		       "mismatch %p %p\n", op->rx_reg_dev, dev);
@@ -962,17 +963,14 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 				 * Only remove subscriptions that had not
 				 * been removed due to NETDEV_UNREGISTER
 				 * in bcm_notifier()
+				 *
+				 * op->rx_reg_dev is a tracked reference taken
+				 * when the subscription was registered, so it
+				 * stays valid here even if a concurrent
+				 * NETDEV_UNREGISTER already unlisted the dev.
 				 */
-				if (op->rx_reg_dev) {
-					struct net_device *dev;
-
-					dev = dev_get_by_index(sock_net(op->sk),
-							       op->ifindex);
-					if (dev) {
-						bcm_rx_unreg(dev, op);
-						dev_put(dev);
-					}
-				}
+				if (op->rx_reg_dev)
+					bcm_rx_unreg(op->rx_reg_dev, op);
 			} else
 				can_rx_unregister(sock_net(op->sk), NULL,
 						  op->can_id,
@@ -1491,7 +1489,15 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 						      bcm_rx_handler, op,
 						      "bcm", sk);
 
-				op->rx_reg_dev = dev;
+				/* keep a reference so that a later
+				 * unregister can safely reach the device even
+				 * if a concurrent NETDEV_UNREGISTER has
+				 * already unlisted it by ifindex
+				 */
+				if (!err) {
+					op->rx_reg_dev = dev;
+					dev_hold(dev);
+				}
 				dev_put(dev);
 			} else {
 				/* the requested device is gone - do not
@@ -1864,16 +1870,14 @@ static int bcm_release(struct socket *sock)
 			 * Only remove subscriptions that had not
 			 * been removed due to NETDEV_UNREGISTER
 			 * in bcm_notifier()
+			 *
+			 * op->rx_reg_dev is a tracked reference taken
+			 * when the subscription was registered, so it
+			 * stays valid here even if a concurrent
+			 * NETDEV_UNREGISTER already unlisted the device.
 			 */
-			if (op->rx_reg_dev) {
-				struct net_device *dev;
-
-				dev = dev_get_by_index(net, op->ifindex);
-				if (dev) {
-					bcm_rx_unreg(dev, op);
-					dev_put(dev);
-				}
-			}
+			if (op->rx_reg_dev)
+				bcm_rx_unreg(op->rx_reg_dev, op);
 		} else
 			can_rx_unregister(net, NULL, op->can_id,
 					  REGMASK(op->can_id),
Signature · 1 line
2.53.0
author maintainer
#21 lore raw

PATCH 21/675 can: bcm: fix stale rx/tx ops after device removal

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 3b762c0d950383ab7a002686c9136b9aa55d2d70 upstream.

RX: an RX_SETUP update(!) for an existing op skipped can_rx_register() unconditionally, even when a concurrent NETDEV_UNREGISTER had already torn down its registration (op->rx_reg_dev == NULL). This silently did not re-enable frame delivery for that updated filter. bcm_rx_setup() now re-registers in that case, while leaving rx_ops with ifindex = 0 (all CAN devices) which never carry a tracked rx_reg_dev registered as-is.

TX: bcm_notify() only handled bo->rx_ops on NETDEV_UNREGISTER, leaving tx_ops with an active cyclic transmission re-arming its hrtimer indefinitely to execute bcm_tx_timeout_handler(). Cancelling the hrtimer prevents the runaway timer and any injection into a later reused ifindex, since nothing else calls bcm_can_tx() for the op until an explicit TX_SETUP update re-arms it.

Unlike bcm_rx_unreg(), which clears the tracked rx_reg_dev for rx_ops, the ifindex is intentionally left unchanged for tx_ops. bcm_tx_setup() always rejects ifindex 0, so clearing it would strand the op: neither a later TX_SETUP (bcm_find_op()) nor TX_DELETE (bcm_delete_tx_op()) could ever find it again, since both require an exact ifindex match.

---
 net/can/bcm.c | 54 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 10 deletions(-)
net/can/bcm.c +44 -10
index ca0dd2229f5b86..8c138376591f37 100644
@@ -1281,6 +1281,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 	struct bcm_sock *bo = bcm_sk(sk);
 	struct bcm_op *op;
 	int do_rx_register;
+	int new_op = 0;
 	int err = 0;
 
 	if ((msg_head->flags & RX_FILTER_ID) || (!(msg_head->nframes))) {
@@ -1365,8 +1366,15 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		/* free temporary frames / kfree(NULL) is safe */
 		kfree(new_frames);
 
-		/* Only an update -> do not call can_rx_register() */
-		do_rx_register = 0;
+		/* Don't register a new CAN filter for the rx_op update unless
+		 * a concurrent NETDEV_UNREGISTER notifier already tore down
+		 * the previous registration. In this case the receiver needs
+		 * to be re-registered here so that this update doesn't
+		 * silently stop delivering frames for the given ifindex.
+		 * Ops with ifindex = 0 (all CAN interfaces) never carry a
+		 * tracked rx_reg_dev and stay registered as-is.
+		 */
+		do_rx_register = (ifindex && !op->rx_reg_dev) ? 1 : 0;
 
 	} else {
 		/* insert new BCM operation for the given can_id */
@@ -1433,6 +1441,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 
 		/* call can_rx_register() */
 		do_rx_register = 1;
+		new_op = 1;
 
 	} /* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
 
@@ -1446,7 +1455,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		if (op->flags & SETTIMER) {
 
 			/* set timers (locked) for newly created op */
-			if (do_rx_register) {
+			if (new_op) {
 				spin_lock_bh(&op->bcm_rx_update_lock);
 				op->ival1 = msg_head->ival1;
 				op->ival2 = msg_head->ival2;
@@ -1476,7 +1485,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 				      HRTIMER_MODE_REL_SOFT);
 	}
 
-	/* now we can register for can_ids, if we added a new bcm_op */
+	/* now we can register for can_ids, if we added a new bcm_op
+	 * or need to re-register after a NETDEV_UNREGISTER tore down
+	 * the previous registration of an existing op
+	 */
 	if (do_rx_register) {
 		if (ifindex) {
 			struct net_device *dev;
@@ -1506,18 +1518,32 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 				err = -ENODEV;
 			}
 
-		} else
+		} else {
 			err = can_rx_register(sock_net(sk), NULL, op->can_id,
 					      REGMASK(op->can_id),
 					      bcm_rx_handler, op, "bcm", sk);
+		}
+
 		if (err) {
-			/* this bcm rx op is broken -> remove it */
-			bcm_remove_op(op);
+			/* newly created bcm rx op is broken -> remove it */
+			if (new_op) {
+				bcm_remove_op(op);
+				return err;
+			}
+
+			/* an existing op just stays unregistered.
+			 * Cancel op->timer and (defensively) op->thrtimer.
+			 * Other settings can't be reached until the next
+			 * successful RX_SETUP.
+			 */
+			hrtimer_cancel(&op->timer);
+			hrtimer_cancel(&op->thrtimer);
 			return err;
 		}
 
-		/* add this bcm_op to the list of the rx_ops */
-		list_add_rcu(&op->list, &bo->rx_ops);
+		/* add a new bcm_op to the list of the rx_ops */
+		if (new_op)
+			list_add_rcu(&op->list, &bo->rx_ops);
 	}
 
 	return msg_head->nframes * op->cfsiz + MHSIZ;
@@ -1733,11 +1759,19 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,
 	case NETDEV_UNREGISTER:
 		lock_sock(sk);
 
-		/* remove device specific receive entries */
+		/* rx_ops: remove device specific receive entries */
 		list_for_each_entry(op, &bo->rx_ops, list)
 			if (op->rx_reg_dev == dev)
 				bcm_rx_unreg(dev, op);
 
+		/* tx_ops: stop device specific cyclic transmissions on the
+		 * vanishing ifindex. Cancelling the timer is enough to stop
+		 * cyclic bcm_can_tx() calls as there is no re-arming.
+		 */
+		list_for_each_entry(op, &bo->tx_ops, list)
+			if (op->ifindex == dev->ifindex)
+				hrtimer_cancel(&op->timer);
+
 		/* remove device reference, if this is our bound device */
 		if (bo->bound && bo->ifindex == dev->ifindex) {
 #if IS_ENABLED(CONFIG_PROC_FS)
Signature · 1 line
2.53.0
author maintainer
#22 lore raw

PATCH 22/675 can: bcm: fix data race on rx_stamp/rx_ifindex in bcm_rx_handler()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 58fd6cbc8541216af1d7ed272ea7ac2b66d50fd8 upstream.

For an rx op subscribed on all interfaces (ifindex == 0), the same op is registered once in the shared per-netns wildcard filter list, so bcm_rx_handler() can run concurrently on different CPUs for frames arriving on different net devices.

op->rx_stamp and op->rx_ifindex were written before bcm_rx_update_lock was taken, allowing concurrent writers to race each other - including a torn store of the 64-bit rx_stamp on 32-bit platforms.

Beyond a torn store bcm_send_to_user() must report the timestamp/ifindex of the very same frame whose content it is delivering. So the assignment is placed in the same unbroken bcm_rx_update_lock section as the content comparison.

As a side effect, the RTR-request frame feature (which never reach bcm_send_to_user()) no longer updates rx_stamp/rx_ifindex, since only the notification path needs them.

---
 net/can/bcm.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
net/can/bcm.c +8 -5
index 8c138376591f37..079a6a801f42e3 100644
@@ -794,11 +794,6 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 	/* disable timeout */
 	hrtimer_cancel(&op->timer);
 
-	/* save rx timestamp */
-	op->rx_stamp = skb->tstamp;
-	/* save originator for recvfrom() */
-	op->rx_ifindex = skb->dev->ifindex;
-
 	/* op->flags/op->frames may be updated concurrently by bcm_rx_setup() */
 	spin_lock_bh(&op->bcm_rx_update_lock);
 
@@ -830,6 +825,14 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 			traffic_flags |= RX_OWN;
 	}
 
+	/* save rx timestamp and originator for recvfrom() under lock.
+	 * For an op subscribed on all interfaces (ifindex == 0)
+	 * bcm_rx_handler() can run concurrently on different CPUs so
+	 * the CAN content and the meta data must be bundled correctly.
+	 */
+	op->rx_stamp = skb->tstamp;
+	op->rx_ifindex = skb->dev->ifindex;
+
 	if (op->flags & RX_FILTER_ID) {
 		/* the easiest case */
 		bcm_rx_update_and_send(op, op->last_frames, rxframe,
Signature · 1 line
2.53.0
author maintainer
#23 lore raw

PATCH 23/675 can: bcm: track a single source interface for ANYDEV timeout/throttle ops

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Oliver Hartkopp <[email protected]>

commit 2f5976f54a04e9f18b25283036ac3136be453b17 upstream.

An ANYDEV rx op (ifindex == 0) with an active RX timeout and/or throttle timer has no defined semantics when matching frames arrive from several interfaces: bcm_rx_handler() can run concurrently for the same op on different CPUs, racing hrtimer_cancel()/ bcm_rx_starttimer() against bcm_rx_timeout_handler() and causing spurious RX_TIMEOUT notifications and last_frames corruption. The same concurrency lets throttled multiplex frames from different interfaces clobber the single rx_ifindex/rx_stamp fields shared by the op.

Add op->if_detected to track the first interface that delivers a matching frame while a timeout/throttle timer is configured, and reject frames from any other interface for that op. The claim is decided in bcm_rx_handler() before hrtimer_cancel() touches op->timer, so a rejected frame can never disturb the claimed interface's watchdog. RTR-mode ops are excluded via RX_RTR_FRAME, independent of kt_ival1/kt_ival2, since those may briefly hold a stale value from an earlier non-RTR configuration.

The claim is released in bcm_notify() on NETDEV_UNREGISTER and in bcm_rx_setup() when SETTIMER reconfigures the timer values.

A (re-)claim is only possible on CAN devices in NETREG_REGISTERED dev->reg_state to cover the release in bcm_notify() where reg_state becomes NETREG_UNREGISTERING until synchronize_net().

---
 net/can/bcm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)
net/can/bcm.c +44 -5
index 079a6a801f42e3..76bc7f72742535 100644
@@ -116,6 +116,7 @@ struct bcm_op {
 	struct hrtimer timer, thrtimer;
 	ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
 	int rx_ifindex;
+	int if_detected; /* first received ifindex in ANYDEV rx_op mode */
 	int cfsiz;
 	u32 count;
 	u32 nframes;
@@ -791,6 +792,33 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 			return;
 	}
 
+	/* An ANYDEV op with an active RX timeout and/or throttle timer
+	 * tracks a single source interface: claim the first interface that
+	 * delivers a matching frame and reject frames from any other one,
+	 * before hrtimer_cancel() below can touch op->timer - this avoids
+	 * racing bcm_rx_timeout_handler() across concurrent interfaces.
+	 * RX_RTR_FRAME ops are excluded, as kt_ival1/kt_ival2 may briefly
+	 * hold a stale value from an earlier non-RTR configuration.
+	 */
+	if (!op->ifindex) {
+		spin_lock_bh(&op->bcm_rx_update_lock);
+
+		if (!(op->flags & RX_RTR_FRAME) &&
+		    (op->kt_ival1 || op->kt_ival2)) {
+			/* don't claim to vanishing interface */
+			if (!op->if_detected &&
+			    skb->dev->reg_state == NETREG_REGISTERED)
+				op->if_detected = skb->dev->ifindex;
+
+			if (op->if_detected != skb->dev->ifindex) {
+				spin_unlock_bh(&op->bcm_rx_update_lock);
+				return;
+			}
+		}
+
+		spin_unlock_bh(&op->bcm_rx_update_lock);
+	}
+
 	/* disable timeout */
 	hrtimer_cancel(&op->timer);
 
@@ -825,10 +853,9 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
 			traffic_flags |= RX_OWN;
 	}
 
-	/* save rx timestamp and originator for recvfrom() under lock.
-	 * For an op subscribed on all interfaces (ifindex == 0)
-	 * bcm_rx_handler() can run concurrently on different CPUs so
-	 * the CAN content and the meta data must be bundled correctly.
+	/* save rx timestamp and originator for recvfrom() under lock: an
+	 * ANYDEV op without an active timer can still run concurrently on
+	 * different CPUs, so content and meta data must be bundled here.
 	 */
 	op->rx_stamp = skb->tstamp;
 	op->rx_ifindex = skb->dev->ifindex;
@@ -1363,6 +1390,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
 			op->kt_ival2 = bcm_timeval_to_ktime(msg_head->ival2);
 			op->kt_lastmsg = 0;
+			op->if_detected = 0; /* reclaim ifindex in ANYDEV mode */
 		}
 		spin_unlock_bh(&op->bcm_rx_update_lock);
 
@@ -1763,10 +1791,21 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,
 		lock_sock(sk);
 
 		/* rx_ops: remove device specific receive entries */
-		list_for_each_entry(op, &bo->rx_ops, list)
+		list_for_each_entry(op, &bo->rx_ops, list) {
 			if (op->rx_reg_dev == dev)
 				bcm_rx_unreg(dev, op);
 
+			/* release an ANYDEV op's claim (see bcm_rx_handler())
+			 * on this now confirmed-gone interface.
+			 */
+			if (!op->ifindex) {
+				spin_lock_bh(&op->bcm_rx_update_lock);
+				if (op->if_detected == dev->ifindex)
+					op->if_detected = 0;
+				spin_unlock_bh(&op->bcm_rx_update_lock);
+			}
+		}
+
 		/* tx_ops: stop device specific cyclic transmissions on the
 		 * vanishing ifindex. Cancelling the timer is enough to stop
 		 * cyclic bcm_can_tx() calls as there is no re-arming.
Signature · 1 line
2.53.0
author maintainer
#24 lore raw

PATCH 24/675 dmaengine: sh: rz-dmac: Move interrupt request after everything is set up

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Claudiu Beznea <[email protected]>

commit 731712403ddb39d1a76a11abf339a0615bc85de7 upstream.

Once the interrupt is requested, the interrupt handler may run immediately. Since the IRQ handler can access channel->ch_base, which is initialized only after requesting the IRQ, this may lead to invalid memory access. Likewise, the IRQ thread may access uninitialized data (the ld_free, ld_queue, and ld_active lists), which may also lead to issues.

Request the interrupts only after everything is set up. To keep the error path simpler, use dmam_alloc_coherent() instead of dma_alloc_coherent().

[tm: Kept the channel->irq field in rz_dmac_chan_probe() instead of
upstream's local irq variable, as commit 04e227718ab8 ("dmaengine: sh: rz-dmac: Make channel irq local") is not present in this tree. Likewise kept platform_get_irq_byname() instead of platform_get_irq_byname_optional() for the error IRQ in rz_dmac_probe(), as commit 6b3a6b6dc074 ("dmaengine: sh: rz_dmac: make error interrupt optional") is not present in this tree either; its early return on failure becomes a goto err jump to match the new call order.]

---
 drivers/dma/sh/rz-dmac.c | 96 ++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 58 deletions(-)
drivers/dma/sh/rz-dmac.c +38 -58
index 818d1ef6f0bf94..4db84b83177a6d 100644
@@ -811,27 +811,6 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
 	channel->index = index;
 	channel->mid_rid = -EINVAL;
 
-	/* Request the channel interrupt. */
-	scnprintf(pdev_irqname, sizeof(pdev_irqname), "ch%u", index);
-	channel->irq = platform_get_irq_byname(pdev, pdev_irqname);
-	if (channel->irq < 0)
-		return channel->irq;
-
-	irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u",
-				 dev_name(dmac->dev), index);
-	if (!irqname)
-		return -ENOMEM;
-
-	ret = devm_request_threaded_irq(dmac->dev, channel->irq,
-					rz_dmac_irq_handler,
-					rz_dmac_irq_handler_thread, 0,
-					irqname, channel);
-	if (ret) {
-		dev_err(dmac->dev, "failed to request IRQ %u (%d)\n",
-			channel->irq, ret);
-		return ret;
-	}
-
 	/* Set io base address for each channel */
 	if (index < 8) {
 		channel->ch_base = dmac->base + CHANNEL_0_7_OFFSET +
@@ -844,9 +823,9 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
 	}
 
 	/* Allocate descriptors */
-	lmdesc = dma_alloc_coherent(&pdev->dev,
-				    sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
-				    &channel->lmdesc.base_dma, GFP_KERNEL);
+	lmdesc = dmam_alloc_coherent(&pdev->dev,
+				     sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
+				     &channel->lmdesc.base_dma, GFP_KERNEL);
 	if (!lmdesc) {
 		dev_err(&pdev->dev, "Can't allocate memory (lmdesc)\n");
 		return -ENOMEM;
@@ -862,7 +841,26 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,
 	INIT_LIST_HEAD(&channel->ld_free);
 	INIT_LIST_HEAD(&channel->ld_active);
 
-	return 0;
+	/* Request the channel interrupt. */
+	scnprintf(pdev_irqname, sizeof(pdev_irqname), "ch%u", index);
+	channel->irq = platform_get_irq_byname(pdev, pdev_irqname);
+	if (channel->irq < 0)
+		return channel->irq;
+
+	irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u",
+				 dev_name(dmac->dev), index);
+	if (!irqname)
+		return -ENOMEM;
+
+	ret = devm_request_threaded_irq(dmac->dev, channel->irq,
+					rz_dmac_irq_handler,
+					rz_dmac_irq_handler_thread, 0,
+					irqname, channel);
+	if (ret)
+		dev_err(dmac->dev, "failed to request IRQ %u (%d)\n",
+			channel->irq, ret);
+
+	return ret;
 }
 
 static void rz_dmac_put_device(void *_dev)
@@ -932,7 +930,6 @@ static int rz_dmac_probe(struct platform_device *pdev)
 	const char *irqname = "error";
 	struct dma_device *engine;
 	struct rz_dmac *dmac;
-	int channel_num;
 	int ret;
 	int irq;
 	u8 i;
@@ -964,19 +961,6 @@ static int rz_dmac_probe(struct platform_device *pdev)
 			return PTR_ERR(dmac->ext_base);
 	}
 
-	/* Register interrupt handler for error */
-	irq = platform_get_irq_byname(pdev, irqname);
-	if (irq < 0)
-		return irq;
-
-	ret = devm_request_irq(&pdev->dev, irq, rz_dmac_irq_handler, 0,
-			       irqname, NULL);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
-			irq, ret);
-		return ret;
-	}
-
 	/* Initialize the channels. */
 	INIT_LIST_HEAD(&dmac->engine.channels);
 
@@ -1002,6 +986,21 @@ static int rz_dmac_probe(struct platform_device *pdev)
 			goto err;
 	}
 
+	/* Register interrupt handler for error */
+	irq = platform_get_irq_byname(pdev, irqname);
+	if (irq < 0) {
+		ret = irq;
+		goto err;
+	}
+
+	ret = devm_request_irq(&pdev->dev, irq, rz_dmac_irq_handler, 0,
+			       irqname, NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
+			irq, ret);
+		goto err;
+	}
+
 	/* Register the DMAC as a DMA provider for DT. */
 	ret = of_dma_controller_register(pdev->dev.of_node, rz_dmac_of_xlate,
 					 NULL);
@@ -1040,16 +1039,6 @@ static int rz_dmac_probe(struct platform_device *pdev)
 dma_register_err:
 	of_dma_controller_free(pdev->dev.of_node);
 err:
-	channel_num = i ? i - 1 : 0;
-	for (i = 0; i < channel_num; i++) {
-		struct rz_dmac_chan *channel = &dmac->channels[i];
-
-		dma_free_coherent(&pdev->dev,
-				  sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
-				  channel->lmdesc.base,
-				  channel->lmdesc.base_dma);
-	}
-
 	reset_control_assert(dmac->rstc);
 err_pm_runtime_put:
 	pm_runtime_put(&pdev->dev);
@@ -1062,18 +1051,9 @@ static int rz_dmac_probe(struct platform_device *pdev)
 static void rz_dmac_remove(struct platform_device *pdev)
 {
 	struct rz_dmac *dmac = platform_get_drvdata(pdev);
-	unsigned int i;
 
 	dma_async_device_unregister(&dmac->engine);
 	of_dma_controller_free(pdev->dev.of_node);
-	for (i = 0; i < dmac->n_channels; i++) {
-		struct rz_dmac_chan *channel = &dmac->channels[i];
-
-		dma_free_coherent(&pdev->dev,
-				  sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
-				  channel->lmdesc.base,
-				  channel->lmdesc.base_dma);
-	}
 	reset_control_assert(dmac->rstc);
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
Signature · 1 line
2.53.0
author maintainer
#25 lore raw

PATCH 25/675 gpu: host1x: Fix use-after-free in host1x_bo_clear_cached_mappings

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mikko Perttunen <[email protected]>

[ Upstream commit 266cddf7bd0f6c79b6c0633aef742a22bf70265b ]

__host1x_bo_unpin() drops the last reference to the mapping and frees it, so we can't dereference mapping afterwards. The cache itself outlives the mapping, so use the cache local variable instead.

---
 drivers/gpu/host1x/bus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/host1x/bus.c +2 -2
index 3801eab63282ff..3313ead8bfcc24 100644
@@ -1001,10 +1001,10 @@ void host1x_bo_clear_cached_mappings(struct host1x_bo *bo)
 		if (WARN_ON(!cache))
 			continue;
 
-		mutex_lock(&mapping->cache->lock);
+		mutex_lock(&cache->lock);
 		WARN_ON(kref_read(&mapping->ref) != 1);
 		__host1x_bo_unpin(&mapping->ref);
-		mutex_unlock(&mapping->cache->lock);
+		mutex_unlock(&cache->lock);
 	}
 }
 EXPORT_SYMBOL(host1x_bo_clear_cached_mappings);
Signature · 1 line
2.53.0
author maintainer
#26 lore raw

PATCH 26/675 crypto: tegra - Dont touch bo refcount in host1x bo pin/unpin

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mikko Perttunen <[email protected]>

[ Upstream commit f8c9c57d750346abd213ffed2ae3cacb0268e9f1 ]

Since commit "gpu: host1x: Allow entries in BO caches to be freed", host1x_bo_pin() and host1x_bo_unpin() handle the bo's refcount themselves. .pin/.unpin callbacks should not adjust it.

---
 drivers/crypto/tegra/tegra-se-main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/crypto/tegra/tegra-se-main.c +1 -2
index 2755f19ad05e92..77b923a6b7c18c 100644
@@ -52,7 +52,7 @@ tegra_se_cmdbuf_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_dire
 		return ERR_PTR(-ENOMEM);
 
 	kref_init(&map->ref);
-	map->bo = host1x_bo_get(bo);
+	map->bo = bo;
 	map->direction = direction;
 	map->dev = dev;
 
@@ -93,7 +93,6 @@ static void tegra_se_cmdbuf_unpin(struct host1x_bo_mapping *map)
 	dma_unmap_sgtable(map->dev, map->sgt, map->direction, 0);
 	sg_free_table(map->sgt);
 	kfree(map->sgt);
-	host1x_bo_put(map->bo);
 
 	kfree(map);
 }
Signature · 1 line
2.53.0
author maintainer
#27 lore raw

PATCH 27/675 xprtrdma: Clear receive-side ownership pointers on release

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chuck Lever <[email protected]>

[ Upstream commit 2ae8e7afbc63bf84243367f89eb43571f0345a74 ]

Three small ownership-state cleanups land the transport in a state that lets future reviewers reason about each pointer locally rather than tracing the whole reply path:

rpcrdma_rep_put() clears rep->rr_rqst before the rep enters rb_free_reps so that no rep on the free list still carries a stale rqst pointer. rpcrdma_reply_handler() and rpcrdma_unpin_rqst() are the only sites that set rr_rqst; rpcrdma_reply_handler() hands the rep through rpcrdma_rep_put(), and rpcrdma_unpin_rqst() NULLs rr_rqst directly because its error path abandons the rep for teardown cleanup rather than returning it to rb_free_reps.

rpcrdma_reply_put() NULLs req->rl_reply before calling rpcrdma_rep_put(). The previous order placed the rep on rb_free_reps while req->rl_reply still pointed at it; the window was harmless because xprt_rdma_free_slot() holds the req exclusively across the pair, but closing it makes the invariant 'rep on rb_free_reps implies no req references it' strictly checkable.

rpcrdma_sendctx_unmap() and rpcrdma_sendctx_cancel() clear req->rl_sendctx after dropping the sendctx pointer in the sendctx ring. Without this, req->rl_sendctx survives across Send completion and points at a sendctx that may already have been reassigned by rpcrdma_sendctx_get_locked() to a different req. No caller dereferences the stale pointer today -- rpcrdma_prepare_send_sges() overwrites it before the next Send -- but a NULL is a more honest representation of 'the Send is no longer outstanding' and lets the assertion patch that follows trip on any future regression.

---
 net/sunrpc/xprtrdma/rpc_rdma.c |  4 ++++
 net/sunrpc/xprtrdma/verbs.c    | 12 ++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)
net/sunrpc/xprtrdma/rpc_rdma.c +4 -0
index 5d1f96bffd7491..e2694fb03ba1b3 100644
@@ -542,6 +542,7 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
 
 	rpcrdma_sendctx_dma_unmap(sc);
 	sc->sc_req = NULL;
+	req->rl_sendctx = NULL;
 	rpcrdma_req_put(req);
 }
 
@@ -550,8 +551,11 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
  */
 static void rpcrdma_sendctx_cancel(struct rpcrdma_sendctx *sc)
 {
+	struct rpcrdma_req *req = sc->sc_req;
+
 	rpcrdma_sendctx_dma_unmap(sc);
 	sc->sc_req = NULL;
+	req->rl_sendctx = NULL;
 }
 
 /* Prepare an SGE for the RPC-over-RDMA transport header.
net/sunrpc/xprtrdma/verbs.c +10 -2
index efd91ed249fabe..e2d3cee825cd7f 100644
@@ -1080,9 +1080,15 @@ static struct rpcrdma_rep *rpcrdma_rep_get_locked(struct rpcrdma_buffer *buf)
  * @buf: buffer pool
  * @rep: rep to release
  *
+ * The rep's transient association with an rpc_rqst, established
+ * by rpcrdma_reply_handler() and torn down here, must not survive
+ * onto rb_free_reps: rpcrdma_post_recvs() pulls reps from the free
+ * list to re-post them, and a non-NULL rr_rqst on a free-listed rep
+ * would imply the rep is still referenced by a req.
  */
 void rpcrdma_rep_put(struct rpcrdma_buffer *buf, struct rpcrdma_rep *rep)
 {
+	rep->rr_rqst = NULL;
 	llist_add(&rep->rr_node, &buf->rb_free_reps);
 }
 
@@ -1265,9 +1271,11 @@ rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt)
  */
 void rpcrdma_reply_put(struct rpcrdma_buffer *buffers, struct rpcrdma_req *req)
 {
-	if (req->rl_reply) {
-		rpcrdma_rep_put(buffers, req->rl_reply);
+	struct rpcrdma_rep *rep = req->rl_reply;
+
+	if (rep) {
 		req->rl_reply = NULL;
+		rpcrdma_rep_put(buffers, rep);
 	}
 	/* I2: rl_reply NULL after the put closes the
 	 * 'rep on rb_free_reps still referenced by req' window.
Signature · 1 line
2.53.0
author maintainer
#28 lore raw

PATCH 28/675 Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Seungjin Bae <[email protected]>

[ Upstream commit 875115b82c295277b81b6dfee7debc725f44e854 ]

The ims_pcu_process_data() processes incoming URB data byte by byte. However, it fails to check if the read_pos index exceeds IMS_PCU_BUF_SIZE.

If a malicious USB device sends a packet larger than IMS_PCU_BUF_SIZE, read_pos will increment indefinitely. Moreover, since read_pos is located immediately after read_buf, the attacker can overwrite read_pos itself to arbitrarily control the index.

This manipulated read_pos is subsequently used in ims_pcu_handle_response() to copy data into cmd_buf, leading to a heap buffer overflow.

Specifically, an attacker can overwrite the cmd_done.wait.head located at offset 136 relative to cmd_buf in the ims_pcu_handle_response(). Consequently, when the driver calls complete(&pcu->cmd_done), it triggers a control flow hijack by using the manipulated pointer.

Fix this by adding a bounds check for read_pos before writing to read_buf. If the packet is too long, discard it, log a warning, and reset the parser state.

Fixes 628329d524743 ("Input: add IMS Passenger Control Unit driver")
[dtor: factor out resetting packet state, reset checksum as well]
---
 drivers/input/misc/ims-pcu.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)
drivers/input/misc/ims-pcu.c +26 -6
index 94113e14bf5995..7c837094c498ed 100644
@@ -448,6 +448,14 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu)
 	}
 }
 
+static void ims_pcu_reset_packet(struct ims_pcu *pcu)
+{
+	pcu->have_stx = true;
+	pcu->have_dle = false;
+	pcu->read_pos = 0;
+	pcu->check_sum = 0;
+}
+
 static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
 {
 	int i;
@@ -460,6 +468,14 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
 			continue;
 
 		if (pcu->have_dle) {
+			if (pcu->read_pos >= IMS_PCU_BUF_SIZE) {
+				dev_warn(pcu->dev,
+					 "Packet too long (%d bytes), discarding\n",
+					 pcu->read_pos);
+				ims_pcu_reset_packet(pcu);
+				continue;
+			}
+
 			pcu->have_dle = false;
 			pcu->read_buf[pcu->read_pos++] = data;
 			pcu->check_sum += data;
@@ -472,10 +488,8 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
 				dev_warn(pcu->dev,
 					 "Unexpected STX at byte %d, discarding old data\n",
 					 pcu->read_pos);
+			ims_pcu_reset_packet(pcu);
 			pcu->have_stx = true;
-			pcu->have_dle = false;
-			pcu->read_pos = 0;
-			pcu->check_sum = 0;
 			break;
 
 		case IMS_PCU_PROTOCOL_DLE:
@@ -495,12 +509,18 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
 				ims_pcu_handle_response(pcu);
 			}
 
-			pcu->have_stx = false;
-			pcu->have_dle = false;
-			pcu->read_pos = 0;
+			ims_pcu_reset_packet(pcu);
 			break;
 
 		default:
+			if (pcu->read_pos >= IMS_PCU_BUF_SIZE) {
+				dev_warn(pcu->dev,
+					 "Packet too long (%d bytes), discarding\n",
+					 pcu->read_pos);
+				ims_pcu_reset_packet(pcu);
+				continue;
+			}
+
 			pcu->read_buf[pcu->read_pos++] = data;
 			pcu->check_sum += data;
 			break;
Signature · 1 line
2.53.0
author maintainer
#29 lore raw

PATCH 29/675 Input: ims-pcu - fix logic error in packet reset

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Torokhov <[email protected]>

[ Upstream commit 2c9b85a14abb4811e8d4773ccd13559e59792efb ]

ims_pcu_reset_packet() incorrectly sets have_stx to true, which implies that the start-of-packet delimiter has already been received. This causes the protocol parser to skip waiting for the next STX byte and potentially process garbage data.

Correctly set have_stx to false when resetting the packet state.

Fixes 875115b82c29 ("Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()")
Assisted-by Gemini:gemini-3.1-pro
---
 drivers/input/misc/ims-pcu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/misc/ims-pcu.c +1 -1
index 7c837094c498ed..168662a2cc890c 100644
@@ -450,7 +450,7 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu)
 
 static void ims_pcu_reset_packet(struct ims_pcu *pcu)
 {
-	pcu->have_stx = true;
+	pcu->have_stx = false;
 	pcu->have_dle = false;
 	pcu->read_pos = 0;
 	pcu->check_sum = 0;
Signature · 1 line
2.53.0
author maintainer
#30 lore raw

PATCH 30/675 fuse: fix writeback array overflow when max_pages is one

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Junxi Qian <[email protected]>

[ Upstream commit c3880a7b10e487e033dc6f388bda118436566f7a ]

fuse_iomap_writeback_range() appends one folio pointer and one fuse_folio_desc for every dirty range that is merged into the current writeback request. The merge decision checks the byte budget against fc->max_pages and fc->max_write, but it does not check whether the folio and descriptor arrays still have another free slot.

This is not sufficient for fuseblk, where the filesystem block size can be smaller than PAGE_SIZE. With writeback cache enabled and max_pages negotiated as one, contiguous sub-page dirty ranges can fit within the byte budget while spanning more than one folio. The next append can then write past the one-slot folios and descs arrays.

Split the request when the number of already attached folios has reached fc->max_pages. This keeps the folio/descriptor slot accounting in sync with the send decision.

---
 fs/fuse/file.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/fuse/file.c +4 -1
index 79d1b502e73195..585dd90361b654 100644
@@ -2140,7 +2140,10 @@ static bool fuse_writepage_need_send(struct fuse_conn *fc, loff_t pos,
 
 	WARN_ON(!ap->num_folios);
 
-	/* Reached max pages */
+	/* Reached max pages or max folio slots */
+	if (ap->num_folios >= fc->max_pages)
+		return true;
+
 	if ((bytes + PAGE_SIZE - 1) >> PAGE_SHIFT > fc->max_pages)
 		return true;
 
Signature · 1 line
2.53.0
author maintainer
#31 lore raw

PATCH 31/675 arm64: tegra: Remove fallback compatible for GPCDMA

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Akhil R <[email protected]>

[ Upstream commit ee7863e43228a3143398dc5bbb943c9a735a8fca ]

Remove the fallback compatible string "nvidia,tegra186-gpcdma" for GPCDMA in Tegra264. Tegra186 compatible cannot work on Tegra264 because of the register offset changes and absence of the reset property.

Fixes 65ef237e4810 ("arm64: tegra: Add Tegra264 support")
---
 arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/nvidia/tegra264.dtsi +1 -1
index 872a69553e3c82..b16d380209a50a 100644
@@ -50,7 +50,7 @@ timer@8000000 {
 		};
 
 		gpcdma: dma-controller@8400000 {
-			compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma";
+			compatible = "nvidia,tegra264-gpcdma";
 			reg = <0x0 0x08400000 0x0 0x210000>;
 			interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>,
Signature · 1 line
2.53.0
author maintainer
#32 lore raw

PATCH 32/675 arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sumit Gupta <[email protected]>

[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]

The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the compatible string for all CPU nodes to match the actual hardware.

Tegra234 hardware reports:

  # head /proc/cpuinfo | egrep 'implementer|part'
  CPU implementer : 0x41
  CPU part        : 0xd42

Which maps to (from arch/arm64/include/asm/cputype.h):
#define ARM_CPU_IMP_ARM 0x41
#define ARM_CPU_PART_CORTEX_A78AE 0xD42

Fixes a12cf5c339b08 ("arm64: tegra: Describe Tegra234 CPU hierarchy")
---
 arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm64/boot/dts/nvidia/tegra234.dtsi +12 -12
index 5b245977d6a037..345587fa1d9ad0 100644
@@ -5345,7 +5345,7 @@ cpus {
 		#size-cells = <0>;
 
 		cpu0_0: cpu@0 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x00000>;
 
@@ -5364,7 +5364,7 @@ cpu0_0: cpu@0 {
 		};
 
 		cpu0_1: cpu@100 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x00100>;
 
@@ -5383,7 +5383,7 @@ cpu0_1: cpu@100 {
 		};
 
 		cpu0_2: cpu@200 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x00200>;
 
@@ -5402,7 +5402,7 @@ cpu0_2: cpu@200 {
 		};
 
 		cpu0_3: cpu@300 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x00300>;
 
@@ -5421,7 +5421,7 @@ cpu0_3: cpu@300 {
 		};
 
 		cpu1_0: cpu@10000 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x10000>;
 
@@ -5440,7 +5440,7 @@ cpu1_0: cpu@10000 {
 		};
 
 		cpu1_1: cpu@10100 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x10100>;
 
@@ -5459,7 +5459,7 @@ cpu1_1: cpu@10100 {
 		};
 
 		cpu1_2: cpu@10200 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x10200>;
 
@@ -5478,7 +5478,7 @@ cpu1_2: cpu@10200 {
 		};
 
 		cpu1_3: cpu@10300 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x10300>;
 
@@ -5497,7 +5497,7 @@ cpu1_3: cpu@10300 {
 		};
 
 		cpu2_0: cpu@20000 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x20000>;
 
@@ -5516,7 +5516,7 @@ cpu2_0: cpu@20000 {
 		};
 
 		cpu2_1: cpu@20100 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x20100>;
 
@@ -5535,7 +5535,7 @@ cpu2_1: cpu@20100 {
 		};
 
 		cpu2_2: cpu@20200 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x20200>;
 
@@ -5554,7 +5554,7 @@ cpu2_2: cpu@20200 {
 		};
 
 		cpu2_3: cpu@20300 {
-			compatible = "arm,cortex-a78";
+			compatible = "arm,cortex-a78ae";
 			device_type = "cpu";
 			reg = <0x20300>;
 
Signature · 1 line
2.53.0
author maintainer
#33 lore raw

PATCH 33/675 net: dropreason: add SKB_DROP_REASON_RECURSION_LIMIT

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit d15d3de94a4766fb43d7fe7a72ed0479fb268131 ]

ip[6]tunnel_xmit() can drop packets if a too deep recursion level is detected.

Add SKB_DROP_REASON_RECURSION_LIMIT drop reason.

We will use this reason later in __dev_queue_xmit().

Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")

---
 include/net/dropreason-core.h | 3 +++
 include/net/ip6_tunnel.h      | 2 +-
 net/ipv4/ip_tunnel_core.c     | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)
include/net/dropreason-core.h +3 -0
index 58d91ccc56e0b5..de74e537b4ede4 100644
@@ -129,6 +129,7 @@
 	FN(DUALPI2_STEP_DROP)		\
 	FN(PSP_INPUT)			\
 	FN(PSP_OUTPUT)			\
+	FN(RECURSION_LIMIT)		\
 	FNe(MAX)
 
 /**
@@ -616,6 +617,8 @@ enum skb_drop_reason {
 	SKB_DROP_REASON_PSP_INPUT,
 	/** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
 	SKB_DROP_REASON_PSP_OUTPUT,
+	/** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */
+	SKB_DROP_REASON_RECURSION_LIMIT,
 	/**
 	 * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
 	 * shouldn't be used as a real 'reason' - only for tracing code gen
include/net/ip6_tunnel.h +1 -1
index 359b595f1df936..b99805ee2fd14b 100644
@@ -162,7 +162,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
 					     dev->name);
 			DEV_STATS_INC(dev, tx_errors);
 		}
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_RECURSION_LIMIT);
 		return;
 	}
 
net/ipv4/ip_tunnel_core.c +1 -1
index 4b5fd4b13722ca..fc993c78cbcc5e 100644
@@ -65,7 +65,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
 			DEV_STATS_INC(dev, tx_errors);
 		}
 		ip_rt_put(rt);
-		kfree_skb(skb);
+		kfree_skb_reason(skb, SKB_DROP_REASON_RECURSION_LIMIT);
 		return;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#34 lore raw

PATCH 34/675 net: plumb drop reasons to __dev_queue_xmit()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 045f977dd4ebdd3ad8e96cf684917adfc5805adb ]

Add drop reasons to __dev_queue_xmit():

- SKB_DROP_REASON_DEV_READY : device is not UP.

- SKB_DROP_REASON_RECURSION_LIMIT : recursion limit on virtual device is hit.

Also add an unlikely() for the SKB_DROP_REASON_DEV_READY case, and reduce indentation level.

Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")

---
 net/core/dev.c | 83 ++++++++++++++++++++++++++------------------------
 1 file changed, 43 insertions(+), 40 deletions(-)
net/core/dev.c +43 -40
index 8dee703a0916ed..246d654551ae56 100644
@@ -4702,9 +4702,10 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
 {
 	struct net_device *dev = skb->dev;
 	struct netdev_queue *txq = NULL;
-	struct Qdisc *q;
-	int rc = -ENOMEM;
+	enum skb_drop_reason reason;
+	int cpu, rc = -ENOMEM;
 	bool again = false;
+	struct Qdisc *q;
 
 	skb_reset_mac_header(skb);
 	skb_assert_len(skb);
@@ -4773,59 +4774,61 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
 	 * Check this and shot the lock. It is not prone from deadlocks.
 	 *Either shot noqueue qdisc, it is even simpler 8)
 	 */
-	if (dev->flags & IFF_UP) {
-		int cpu = smp_processor_id(); /* ok because BHs are off */
+	if (unlikely(!(dev->flags & IFF_UP))) {
+		reason = SKB_DROP_REASON_DEV_READY;
+		goto drop;
+	}
 
-		if (!netif_tx_owned(txq, cpu)) {
-			bool is_list = false;
+	cpu = smp_processor_id(); /* ok because BHs are off */
 
-			if (dev_xmit_recursion())
-				goto recursion_alert;
+	if (likely(!netif_tx_owned(txq, cpu))) {
+		bool is_list = false;
 
-			skb = validate_xmit_skb(skb, dev, &again);
-			if (!skb)
-				goto out;
+		if (dev_xmit_recursion())
+			goto recursion_alert;
 
-			HARD_TX_LOCK(dev, txq, cpu);
+		skb = validate_xmit_skb(skb, dev, &again);
+		if (!skb)
+			goto out;
 
-			if (!netif_xmit_stopped(txq)) {
-				is_list = !!skb->next;
+		HARD_TX_LOCK(dev, txq, cpu);
 
-				dev_xmit_recursion_inc();
-				skb = dev_hard_start_xmit(skb, dev, txq, &rc);
-				dev_xmit_recursion_dec();
+		if (!netif_xmit_stopped(txq)) {
+			is_list = !!skb->next;
 
-				/* GSO segments a single SKB into
-				 * a list of frames. TCP expects error
-				 * to mean none of the data was sent.
-				 */
-				if (is_list)
-					rc = NETDEV_TX_OK;
-			}
-			HARD_TX_UNLOCK(dev, txq);
-			if (!skb) /* xmit completed */
-				goto out;
+			dev_xmit_recursion_inc();
+			skb = dev_hard_start_xmit(skb, dev, txq, &rc);
+			dev_xmit_recursion_dec();
 
-			net_crit_ratelimited("Virtual device %s asks to queue packet!\n",
-					     dev->name);
-			/* NETDEV_TX_BUSY or queue was stopped */
-			if (!is_list)
-				rc = -ENETDOWN;
-		} else {
-			/* Recursion is detected! It is possible,
-			 * unfortunately
+			/* GSO segments a single SKB into a list of frames.
+			 * TCP expects error to mean none of the data was sent.
 			 */
-recursion_alert:
-			net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n",
-					     dev->name);
-			rc = -ENETDOWN;
+			if (is_list)
+				rc = NETDEV_TX_OK;
 		}
+		HARD_TX_UNLOCK(dev, txq);
+		if (!skb) /* xmit completed */
+			goto out;
+
+		net_crit_ratelimited("Virtual device %s asks to queue packet!\n",
+				     dev->name);
+		/* NETDEV_TX_BUSY or queue was stopped */
+		if (!is_list)
+			rc = -ENETDOWN;
+	} else {
+		/* Recursion is detected! It is possible unfortunately. */
+recursion_alert:
+		net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n",
+				     dev->name);
+		rc = -ENETDOWN;
 	}
 
+	reason = SKB_DROP_REASON_RECURSION_LIMIT;
+drop:
 	rcu_read_unlock_bh();
 
 	dev_core_stats_tx_dropped_inc(dev);
-	kfree_skb_list(skb);
+	kfree_skb_list_reason(skb, reason);
 	return rc;
 out:
 	rcu_read_unlock_bh();
Signature · 1 line
2.53.0
author maintainer
#35 lore raw

PATCH 35/675 xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Petr Wozniak <[email protected]>

[ Upstream commit 6860b467f569f732b11cbc588ae7e195e90e7e23 ]

validate_xmit_xfrm() returns NULL both when a packet is dropped and when it is stolen by async crypto (-EINPROGRESS from ->xmit()). Callers cannot distinguish the two cases.

f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.") changed the semantics of a NULL return from "dropped" to "stolen or dropped", but __dev_queue_xmit() was not updated. On virtual/bridge interfaces (noqueue qdisc) __dev_queue_xmit() initialises rc=-ENOMEM and jumps to out: when skb is NULL, returning -ENOMEM to the caller even though the packet will be delivered correctly via xfrm_dev_resume().

Return ERR_PTR(-EINPROGRESS) from validate_xmit_xfrm() for the async case so callers can tell it apart from a real drop. Update __dev_queue_xmit() to handle ERR_PTR(-EINPROGRESS) from validate_xmit_skb() correctly. Update validate_xmit_skb_list() to use IS_ERR_OR_NULL() so that ERR_PTR(-EINPROGRESS) is not mistakenly added to the transmitted list.

Fixes f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
---
 net/core/dev.c         | 10 ++++++++--
 net/xfrm/xfrm_device.c |  4 ++--
 2 files changed, 10 insertions(+), 4 deletions(-)
net/core/dev.c +8 -2
index 246d654551ae56..a83083e8761b1b 100644
@@ -4005,6 +4005,9 @@ static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb,
 	return NULL;
 }
 
+/* Returns the skb on success, NULL if dropped, or ERR_PTR(-EINPROGRESS)
+ * if stolen by async xfrm crypto (delivered via xfrm_dev_resume()).
+ */
 static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev, bool *again)
 {
 	netdev_features_t features;
@@ -4076,7 +4079,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d
 		skb->prev = skb;
 
 		skb = validate_xmit_skb(skb, dev, again);
-		if (!skb)
+		if (IS_ERR_OR_NULL(skb))
 			continue;
 
 		if (!head)
@@ -4788,8 +4791,11 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
 			goto recursion_alert;
 
 		skb = validate_xmit_skb(skb, dev, &again);
-		if (!skb)
+		if (IS_ERR_OR_NULL(skb)) {
+			if (PTR_ERR(skb) == -EINPROGRESS)
+				rc = NET_XMIT_SUCCESS;
 			goto out;
+		}
 
 		HARD_TX_LOCK(dev, txq, cpu);
 
net/xfrm/xfrm_device.c +2 -2
index 550457e4c4f01d..8b526e3676389a 100644
@@ -182,7 +182,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
 		err = x->type_offload->xmit(x, skb, esp_features);
 		if (err) {
 			if (err == -EINPROGRESS)
-				return NULL;
+				return ERR_PTR(-EINPROGRESS);
 
 			XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
 			kfree_skb(skb);
@@ -224,7 +224,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
 		pskb = skb2;
 	}
 
-	return skb;
+	return skb ? skb : ERR_PTR(-EINPROGRESS);
 }
 EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
 
Signature · 1 line
2.53.0
author maintainer
#36 lore raw

PATCH 36/675 xfrm: fix stale skb->prev after async crypto steals a GSO segment

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Petr Wozniak <[email protected]>

[ Upstream commit 3f4c3919baf0944ad96580467c302bc6c7758b00 ]

skb_gso_segment() leaves the segment list head with ->prev pointing at the last segment, an invariant validate_xmit_skb_list() relies on when it sets its tail pointer (tail = skb->prev).

When validate_xmit_xfrm() walks a GSO list and some segments are stolen by async crypto (->xmit() returns -EINPROGRESS), those segments are unlinked from the list but the head ->prev is never updated. If the last segment is the one stolen, the returned head still has ->prev pointing at it, even though it is now owned by the crypto engine and may be freed. validate_xmit_skb_list() later does tail->next = skb, writing through that stale pointer -- a use-after-free.

Repoint skb->prev at the last retained segment before returning.

Fixes f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.")
---
 net/xfrm/xfrm_device.c | 8 ++++++++
 1 file changed, 8 insertions(+)
net/xfrm/xfrm_device.c +8 -0
index 8b526e3676389a..4719aba331cd66 100644
@@ -224,6 +224,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
 		pskb = skb2;
 	}
 
+	/* skb_gso_segment() set skb->prev to the last segment, but async
+	 * crypto may have stolen it above without updating ->prev.  Repoint
+	 * it at the last retained segment so validate_xmit_skb_list() does
+	 * not chain onto a segment now owned by the crypto engine.
+	 */
+	if (skb)
+		skb->prev = pskb;
+
 	return skb ? skb : ERR_PTR(-EINPROGRESS);
 }
 EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
Signature · 1 line
2.53.0
author maintainer
#37 lore raw

PATCH 37/675 firmware: arm_ffa: Respect firmware advertised RX/TX buffer size limits

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Seth Forshee <[email protected]>

[ Upstream commit 53716a4d745f1dac7aff33f3d1494b701eb2f888 ]

FFA_FEATURES reports the minimum size and alignment boundary required for RXTX_MAP. In FF-A v1.2 and later it can also report a maximum buffer size, with zero meaning that no maximum is enforced.

The driver only used the minimum value and then rounded it up to PAGE_SIZE before invoking RXTX_MAP after commit 83210251fd70 ("firmware: arm_ffa:
Use the correct buffer size during RXTX_MAP"). On systems where PAGE_SIZE is larger than the advertised minimum, this can exceed a non-zero maximum reported by firmware. Older implementations do not advertise a maximum and may also reject the rounded-up size.

Decode the maximum size and clamp the page-aligned minimum to it when it is present. If no maximum is advertised and RXTX_MAP rejects the rounded size with INVALID_PARAMETERS, retry with the advertised minimum size. Record drv_info->rxtx_bufsz only after RXTX_MAP succeeds so it reflects the size registered with firmware.

While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for consistency.

Fixes 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")

(sudeep.holla: Minor rewording subject and commit message)

---
 drivers/firmware/arm_ffa/driver.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)
drivers/firmware/arm_ffa/driver.c +20 -7
index 3fbc75caf0c506..c76eabb8436a85 100644
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
@@ -55,7 +56,9 @@
 	(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
 
 #define RXTX_MAP_MIN_BUFSZ_MASK	GENMASK(1, 0)
-#define RXTX_MAP_MIN_BUFSZ(x)	((x) & RXTX_MAP_MIN_BUFSZ_MASK)
+#define RXTX_MAP_MAX_BUFSZ_MASK	GENMASK(31, 16)
+#define RXTX_MAP_MIN_BUFSZ(x)	(FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
+#define RXTX_MAP_MAX_BUFSZ(x)	(FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
 
 #define FFA_MAX_NOTIFICATIONS		64
 
@@ -2088,7 +2091,7 @@ static int __init ffa_init(void)
 {
 	int ret;
 	u32 buf_sz;
-	size_t rxtx_bufsz = SZ_4K;
+	size_t rxtx_min_bufsz = SZ_4K, rxtx_max_bufsz = 0, rxtx_bufsz;
 
 	ret = ffa_transport_init(&invoke_ffa_fn);
 	if (ret)
@@ -2111,15 +2114,18 @@ static int __init ffa_init(void)
 	ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
 	if (!ret) {
 		if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
-			rxtx_bufsz = SZ_64K;
+			rxtx_min_bufsz = SZ_64K;
 		else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
-			rxtx_bufsz = SZ_16K;
+			rxtx_min_bufsz = SZ_16K;
 		else
-			rxtx_bufsz = SZ_4K;
+			rxtx_min_bufsz = SZ_4K;
+
+		rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
+		if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
+			rxtx_max_bufsz = rxtx_min_bufsz;
 	}
 
-	rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
-	drv_info->rxtx_bufsz = rxtx_bufsz;
+	rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
 	drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
 	if (!drv_info->rx_buffer) {
 		ret = -ENOMEM;
@@ -2135,10 +2141,17 @@ static int __init ffa_init(void)
 	ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
 			   virt_to_phys(drv_info->rx_buffer),
 			   rxtx_bufsz / FFA_PAGE_SIZE);
+	if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
+		rxtx_bufsz = rxtx_min_bufsz;
+		ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+				   virt_to_phys(drv_info->rx_buffer),
+				   rxtx_bufsz / FFA_PAGE_SIZE);
+	}
 	if (ret) {
 		pr_err("failed to register FFA RxTx buffers\n");
 		goto free_pages;
 	}
+	drv_info->rxtx_bufsz = rxtx_bufsz;
 
 	mutex_init(&drv_info->rx_lock);
 	mutex_init(&drv_info->tx_lock);
Signature · 1 line
2.53.0
author maintainer
#38 lore raw

PATCH 38/675 IB/mad: Drop unmatched RMPP responses before reassembly

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Bommarito <[email protected]>

[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]

Kernel-handled RMPP receive processing starts reassembly for active DATA responses before the response is matched to an outstanding send. The normal match happens later, after ib_process_rmpp_recv_wc() has either assembled a complete message or consumed the segment.

That ordering lets an unsolicited response that routes to a kernel RMPP agent by the high TID bits allocate or extend RMPP receive state before the full TID and source address are checked against a real request. A reordered burst can therefore reach the receive-side insertion path even though the response would not match any send.

For kernel-handled RMPP DATA responses, require the existing ib_find_send_mad() match before entering RMPP reassembly. The matcher already checks the full TID, management class and source address/GID against the agent wait, backlog and in-flight send lists. If there is no match, drop the response without creating RMPP state.

This leaves the RMPP window behavior unchanged and only rejects responses that have no corresponding request.

---
 drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
drivers/infiniband/core/mad.c +30 -0
index 8f26bfb695861f..5150cd53d4435a 100644
@@ -2031,6 +2031,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
 		change_mad_state(mad_send_wr, IB_MAD_STATE_EARLY_RESP);
 }
 
+static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
+					 struct ib_mad_recv_wc *mad_recv_wc)
+{
+	const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
+	struct ib_rmpp_mad *rmpp_mad;
+
+	if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
+	    !ib_response_mad(mad_hdr) ||
+	    !ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
+		return false;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
+
+	return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+		IB_MGMT_RMPP_FLAG_ACTIVE) &&
+	       rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
+}
+
 static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 				 struct ib_mad_recv_wc *mad_recv_wc)
 {
@@ -2050,6 +2068,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 	}
 
 	list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
+	if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
+		spin_lock_irqsave(&mad_agent_priv->lock, flags);
+		mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
+		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+
+		if (!mad_send_wr) {
+			ib_free_recv_mad(mad_recv_wc);
+			deref_mad_agent(mad_agent_priv);
+			return;
+		}
+	}
+
 	if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
 		mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
 						      mad_recv_wc);
Signature · 1 line
2.53.0
author maintainer
#39 lore raw

PATCH 39/675 mtd: mtdswap: remove debugfs stats file on teardown

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <[email protected]>

[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]

mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the per-MTD debugfs directory, but mtdswap_remove_dev() never removes it before freeing the mtdswap_dev.

Store the returned dentry and remove it during device teardown before the driver-private state is freed.

Fixes a32159024620 ("mtd: Add mtdswap block driver")
---
 drivers/mtd/mtdswap.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/mtdswap.c +4 -1
index d8f2e5be2d315e..42ff7deace80c5 100644
@@ -125,6 +125,7 @@ struct mtdswap_dev {
 
 	char *page_buf;
 	char *oob_buf;
+	struct dentry *debugfs_stats;
 };
 
 struct mtdswap_oobdata {
@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)
 	if (IS_ERR_OR_NULL(root))
 		return -1;
 
-	debugfs_create_file("mtdswap_stats", S_IRUSR, root, d, &mtdswap_fops);
+	d->debugfs_stats = debugfs_create_file("mtdswap_stats", 0400, root,
+					       d, &mtdswap_fops);
 
 	return 0;
 }
@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev)
 {
 	struct mtdswap_dev *d = MTDSWAP_MBD_TO_MTDSWAP(dev);
 
+	debugfs_remove(d->debugfs_stats);
 	del_mtd_blktrans_dev(dev);
 	mtdswap_cleanup(d);
 	kfree(d);
Signature · 1 line
2.53.0
author maintainer
#40 lore raw

PATCH 40/675 mtd: nand: mtk-ecc: stop on ECC idle timeouts

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <[email protected]>

[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]

mtk_ecc_wait_idle() logs when the encoder or decoder does not become idle, but returns void. Callers can therefore configure a non-idle ECC engine or read parity bytes after an unconfirmed encoder idle state.

Return the idle poll result and propagate it from the enable and encode paths that require the engine to be idle before continuing.

Fixes 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
---
 drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/mtd/nand/ecc-mtk.c +12 -4
index c75bb8b80cc1e1..96703f0a418ea2 100644
@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = {
 	[ECC_DECIRQ_STA] =      0x144,
 };
 
-static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
-				     enum mtk_ecc_operation op)
+static inline int mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+				    enum mtk_ecc_operation op)
 {
 	struct device *dev = ecc->dev;
 	u32 val;
@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
 	if (ret)
 		dev_warn(dev, "%s NOT idle\n",
 			 op == ECC_ENCODE ? "encoder" : "decoder");
+
+	return ret;
 }
 
 static irqreturn_t mtk_ecc_irq(int irq, void *id)
@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
 		return ret;
 	}
 
-	mtk_ecc_wait_idle(ecc, op);
+	ret = mtk_ecc_wait_idle(ecc, op);
+	if (ret) {
+		mutex_unlock(&ecc->lock);
+		return ret;
+	}
 
 	ret = mtk_ecc_config(ecc, config);
 	if (ret) {
@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
 	if (ret)
 		goto timeout;
 
-	mtk_ecc_wait_idle(ecc, ECC_ENCODE);
+	ret = mtk_ecc_wait_idle(ecc, ECC_ENCODE);
+	if (ret)
+		goto timeout;
 
 	/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
 	len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
Signature · 1 line
2.53.0
author maintainer
#41 lore raw

PATCH 41/675 btrfs: reject free space cache with more entries than pages

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei <[email protected]>

[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]

When loading a v1 free space cache, __load_free_space_cache() takes num_entries and num_bitmaps straight from the on-disk btrfs_free_space_header. That header is stored in the tree_root under a key with type 0, which the tree-checker has no case for, so neither count is validated before the load trusts it.

The load loops num_entries times and maps the next page whenever the current one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in io_ctl_init() from the cache inode's i_size, not from num_entries:

	num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
	io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);

So if num_entries claims more records than the pages can hold, io_ctl->index runs off the end of pages[]. The write side never hits this because io_ctl_add_entry() and io_ctl_add_bitmap() both stop once io_ctl->index >= io_ctl->num_pages; the read side just never had the same check.

To trigger it, take a clean cache (num_entries = <N> here), set num_entries in the header to 0x10000, and fix up the leaf checksum so it still passes the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read 65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the array:

  BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
  Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
   io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
   __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
   load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
   caching_thread (fs/btrfs/block-group.c:880)
   btrfs_work_helper (fs/btrfs/async-thread.c:312)
   process_one_work
   worker_thread
   kthread
   ret_from_fork

free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc() at line 565, which is why that is the frame KASAN names. The out-of-bounds slot is then treated as a struct page and handed to crc32c(), so the bad read turns into a GP fault.

Add the missing check to io_ctl_check_crc(), which is where both the entry loop and the bitmap loop end up. When num_entries is too large the load now fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds the free space from the extent tree, so a valid cache is never rejected.

---
 fs/btrfs/free-space-cache.c | 3 +++
 1 file changed, 3 insertions(+)
fs/btrfs/free-space-cache.c +3 -0
index ab873bd6719209..9828da12765f5c 100644
@@ -554,6 +554,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)
 	u32 crc = ~(u32)0;
 	unsigned offset = 0;
 
+	if (index >= io_ctl->num_pages)
+		return -EIO;
+
 	if (index == 0)
 		offset = sizeof(u32) * io_ctl->num_pages;
 
Signature · 1 line
2.53.0
author maintainer
#42 lore raw

PATCH 42/675 btrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Filipe Manana <[email protected]>

[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]

If we have an unexpected reloc_root for our root, we jump to the out label but never drop the reference we obtained for root, resulting in a leak. Add a missing btrfs_put_root() call.

Fixes 24213fa46c70 ("btrfs: do proper error handling in merge_reloc_roots")
---
 fs/btrfs/relocation.c | 1 +
 1 file changed, 1 insertion(+)
fs/btrfs/relocation.c +1 -0
index fc76013b1a3e01..ea68328d289cba 100644
@@ -1857,6 +1857,7 @@ void merge_reloc_roots(struct reloc_control *rc)
 				 * corruption, e.g. bad reloc tree key offset.
 				 */
 				ret = -EINVAL;
+				btrfs_put_root(root);
 				goto out;
 			}
 			ret = merge_reloc_root(rc, root);
Signature · 1 line
2.53.0
author maintainer
#43 lore raw

PATCH 43/675 btrfs: use bool type for btrfs_path members used as booleans

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Filipe Manana <[email protected]>

[ Upstream commit d7fe41044b3ac8f9b5965de499a13ac9ae947e79 ]

Many fields of struct btrfs_path are used as booleans but their type is an unsigned int (of one 1 bit width to save space). Change the type to bool keeping the :1 suffix so that they combine with the previous u8 fields in order to save space. This makes the code more clear by using explicit true/false and more in line with the preferred style, preserving the size of the structure.

Stable-dep-of: 3dcd50730814 ("btrfs: fallback to transaction csum tree on a commit root csum miss")

---
 fs/btrfs/backref.c          | 16 ++++++++--------
 fs/btrfs/block-group.c      |  8 ++++----
 fs/btrfs/ctree.c            | 28 ++++++++++++++--------------
 fs/btrfs/ctree.h            | 16 ++++++++--------
 fs/btrfs/defrag.c           |  4 ++--
 fs/btrfs/dev-replace.c      |  4 ++--
 fs/btrfs/extent-tree.c      |  8 ++++----
 fs/btrfs/file-item.c        | 12 ++++++------
 fs/btrfs/free-space-cache.c |  4 ++--
 fs/btrfs/free-space-tree.c  |  4 ++--
 fs/btrfs/inode-item.c       |  2 +-
 fs/btrfs/inode.c            |  4 ++--
 fs/btrfs/qgroup.c           |  4 ++--
 fs/btrfs/raid-stripe-tree.c |  4 ++--
 fs/btrfs/relocation.c       |  8 ++++----
 fs/btrfs/scrub.c            | 20 ++++++++++----------
 fs/btrfs/send.c             | 14 +++++++-------
 fs/btrfs/tree-log.c         | 20 ++++++++++----------
 fs/btrfs/volumes.c          |  6 +++---
 fs/btrfs/xattr.c            |  2 +-
 20 files changed, 94 insertions(+), 94 deletions(-)
fs/btrfs/backref.c +8 -8
index e050d0938dc45f..0c47b4570a7bf8 100644
@@ -1408,12 +1408,12 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,
 	if (!path)
 		return -ENOMEM;
 	if (!ctx->trans) {
-		path->search_commit_root = 1;
-		path->skip_locking = 1;
+		path->search_commit_root = true;
+		path->skip_locking = true;
 	}
 
 	if (ctx->time_seq == BTRFS_SEQ_LAST)
-		path->skip_locking = 1;
+		path->skip_locking = true;
 
 again:
 	head = NULL;
@@ -1560,7 +1560,7 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,
 
 	btrfs_release_path(path);
 
-	ret = add_missing_keys(ctx->fs_info, &preftrees, path->skip_locking == 0);
+	ret = add_missing_keys(ctx->fs_info, &preftrees, !path->skip_locking);
 	if (ret)
 		goto out;
 
@@ -2833,8 +2833,8 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_inf
 	}
 
 	/* Current backref iterator only supports iteration in commit root */
-	ret->path->search_commit_root = 1;
-	ret->path->skip_locking = 1;
+	ret->path->search_commit_root = true;
+	ret->path->skip_locking = true;
 	ret->fs_info = fs_info;
 
 	return ret;
@@ -3307,8 +3307,8 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
 	level = cur->level + 1;
 
 	/* Search the tree to find parent blocks referring to the block */
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 	path->lowest_level = level;
 	ret = btrfs_search_slot(NULL, root, tree_key, path, 0, 0);
 	path->lowest_level = 0;
fs/btrfs/block-group.c +4 -4
index 1e57f7d04c47ec..e6bac34ebe83d6 100644
@@ -613,8 +613,8 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_
 	extent_root = btrfs_extent_root(fs_info, max_t(u64, block_group->start,
 						       BTRFS_SUPER_INFO_OFFSET));
 
-	path->skip_locking = 1;
-	path->search_commit_root = 1;
+	path->skip_locking = true;
+	path->search_commit_root = true;
 	path->reada = READA_FORWARD;
 
 	search_offset = index * div_u64(block_group->length, max_index);
@@ -744,8 +744,8 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
 	 * root to add free space.  So we skip locking and search the commit
 	 * root, since its read-only
 	 */
-	path->skip_locking = 1;
-	path->search_commit_root = 1;
+	path->skip_locking = true;
+	path->search_commit_root = true;
 	path->reada = READA_FORWARD;
 
 	key.objectid = last;
fs/btrfs/ctree.c +14 -14
index 27e2adc2ee717b..0f2e9f33dd0cbc 100644
@@ -1709,9 +1709,9 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root,
 		level = btrfs_header_level(b);
 		/*
 		 * Ensure that all callers have set skip_locking when
-		 * p->search_commit_root = 1.
+		 * p->search_commit_root is true.
 		 */
-		ASSERT(p->skip_locking == 1);
+		ASSERT(p->skip_locking);
 
 		goto out;
 	}
@@ -3858,10 +3858,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
 	}
 	btrfs_release_path(path);
 
-	path->keep_locks = 1;
-	path->search_for_split = 1;
+	path->keep_locks = true;
+	path->search_for_split = true;
 	ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
-	path->search_for_split = 0;
+	path->search_for_split = false;
 	if (ret > 0)
 		ret = -EAGAIN;
 	if (ret < 0)
@@ -3888,11 +3888,11 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
 	if (ret)
 		goto err;
 
-	path->keep_locks = 0;
+	path->keep_locks = false;
 	btrfs_unlock_up_safe(path, 1);
 	return 0;
 err:
-	path->keep_locks = 0;
+	path->keep_locks = false;
 	return ret;
 }
 
@@ -4610,11 +4610,11 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
 	u32 nritems;
 	int level;
 	int ret = 1;
-	int keep_locks = path->keep_locks;
+	const bool keep_locks = path->keep_locks;
 
 	ASSERT(!path->nowait);
 	ASSERT(path->lowest_level == 0);
-	path->keep_locks = 1;
+	path->keep_locks = true;
 again:
 	cur = btrfs_read_lock_root_node(root);
 	level = btrfs_header_level(cur);
@@ -4704,7 +4704,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,
  * 0 is returned if another key is found, < 0 if there are any errors
  * and 1 is returned if there are no higher keys in the tree
  *
- * path->keep_locks should be set to 1 on the search made before
+ * path->keep_locks should be set to true on the search made before
  * calling this function.
  */
 int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
@@ -4803,13 +4803,13 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
 	next = NULL;
 	btrfs_release_path(path);
 
-	path->keep_locks = 1;
+	path->keep_locks = true;
 
 	if (time_seq) {
 		ret = btrfs_search_old_slot(root, &key, path, time_seq);
 	} else {
 		if (path->need_commit_sem) {
-			path->need_commit_sem = 0;
+			path->need_commit_sem = false;
 			need_commit_sem = true;
 			if (path->nowait) {
 				if (!down_read_trylock(&fs_info->commit_root_sem)) {
@@ -4822,7 +4822,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
 		}
 		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	}
-	path->keep_locks = 0;
+	path->keep_locks = false;
 
 	if (ret < 0)
 		goto done;
@@ -4961,7 +4961,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
 	if (need_commit_sem) {
 		int ret2;
 
-		path->need_commit_sem = 1;
+		path->need_commit_sem = true;
 		ret2 = finish_need_commit_sem_search(path);
 		up_read(&fs_info->commit_root_sem);
 		if (ret2)
fs/btrfs/ctree.h +8 -8
index 16dd11c4853130..692370fc07b280 100644
@@ -65,21 +65,21 @@ struct btrfs_path {
 	 * set by btrfs_split_item, tells search_slot to keep all locks
 	 * and to force calls to keep space in the nodes
 	 */
-	unsigned int search_for_split:1;
+	bool search_for_split:1;
 	/* Keep some upper locks as we walk down. */
-	unsigned int keep_locks:1;
-	unsigned int skip_locking:1;
-	unsigned int search_commit_root:1;
-	unsigned int need_commit_sem:1;
-	unsigned int skip_release_on_error:1;
+	bool keep_locks:1;
+	bool skip_locking:1;
+	bool search_commit_root:1;
+	bool need_commit_sem:1;
+	bool skip_release_on_error:1;
 	/*
 	 * Indicate that new item (btrfs_search_slot) is extending already
 	 * existing item and ins_len contains only the data size and not item
 	 * header (ie. sizeof(struct btrfs_item) is not included).
 	 */
-	unsigned int search_for_extension:1;
+	bool search_for_extension:1;
 	/* Stop search if any locks need to be taken (for read) */
-	unsigned int nowait:1;
+	bool nowait:1;
 };
 
 #define BTRFS_PATH_AUTO_FREE(path_name)					\
fs/btrfs/defrag.c +2 -2
index a4cc1bc6356227..2e3c011d410a6f 100644
@@ -472,7 +472,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
 		memcpy(&key, &root->defrag_progress, sizeof(key));
 	}
 
-	path->keep_locks = 1;
+	path->keep_locks = true;
 
 	ret = btrfs_search_forward(root, &key, path, BTRFS_OLDEST_GENERATION);
 	if (ret < 0)
@@ -515,7 +515,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
 	/*
 	 * Now that we reallocated the node we can find the next key. Note that
 	 * btrfs_find_next_key() can release our path and do another search
-	 * without COWing, this is because even with path->keep_locks = 1,
+	 * without COWing, this is because even with path->keep_locks == true,
 	 * btrfs_search_slot() / ctree.c:unlock_up() does not keeps a lock on a
 	 * node when path->slots[node_level - 1] does not point to the last
 	 * item or a slot beyond the last item (ctree.c:unlock_up()). Therefore
fs/btrfs/dev-replace.c +2 -2
index a4eaef60549eed..b6c7da8e1bc8b1 100644
@@ -489,8 +489,8 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
 	}
 
 	path->reada = READA_FORWARD;
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	key.objectid = src_dev->devid;
 	key.type = BTRFS_DEV_EXTENT_KEY;
fs/btrfs/extent-tree.c +4 -4
index 6ef7cc116bfcca..d2d96f366dac31 100644
@@ -788,7 +788,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
 	want = extent_ref_type(parent, owner);
 	if (insert) {
 		extra_size = btrfs_extent_inline_ref_size(want);
-		path->search_for_extension = 1;
+		path->search_for_extension = true;
 	} else
 		extra_size = -1;
 
@@ -954,7 +954,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
 
 		if (!path->keep_locks) {
 			btrfs_release_path(path);
-			path->keep_locks = 1;
+			path->keep_locks = true;
 			goto again;
 		}
 
@@ -975,11 +975,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
 	*ref_ret = (struct btrfs_extent_inline_ref *)ptr;
 out:
 	if (path->keep_locks) {
-		path->keep_locks = 0;
+		path->keep_locks = false;
 		btrfs_unlock_up_safe(path, 1);
 	}
 	if (insert)
-		path->search_for_extension = 0;
+		path->search_for_extension = false;
 	return ret;
 }
 
fs/btrfs/file-item.c +6 -6
index 4b7c40f05e8f9e..a2f851eaadca06 100644
@@ -394,8 +394,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 	 * between reading the free space cache and updating the csum tree.
 	 */
 	if (btrfs_is_free_space_inode(inode)) {
-		path->search_commit_root = 1;
-		path->skip_locking = 1;
+		path->search_commit_root = true;
+		path->skip_locking = true;
 	}
 
 	/*
@@ -423,8 +423,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 	 * from across transactions.
 	 */
 	if (bbio->csum_search_commit_root) {
-		path->search_commit_root = 1;
-		path->skip_locking = 1;
+		path->search_commit_root = true;
+		path->skip_locking = true;
 		down_read(&fs_info->commit_root_sem);
 	}
 
@@ -1168,10 +1168,10 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
 	}
 
 	btrfs_release_path(path);
-	path->search_for_extension = 1;
+	path->search_for_extension = true;
 	ret = btrfs_search_slot(trans, root, &file_key, path,
 				csum_size, 1);
-	path->search_for_extension = 0;
+	path->search_for_extension = false;
 	if (ret < 0)
 		goto out;
 
fs/btrfs/free-space-cache.c +2 -2
index 9828da12765f5c..7ee3d8f05c1a21 100644
@@ -971,8 +971,8 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
 	path = btrfs_alloc_path();
 	if (!path)
 		return 0;
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	/*
 	 * We must pass a path with search_commit_root set to btrfs_iget in
fs/btrfs/free-space-tree.c +2 -2
index c3734892d6548b..f9ffb1c8988d90 100644
@@ -1699,8 +1699,8 @@ int btrfs_load_free_space_tree(struct btrfs_caching_control *caching_ctl)
 	 * Just like caching_thread() doesn't want to deadlock on the extent
 	 * tree, we don't want to deadlock on the free space tree.
 	 */
-	path->skip_locking = 1;
-	path->search_commit_root = 1;
+	path->skip_locking = true;
+	path->search_commit_root = true;
 	path->reada = READA_FORWARD;
 
 	info = btrfs_search_free_space_info(NULL, block_group, path, 0);
fs/btrfs/inode-item.c +1 -1
index 7e14e1bbcf389b..b73e1dd97208a8 100644
@@ -312,7 +312,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
 	if (!path)
 		return -ENOMEM;
 
-	path->skip_release_on_error = 1;
+	path->skip_release_on_error = true;
 	ret = btrfs_insert_empty_item(trans, root, path, &key,
 				      ins_len);
 	if (ret == -EEXIST) {
fs/btrfs/inode.c +2 -2
index 30a34cd905ba48..36f75c6a8344d4 100644
@@ -7170,8 +7170,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
 	 * point the commit_root has everything we need.
 	 */
 	if (btrfs_is_free_space_inode(inode)) {
-		path->search_commit_root = 1;
-		path->skip_locking = 1;
+		path->search_commit_root = true;
+		path->skip_locking = true;
 	}
 
 	ret = btrfs_lookup_file_extent(NULL, root, path, objectid, start, 0);
fs/btrfs/qgroup.c +2 -2
index 261aa65019207f..b4c6cbbcd168e6 100644
@@ -3882,8 +3882,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
 	 * Rescan should only search for commit root, and any later difference
 	 * should be recorded by qgroup
 	 */
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	while (!ret && !(stopped = rescan_should_stop(fs_info))) {
 		trans = btrfs_start_transaction(fs_info->fs_root, 0);
fs/btrfs/raid-stripe-tree.c +2 -2
index cc6f6095cc9fd0..f6f02463dd1a9b 100644
@@ -394,8 +394,8 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
 		return -ENOMEM;
 
 	if (stripe->rst_search_commit_root) {
-		path->skip_locking = 1;
-		path->search_commit_root = 1;
+		path->skip_locking = true;
+		path->search_commit_root = true;
 	}
 
 	ret = btrfs_search_slot(NULL, stripe_root, &stripe_key, path, 0, 0);
fs/btrfs/relocation.c +4 -4
index ea68328d289cba..86430435d3acc7 100644
@@ -3176,8 +3176,8 @@ static int __add_tree_block(struct reloc_control *rc,
 		key.offset = blocksize;
 	}
 
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 	ret = btrfs_search_slot(NULL, rc->extent_root, &key, path, 0, 0);
 	if (ret < 0)
 		return ret;
@@ -3369,8 +3369,8 @@ int find_next_extent(struct reloc_control *rc, struct btrfs_path *path,
 		key.type = BTRFS_EXTENT_ITEM_KEY;
 		key.offset = 0;
 
-		path->search_commit_root = 1;
-		path->skip_locking = 1;
+		path->search_commit_root = true;
+		path->skip_locking = true;
 		ret = btrfs_search_slot(NULL, rc->extent_root, &key, path,
 					0, 0);
 		if (ret < 0)
fs/btrfs/scrub.c +10 -10
index 16936d17166eef..368f1d44449351 100644
@@ -463,10 +463,10 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx(
 	refcount_set(&sctx->refs, 1);
 	sctx->is_dev_replace = is_dev_replace;
 	sctx->fs_info = fs_info;
-	sctx->extent_path.search_commit_root = 1;
-	sctx->extent_path.skip_locking = 1;
-	sctx->csum_path.search_commit_root = 1;
-	sctx->csum_path.skip_locking = 1;
+	sctx->extent_path.search_commit_root = true;
+	sctx->extent_path.skip_locking = true;
+	sctx->csum_path.search_commit_root = true;
+	sctx->csum_path.skip_locking = true;
 	for (i = 0; i < SCRUB_TOTAL_STRIPES; i++) {
 		int ret;
 
@@ -2103,10 +2103,10 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
 	 * as the data stripe bytenr may be smaller than previous extent.  Thus
 	 * we have to use our own extent/csum paths.
 	 */
-	extent_path.search_commit_root = 1;
-	extent_path.skip_locking = 1;
-	csum_path.search_commit_root = 1;
-	csum_path.skip_locking = 1;
+	extent_path.search_commit_root = true;
+	extent_path.skip_locking = true;
+	csum_path.search_commit_root = true;
+	csum_path.skip_locking = true;
 
 	for (int i = 0; i < data_stripes; i++) {
 		int stripe_index;
@@ -2630,8 +2630,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
 		return -ENOMEM;
 
 	path->reada = READA_FORWARD;
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	key.objectid = scrub_dev->devid;
 	key.type = BTRFS_DEV_EXTENT_KEY;
fs/btrfs/send.c +7 -7
index 04473387ee8bf0..34a57f11e4bb9c 100644
@@ -633,9 +633,9 @@ static struct btrfs_path *alloc_path_for_send(void)
 	path = btrfs_alloc_path();
 	if (!path)
 		return NULL;
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
-	path->need_commit_sem = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
+	path->need_commit_sem = true;
 	return path;
 }
 
@@ -7643,10 +7643,10 @@ static int btrfs_compare_trees(struct btrfs_root *left_root,
 		goto out;
 	}
 
-	left_path->search_commit_root = 1;
-	left_path->skip_locking = 1;
-	right_path->search_commit_root = 1;
-	right_path->skip_locking = 1;
+	left_path->search_commit_root = true;
+	left_path->skip_locking = true;
+	right_path->search_commit_root = true;
+	right_path->skip_locking = true;
 
 	/*
 	 * Strategy: Go to the first items of both trees. Then do
fs/btrfs/tree-log.c +10 -10
index a0e12b4fb95614..f84065b69464c7 100644
@@ -602,9 +602,9 @@ static int overwrite_item(struct walk_control *wc)
 insert:
 	btrfs_release_path(wc->subvol_path);
 	/* try to insert the key into the destination tree */
-	wc->subvol_path->skip_release_on_error = 1;
+	wc->subvol_path->skip_release_on_error = true;
 	ret = btrfs_insert_empty_item(trans, root, wc->subvol_path, &wc->log_key, item_size);
-	wc->subvol_path->skip_release_on_error = 0;
+	wc->subvol_path->skip_release_on_error = false;
 
 	dst_eb = wc->subvol_path->nodes[0];
 	dst_slot = wc->subvol_path->slots[0];
@@ -5734,8 +5734,8 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
 	search_path = btrfs_alloc_path();
 	if (!search_path)
 		return -ENOMEM;
-	search_path->search_commit_root = 1;
-	search_path->skip_locking = 1;
+	search_path->search_commit_root = true;
+	search_path->skip_locking = true;
 
 	while (cur_offset < item_size) {
 		u64 parent;
@@ -6052,8 +6052,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (WARN_ON_ONCE(ret > 0)) {
@@ -6073,8 +6073,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino,
 	}
 
 	btrfs_release_path(path);
-	path->search_commit_root = 0;
-	path->skip_locking = 0;
+	path->search_commit_root = false;
+	path->skip_locking = false;
 
 	return ret;
 }
@@ -7232,8 +7232,8 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
-	path->skip_locking = 1;
-	path->search_commit_root = 1;
+	path->skip_locking = true;
+	path->search_commit_root = true;
 
 	key.objectid = ino;
 	key.type = BTRFS_INODE_REF_KEY;
fs/btrfs/volumes.c +3 -3
index 630fb5885692b1..863f69b9cf14bd 100644
@@ -1839,8 +1839,8 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
 	}
 
 	path->reada = READA_FORWARD;
-	path->search_commit_root = 1;
-	path->skip_locking = 1;
+	path->search_commit_root = true;
+	path->skip_locking = true;
 
 	key.objectid = device->devid;
 	key.type = BTRFS_DEV_EXTENT_KEY;
@@ -7627,7 +7627,7 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
 	 * chunk tree, to keep it simple, just skip locking on the chunk tree.
 	 */
 	ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
-	path->skip_locking = 1;
+	path->skip_locking = true;
 
 	/*
 	 * Read all device items, and then all the chunk items. All
fs/btrfs/xattr.c +1 -1
index b6f01d6c79e7f3..b6e91e8fb7e388 100644
@@ -97,7 +97,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
-	path->skip_release_on_error = 1;
+	path->skip_release_on_error = true;
 
 	if (!value) {
 		di = btrfs_lookup_xattr(trans, root, path,
Signature · 1 line
2.53.0
author maintainer
#44 lore raw

PATCH 44/675 btrfs: fallback to transaction csum tree on a commit root csum miss

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Boris Burkov <[email protected]>

[ Upstream commit 3dcd50730814e5220072d2b26d0587af6bfb6dbe ]

We have been running with commit root csums enabled for some time and have noticed a slight uptick in zero csum errors. Investigating those revealed that they were same transaction reads of extents that were just relocated, but the extent map generation was long ago.

It turns out that relocation intentionally does not update the extent generation (replace_file_extents()), but must write a new csum since the data has moved, so we must account for this with commit root csum reading.

Luckily this is a short lived condition: after the relocation transaction the commit root will once again have the csum. So we can add a generic fallback to the lookup to try again with the transaction csum root.

Fixes f07b855c56b1 ("btrfs: try to search for data csums in commit root")
---
 fs/btrfs/file-item.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)
fs/btrfs/file-item.c +25 -1
index a2f851eaadca06..9b19b33e85b687 100644
@@ -350,6 +350,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 	const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;
 	int ret = 0;
 	u32 bio_offset = 0;
+	bool using_commit_root = false;
 
 	if ((inode->flags & BTRFS_INODE_NODATASUM) ||
 	    test_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state))
@@ -423,6 +424,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 	 * from across transactions.
 	 */
 	if (bbio->csum_search_commit_root) {
+		using_commit_root = true;
 		path->search_commit_root = true;
 		path->skip_locking = true;
 		down_read(&fs_info->commit_root_sem);
@@ -455,6 +457,28 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 		 * assume this is the case.
 		 */
 		if (count == 0) {
+			/*
+			 * If an extent is relocated in the current transaction
+			 * then relocation writes a new csum without updating
+			 * the extent map generation. Until the next commit, we
+			 * will see a hole in that case, so we need to fallback
+			 * to searching the transaction csum root.
+			 *
+			 * Note that a commit root lookup of a referenced extent can
+			 * only miss, not return a stale csum. A freed extent's csum
+			 * is deleted in the same transaction and its bytenr is not
+			 * reusable until that transaction has committed and the
+			 * extent is unpinned.
+			 */
+			if (using_commit_root) {
+				up_read(&fs_info->commit_root_sem);
+				using_commit_root = false;
+				path->search_commit_root = false;
+				path->skip_locking = false;
+				btrfs_release_path(path);
+				continue;
+			}
+
 			memset(csum_dst, 0, csum_size);
 			count = 1;
 
@@ -473,7 +497,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
 		bio_offset += count * sectorsize;
 	}
 
-	if (bbio->csum_search_commit_root)
+	if (using_commit_root)
 		up_read(&fs_info->commit_root_sem);
 	return ret;
 }
Signature · 1 line
2.53.0
author maintainer
#45 lore raw

PATCH 45/675 firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Unnathi Chalicheemala <[email protected]>

[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]

ffa_partition_info_get() passes uuid_str directly to uuid_parse() without a NULL check. When a caller passes NULL, uuid_parse() -> __uuid_parse() -> uuid_is_valid() dereferences the pointer, causing a kernel panic:

  |  Unable to handle kernel NULL pointer dereference at virtual address
  |  0000000000000040
  |  pc : uuid_parse+0x40/0xac
  |  lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]

Add a NULL guard before uuid_parse() so a NULL argument returns -ENODEV instead of crashing. Callers are expected to always supply a valid partition UUID, so NULL is not a supported input.

---
 drivers/firmware/arm_ffa/driver.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_ffa/driver.c +1 -1
index c76eabb8436a85..feded15bb5e921 100644
@@ -1133,7 +1133,7 @@ static int ffa_partition_info_get(const char *uuid_str,
 	uuid_t uuid;
 	struct ffa_partition_info *pbuf;
 
-	if (uuid_parse(uuid_str, &uuid)) {
+	if (!uuid_str || uuid_parse(uuid_str, &uuid)) {
 		pr_err("invalid uuid (%s)\n", uuid_str);
 		return -ENODEV;
 	}
Signature · 1 line
2.53.0
author maintainer
#46 lore raw

PATCH 46/675 sched/ext: Avoid null ptr traversal when ->put_prev_task() is called with NULL next

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: John Stultz <[email protected]>

[ Upstream commit 12b5cd99a05f7cbc2ceb88b3b9601d404ef2236a ]

Early when trying to get sched_ext and proxy-exe working together, I kept tripping over NULL ptr in put_prev_task_scx() on the line:
if (sched_class_above(&ext_sched_class, next->sched_class)) {

Which was due to put_prev_task() passes a NULL next, calling:
prev->sched_class->put_prev_task(rq, prev, NULL);

put_prev_task_scx() already guards for a NULL next in the switch_class case, but doesn't seem to have a guard for sched_class_above() check.

I can't say I understand why this doesn't trip usually without proxy-exec. And in newer kernels there are way fewer put_prev_task(), and I can't easily reproduce the issue now even with proxy-exec.

But we still have one put_prev_task() call left in core.c that seems like it could trip this, so I wanted to send this out for consideration.

tj: put_prev_task() can be called with NULL @next; however, when @p is queued, that doesn't happen, so this condition shouldn't currently be triggerable. The connection isn't straightforward or necessarily reliable, so add the NULL check even if it can't currently be triggered.

Stable-dep-of: b7d9c359e5cf ("sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()")

---
 kernel/sched/ext.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/ext.c +1 -1
index d8280f87443310..d399494364c0a3 100644
@@ -2396,7 +2396,7 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
 		 * ops.enqueue() that @p is the only one available for this cpu,
 		 * which should trigger an explicit follow-up scheduling event.
 		 */
-		if (sched_class_above(&ext_sched_class, next->sched_class)) {
+		if (next && sched_class_above(&ext_sched_class, next->sched_class)) {
 			WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_LAST));
 			do_enqueue_task(rq, p, SCX_ENQ_LAST, -1);
 		} else {
Signature · 1 line
2.53.0
author maintainer
#47 lore raw

PATCH 47/675 sched_ext: Dont warn on core-sched forced idle in put_prev_task_scx()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

[ Upstream commit b7d9c359e5cf867f7eb23df3bb1c6b9e58af24da ]

put_prev_task_scx() warns when a runnable task drops to a lower sched_class without SCX_OPS_ENQ_LAST, on the assumption that balance_one() would have kept it running. Core scheduling breaks that: a forced-idle SMT sibling reschedules through the core_pick fast path in pick_next_task(), which skips pick_task_scx() and thus balance_one(), so a runnable task can drop to idle with ENQ_LAST unset.

Gate the warning on sched_cpu_cookie_match(): a cookie mismatch means core scheduling forced the idle, while a match (or core scheduling off) still catches a genuine missing-ENQ_LAST drop.

Fixes 7c65ae81ea86 ("sched_ext: Don't call put_prev_task_scx() before picking the next task")
---
 kernel/sched/ext.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/sched/ext.c +6 -1
index d399494364c0a3..83baf270888882 100644
@@ -2395,9 +2395,14 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,
 		 * sched_class, %SCX_OPS_ENQ_LAST must be set. Tell
 		 * ops.enqueue() that @p is the only one available for this cpu,
 		 * which should trigger an explicit follow-up scheduling event.
+		 *
+		 * Core scheduling can force this CPU idle while @p stays
+		 * runnable. @p's cookie then won't match the core's, so skip
+		 * the warning in that case.
 		 */
 		if (next && sched_class_above(&ext_sched_class, next->sched_class)) {
-			WARN_ON_ONCE(!(sch->ops.flags & SCX_OPS_ENQ_LAST));
+			WARN_ON_ONCE(sched_cpu_cookie_match(rq, p) &&
+				     !(sch->ops.flags & SCX_OPS_ENQ_LAST));
 			do_enqueue_task(rq, p, SCX_ENQ_LAST, -1);
 		} else {
 			do_enqueue_task(rq, p, 0, -1);
Signature · 1 line
2.53.0
author maintainer
#48 lore raw

PATCH 48/675 xfrm: reject optional IPTFS templates in outbound policies

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Antony Antony <[email protected]>

[ Upstream commit ea528f18231ec0f33317be57f8866913b19aba6e ]

syzbot reported a stack-out-of-bounds read in xfrm_state_find() which flows from xfrm_tmpl_resolve_one().

Commit 3d776e31c841 ("xfrm: Reject optional tunnel/BEET mode templates in outbound policies") disallowed optional tunnel and BEET in outbound policies to prevent this. Later when IPTFS added, it was not covered by that fix and can still trigger the out-of-bounds read;

Extend the check to disallow optional IPTFS in outbound policies as well. IPTFS should be identical to tunnel mode.
IN and FWD policies are not affected: xfrm_tmpl_resolve_one() is only reachable via the outbound path.

Reproducer, before:

ip link add dummy0 type dummy
ip link set dummy0 up
ip addr add 10.1.1.1/24 dev dummy0
ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 mode transport
ping -W 1 -c 1 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.

[   64.168420] ==================================================================
[   64.169977] BUG: KASAN: stack-out-of-bounds in __xfrm6_addr_hash+0x11e/0x170
[   64.169977] Read of size 4 at addr ffff88800e1ffd20 by task ping/2844
[   64.169977] CPU: 2 UID: 0 PID: 2844 Comm: ping Not tainted 7.1.0-rc7-00180-geb23b588430a #98 PREEMPT(full)
[   64.169977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   64.169977] Call Trace:
[   64.169977]  <TASK>
[   64.169977]  dump_stack_lvl+0x47/0x70
[   64.169977]  ? __xfrm6_addr_hash+0x11e/0x170
[   64.169977]  print_report+0x152/0x4b0
[   64.169977]  ? ksys_mmap_pgoff+0x6d/0xa0
[   64.169977]  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   64.169977]  ? rcu_read_unlock_sched+0xa/0x20
[   64.169977]  ? __virt_addr_valid+0x21b/0x230
[   64.169977]  ? __xfrm6_addr_hash+0x11e/0x170
[   64.169977]  kasan_report+0xa8/0xd0
[   64.169977]  ? __xfrm6_addr_hash+0x11e/0x170
[   64.169977]  __xfrm6_addr_hash+0x11e/0x170
[   64.169977]  __xfrm_dst_hash+0x24/0xc0
[   64.169977]  xfrm_state_find+0xa2d/0x2f90
[   64.169977]  ? __pfx_xfrm_state_find+0x10/0x10
[   64.169977]  ? __pfx_ftrace_graph_ret_addr+0x10/0x10
[   64.169977]  ? __pfx_ftrace_graph_ret_addr+0x10/0x10
[   64.169977]  xfrm_tmpl_resolve_one+0x210/0x570
[   64.169977]  ? __pfx_xfrm_tmpl_resolve_one+0x10/0x10
[   64.169977]  ? __pfx_stack_trace_consume_entry+0x10/0x10
[   64.169977]  ? kernel_text_address+0x5b/0x80
[   64.169977]  ? __kernel_text_address+0xe/0x30
[   64.169977]  ? unwind_get_return_address+0x5e/0x90
[   64.169977]  ? arch_stack_walk+0x8c/0xe0
[   64.169977]  xfrm_tmpl_resolve+0x130/0x200
[   64.169977]  ? __pfx_xfrm_tmpl_resolve+0x10/0x10
[   64.169977]  ? __pfx_xfrm_policy_inexact_lookup_rcu+0x10/0x10
[   64.169977]  ? __refcount_add_not_zero.constprop.0+0xb2/0x110
[   64.169977]  ? __pfx___refcount_add_not_zero.constprop.0+0x10/0x10
[   64.169977]  xfrm_resolve_and_create_bundle+0xd5/0x310
[   64.169977]  ? __pfx_xfrm_resolve_and_create_bundle+0x10/0x10
[   64.169977]  ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
[   64.169977]  ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
[   64.169977]  xfrm_lookup_with_ifid+0x3d8/0xb80
[   64.169977]  ? __pfx_xfrm_lookup_with_ifid+0x10/0x10
[   64.169977]  ? ip_route_output_key_hash+0xc6/0x110
[   64.169977]  ? kasan_save_track+0x10/0x30
[   64.169977]  xfrm_lookup_route+0x18/0xe0
[   64.169977]  ip4_datagram_release_cb+0x4c9/0x530
[   64.169977]  ? __pfx_ip4_datagram_release_cb+0x10/0x10
[   64.169977]  ? do_raw_spin_lock+0x71/0xc0
[   64.169977]  ? __pfx_do_raw_spin_lock+0x10/0x10
[   64.169977]  release_sock+0xb0/0x170
[   64.169977]  udp_connect+0x43/0x50
[   64.169977]  __sys_connect+0xa6/0x100
[   64.169977]  ? alloc_fd+0x2e9/0x300
[   64.169977]  ? __pfx___sys_connect+0x10/0x10
[   64.169977]  ? preempt_latency_start+0x1f/0x70
[   64.169977]  ? fd_install+0x7e/0x150
[   64.169977]  ? rcu_read_unlock_sched+0xa/0x20
[   64.169977]  ? __sys_socket+0xdf/0x130
[   64.169977]  ? __pfx___sys_socket+0x10/0x10
[   64.169977]  ? vma_refcount_put+0x43/0xa0
[   64.169977]  __x64_sys_connect+0x7e/0x90
[   64.169977]  do_syscall_64+0x11b/0x2b0
[   64.169977]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   64.169977] RIP: 0033:0x7f4851ecb570
[   64.169977] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 80 3d f9 ca 0d 00 00 74 17 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 54
[   64.169977] RSP: 002b:00007ffc830e3498 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
[   64.169977] RAX: ffffffffffffffda RBX: 00007ffc830e34d0 RCX: 00007f4851ecb570
[   64.169977] RDX: 0000000000000010 RSI: 00007ffc830e34d0 RDI: 0000000000000005
[   64.169977] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
[   64.169977] R10: 0000000000000006 R11: 0000000000000202 R12: 0000000000000005
[   64.169977] R13: 0000000000000000 R14: 00005619a863f340 R15: 0000000000000000
[   64.169977]  </TASK>
[   64.169977] The buggy address belongs to stack of task ping/2844
[   64.169977]  and is located at offset 88 in frame:
[   64.169977]  ip4_datagram_release_cb+0x0/0x530
[   64.169977] This frame has 1 object:
[   64.169977]  [32, 88) 'fl4'
[   64.169977] The buggy address belongs to the physical page:
[   64.169977] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xe1ff
[   64.169977] flags: 0x4000000000000000(zone=1)
[   64.169977] raw: 4000000000000000 0000000000000000 ffffea0000387fc8 0000000000000000
[   64.169977] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   64.169977] page dumped because: kasan: bad access detected
[   64.169977] Memory state around the buggy address:
[   64.169977]  ffff88800e1ffc00: f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00
[   64.169977]  ffff88800e1ffc80: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00
[   64.169977] >ffff88800e1ffd00: 00 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00
[   64.169977]                                ^
[   64.169977]  ffff88800e1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
[   64.169977]  ffff88800e1ffe00: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   64.169977] ==================================================================
[   64.245153] Disabling lock debugging due to kernel taint

After the fix:

ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl \
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs \
level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 \
mode transport

Error: Mode in optional template not allowed in outbound policy.

Fixes d1716d5a44c3 ("xfrm: add generic iptfs defines and functionality")
Reported-by [email protected]
---
 net/xfrm/xfrm_user.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
net/xfrm/xfrm_user.c +1 -2
index 9ad6619888c738..3641ccccbc4153 100644
@@ -2068,13 +2068,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
 		switch (ut[i].mode) {
 		case XFRM_MODE_TUNNEL:
 		case XFRM_MODE_BEET:
+		case XFRM_MODE_IPTFS:
 			if (ut[i].optional && dir == XFRM_POLICY_OUT) {
 				NL_SET_ERR_MSG(extack, "Mode in optional template not allowed in outbound policy");
 				return -EINVAL;
 			}
 			break;
-		case XFRM_MODE_IPTFS:
-			break;
 		default:
 			if (ut[i].family != prev_family) {
 				NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
Signature · 1 line
2.53.0
author maintainer
#49 lore raw

PATCH 49/675 RDMA/cma: Fix hardware address comparison length in netevent callback

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Or Gerlitz <[email protected]>

[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]

The cited commit hardcoded the hardware address comparison len to ETH_ALEN.

This breaks IPoIB, which uses 20-byte addresses. By truncating the memcmp, the CMA may incorrectly assume the target address is unchanged and fails to abort the stalled connection.

Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len to correctly evaluate the full address regardless of the link layer.

Fixes 925d046e7e52 ("RDMA/core: Add a netevent notifier to cma")
---
 drivers/infiniband/core/cma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/cma.c +1 -1
index ce511800b056cf..648acc2222cf54 100644
@@ -5237,7 +5237,7 @@ static int cma_netevent_callback(struct notifier_block *self,
 
 	list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
 		if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
-			   neigh->ha, ETH_ALEN))
+			   neigh->ha, neigh->dev->addr_len))
 			continue;
 		cma_id_get(current_id);
 		if (!queue_work(cma_wq, &current_id->id.net_work))
Signature · 1 line
2.53.0
author maintainer
#50 lore raw

PATCH 50/675 RDMA/umem: Add pinned revocable dmabuf import interface

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jacob Moroni <[email protected]>

[ Upstream commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c ]

Added an interface for importing a pinned but revocable dmabuf. This interface can be used by drivers that are capable of revocation so that they can import dmabufs from exporters that may require it, such as VFIO.

This interface implements a two step process, where drivers will first call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and map the dmabuf (and provide a functional move_notify/invalidate_mappings callback), but will return with the lock still held so that the driver can then populate the callback via ib_umem_dmabuf_set_revoke_locked() without races from concurrent revocations. This scheme also allows for easier integration with drivers that may not have actually allocated their internal MR objects at the time of the get_pinned_revocable* call.

Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")

---
 drivers/infiniband/core/umem_dmabuf.c | 61 +++++++++++++++++++++++++++
 include/rdma/ib_umem.h                | 19 +++++++++
 2 files changed, 80 insertions(+)
drivers/infiniband/core/umem_dmabuf.c +61 -0
index b239ac09ec2921..4fc73f53342b7e 100644
@@ -206,6 +206,10 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
 
 	if (umem_dmabuf->revoked)
 		return;
+
+	if (umem_dmabuf->pinned_revoke)
+		umem_dmabuf->pinned_revoke(umem_dmabuf->private);
+
 	ib_umem_dmabuf_unmap_pages(umem_dmabuf);
 	if (umem_dmabuf->pinned) {
 		dma_buf_unpin(umem_dmabuf->attach);
@@ -214,6 +218,11 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)
 	umem_dmabuf->revoked = 1;
 }
 
+static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = {
+	.allow_peer2peer = true,
+	.move_notify = ib_umem_dmabuf_revoke_locked,
+};
+
 static struct ib_umem_dmabuf *
 ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device,
 				   struct device *dma_device,
@@ -266,6 +275,58 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
 }
 EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
 
+/**
+ * ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf
+ * @device: IB device.
+ * @offset: Start offset.
+ * @size: Length.
+ * @fd: dmabuf fd.
+ * @access: Access flags.
+ *
+ * Obtains a umem from a dmabuf for drivers/devices that can support revocation.
+ *
+ * Returns with dma_resv_lock held upon success. The driver must set the revoke
+ * callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked().
+ *
+ * When a revocation occurs, the revoke callback will be called. The driver must
+ * ensure that the region is no longer accessed when the callback returns. Any
+ * subsequent access attempts should also probably cause an AE for MRs.
+ *
+ * If the umem is used for an MR, the driver must ensure that the key remains in
+ * use such that it cannot be obtained by a new region until this region is
+ * fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with
+ * revoke calls, it can use dma_resv_lock.
+ *
+ * If successful, then the revoke callback may be called at any time and will
+ * also be called automatically upon ib_umem_release (serialized). The revoke
+ * callback will be called one time at most.
+ *
+ * Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure.
+ */
+struct ib_umem_dmabuf *
+ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
+					     unsigned long offset, size_t size,
+					     int fd, int access)
+{
+	const struct dma_buf_attach_ops *ops =
+		&ib_umem_dmabuf_attach_pinned_revocable_ops;
+
+	return ib_umem_dmabuf_get_pinned_and_lock(device, device->dma_device,
+						  offset, size, fd, access,
+						  ops);
+}
+EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_revocable_and_lock);
+
+void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
+				      void (*revoke)(void *priv), void *priv)
+{
+	dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
+
+	umem_dmabuf->pinned_revoke = revoke;
+	umem_dmabuf->private = priv;
+}
+EXPORT_SYMBOL(ib_umem_dmabuf_set_revoke_locked);
+
 struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
 						 unsigned long offset,
 						 size_t size, int fd,
include/rdma/ib_umem.h +19 -0
index 5122f78467675e..90b1ea19a90a0a 100644
@@ -36,6 +36,7 @@ struct ib_umem_dmabuf {
 	struct scatterlist *last_sg;
 	unsigned long first_sg_offset;
 	unsigned long last_sg_trim;
+	void (*pinned_revoke)(void *priv);
 	void *private;
 	u8 pinned : 1;
 	u8 revoked : 1;
@@ -141,6 +142,12 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
 						 size_t size, int fd,
 						 int access);
 struct ib_umem_dmabuf *
+ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
+					     unsigned long offset, size_t size,
+					     int fd, int access);
+void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
+				      void (*revoke)(void *priv), void *priv);
+struct ib_umem_dmabuf *
 ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
 					  struct device *dma_device,
 					  unsigned long offset, size_t size,
@@ -201,6 +208,18 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline struct ib_umem_dmabuf *
+ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device,
+					     unsigned long offset, size_t size,
+					     int fd, int access)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void
+ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf,
+				 void (*revoke)(void *priv), void *priv) {}
+
 static inline struct ib_umem_dmabuf *
 ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
 					  struct device *dma_device,
Signature · 1 line
2.53.0
author maintainer
#51 lore raw

PATCH 51/675 RDMA/irdma: Prevent rereg_mr for non-mem regions

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jacob Moroni <[email protected]>

[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]

When a QP/CQ/SRQ is created, a two step process is used where the buffer is allocated in userspace and explicitly registered with the normal reg_mr mechanism prior to creating the actual QP/CQ/SRQ object.

These special registrations are indicated via an ABI field so the driver knows that they do not have a valid mkey and to skip the actual CQP command submission.

Since these are real MR objects from the core's perspective, it is possible for a user application to invoke rereg_mr on them and cause a real CQP op to be emitted with the zero-initialized mkey value of 0.

Fix this by preventing rereg_mr on these special regions.

Fixes 5ac388db27c4 ("RDMA/irdma: Add support to re-register a memory region")
---
 drivers/infiniband/hw/irdma/verbs.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/infiniband/hw/irdma/verbs.c +3 -0
index 2b85e32134a5b8..c210f9a37fb97b 100644
@@ -3756,6 +3756,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
 	if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
 		return ERR_PTR(-EOPNOTSUPP);
 
+	if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
+	     return ERR_PTR(-EINVAL);
+
 	ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
 	if (ret)
 		return ERR_PTR(ret);
Signature · 1 line
2.53.0
author maintainer
#52 lore raw

PATCH 52/675 RDMA/irdma: Remove redundant legacy_mode checks

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jacob Moroni <[email protected]>

[ Upstream commit ed8621be482bf18dcd217aa024e95758bf9d28f2 ]

The driver has the following invariants:

1. legacy_mode is only allowed on GEN_1 hardware (enforced in irdma_alloc_ucontext).

2. GEN_1 hardware does not set IRDMA_FEATURE_CQ_RESIZE or IRDMA_FEATURE_RTS_AE. These feature flags are only set for GEN_2 and GEN_3 hardware.

Therefore, legacy_mode is always false if IRDMA_FEATURE_CQ_RESIZE or IRDMA_FEATURE_RTS_AE is set, so remove the redundant checks.

Stable-dep-of: b9b088907156 ("RDMA/irdma: Prevent user-triggered null deref on QP create")

---
 drivers/infiniband/hw/irdma/uk.c    | 9 +++------
 drivers/infiniband/hw/irdma/user.h  | 1 -
 drivers/infiniband/hw/irdma/verbs.c | 7 +------
 3 files changed, 4 insertions(+), 13 deletions(-)
drivers/infiniband/hw/irdma/uk.c +3 -6
index 4cc81d61be7fad..7aab0076196677 100644
@@ -1540,15 +1540,12 @@ static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {
  * irdma_setup_connection_wqes - setup WQEs necessary to complete
  * connection.
  * @qp: hw qp (user and kernel)
- * @info: qp initialization info
  */
-static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
-					struct irdma_qp_uk_init_info *info)
+static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp)
 {
 	u16 move_cnt = 1;
 
-	if (!info->legacy_mode &&
-	    (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE))
+	if (qp->uk_attrs->feature_flags & IRDMA_FEATURE_RTS_AE)
 		move_cnt = 3;
 
 	qp->conn_wqes = move_cnt;
@@ -1699,7 +1696,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
 	sq_ring_size = qp->sq_size << info->sq_shift;
 	IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
 	if (info->first_sq_wq) {
-		irdma_setup_connection_wqes(qp, info);
+		irdma_setup_connection_wqes(qp);
 		qp->swqe_polarity = 1;
 		qp->first_sq_wq = true;
 	} else {
drivers/infiniband/hw/irdma/user.h +0 -1
index aeebf768174abd..a0b409a895f0eb 100644
@@ -560,7 +560,6 @@ struct irdma_qp_uk_init_info {
 	u8 sq_shift;
 	u8 rq_shift;
 	int abi_ver;
-	bool legacy_mode;
 	struct irdma_srq_uk *srq_uk;
 };
 
drivers/infiniband/hw/irdma/verbs.c +1 -6
index c210f9a37fb97b..dfd5f0caabb878 100644
@@ -632,7 +632,6 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
 	iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
 	iwqp->user_mode = 1;
 	if (req.user_wqe_bufs) {
-		info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode;
 		spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
 		iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
 					    &ucontext->qp_reg_mem_list);
@@ -2068,10 +2067,6 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
 			rdma_udata_to_drv_context(udata, struct irdma_ucontext,
 						  ibucontext);
 
-		/* CQ resize not supported with legacy GEN_1 libi40iw */
-		if (ucontext->legacy_mode)
-			return -EOPNOTSUPP;
-
 		if (ib_copy_from_udata(&req, udata,
 				       min(sizeof(req), udata->inlen)))
 			return -EINVAL;
@@ -2550,7 +2545,7 @@ static int irdma_create_cq(struct ib_cq *ibcq,
 		cqmr = &iwpbl->cq_mr;
 
 		if (rf->sc_dev.hw_attrs.uk_attrs.feature_flags &
-		    IRDMA_FEATURE_CQ_RESIZE && !ucontext->legacy_mode) {
+		    IRDMA_FEATURE_CQ_RESIZE) {
 			spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
 			iwpbl_shadow = irdma_get_pbl(
 					(unsigned long)req.user_shadow_area,
Signature · 1 line
2.53.0
author maintainer
#53 lore raw

PATCH 53/675 RDMA/irdma: Prevent user-triggered null deref on QP create

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jacob Moroni <[email protected]>

[ Upstream commit b9b0889071569d43623c260074e159cd8f26adb1 ]

Previously, the user QP creation path would only attempt to populate iwqp->iwpbl if the user-provided req.user_wqe_bufs field was non-zero. The problem is that iwqp->iwpbl is unconditionally dereferenced later on in irdma_setup_virt_qp.

While there was a check for iwqp->iwpbl != NULL, this check would only occur if req.user_wqe_bufs was non-zero. The end result is that a user could send a zero user_wqe_bufs value and trigger a null ptr deref.

Fix this by unconditionally calling irdma_get_pbl and bailing if it fails, similar to the CQ and SRQ paths.

Fixes b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
---
 drivers/infiniband/hw/irdma/verbs.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/infiniband/hw/irdma/verbs.c +9 -10
index dfd5f0caabb878..5f5b79109d5471 100644
@@ -631,17 +631,16 @@ static int irdma_setup_umode_qp(struct ib_udata *udata,
 
 	iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
 	iwqp->user_mode = 1;
-	if (req.user_wqe_bufs) {
-		spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
-		iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
-					    &ucontext->qp_reg_mem_list);
-		spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
 
-		if (!iwqp->iwpbl) {
-			ret = -ENODATA;
-			ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
-			return ret;
-		}
+	spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+	iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+				    &ucontext->qp_reg_mem_list);
+	spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
+
+	if (!iwqp->iwpbl) {
+		ret = -ENODATA;
+		ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
+		return ret;
 	}
 
 	if (!ucontext->use_raw_attrs) {
Signature · 1 line
2.53.0
author maintainer
#54 lore raw

PATCH 54/675 RDMA/erdma: initialize ret for empty receive WR lists

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ruoyu Wang <[email protected]>

[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]

erdma_post_recv() returns ret after walking the receive work request list. If the caller passes an empty list, the loop is skipped and ret is not assigned.

Initialize ret to 0 so an empty receive work request list returns success instead of stack data.

---
 drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/erdma/erdma_qp.c +1 -1
index 25f6c49aec7798..e002343832f74d 100644
@@ -734,7 +734,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
 	const struct ib_recv_wr *wr = recv_wr;
 	struct erdma_qp *qp = to_eqp(ibqp);
 	unsigned long flags;
-	int ret;
+	int ret = 0;
 
 	spin_lock_irqsave(&qp->lock, flags);
 
Signature · 1 line
2.53.0
author maintainer
#55 lore raw

PATCH 55/675 RDMA/mana_ib: initialize err for empty send WR lists

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ruoyu Wang <[email protected]>

[ Upstream commit 155fd5ce2382b0ffbec0d7ee7b3a6818a27a5aed ]

mana_ib_post_send() returns err after walking the send work request list. If the caller passes an empty list, the loop is skipped and err is not assigned.

Initialize err to 0 so an empty send work request list returns success instead of stack data.

---
 drivers/infiniband/hw/mana/wr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mana/wr.c +1 -1
index 1813567d3b16c9..36a1d506f08f65 100644
@@ -144,7 +144,7 @@ static int mana_ib_post_send_ud(struct mana_ib_qp *qp, const struct ib_ud_wr *wr
 int mana_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
 		      const struct ib_send_wr **bad_wr)
 {
-	int err;
+	int err = 0;
 	struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
 
 	for (; wr; wr = wr->next) {
Signature · 1 line
2.53.0
author maintainer
#56 lore raw

PATCH 56/675 RDMA/hns: Fix potential integer overflow in mhop hem cleanup

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Danila Chernetsov <[email protected]>

[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]

In hns_roce_cleanup_mhop_hem_table(), the expression:

    obj = i * buf_chunk_size / table->obj_size;

is evaluated using 32-bit unsigned arithmetic because 'buf_chunk_size' is u32 and the usual arithmetic conversions convert 'i' to unsigned int. The result is assigned to a u64 variable, but the multiplication may overflow before the assignment.

For sufficiently large HEM tables, this produces an incorrect object index passed to hns_roce_table_mhop_put().

Cast 'i' to u64 before the multiplication so that the intermediate calculation is performed with 64-bit arithmetic.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes a25d13cbe816 ("RDMA/hns: Add the interfaces to support multi hop addressing for the contexts in hip08")
---
 drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +1 -1
index 1680d0ac071ed1..ae7a3939124f23 100644
@@ -842,7 +842,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
 					mhop.bt_chunk_size;
 
 	for (i = 0; i < table->num_hem; ++i) {
-		obj = i * buf_chunk_size / table->obj_size;
+		obj = (u64)i * buf_chunk_size / table->obj_size;
 		if (table->hem[i])
 			hns_roce_table_mhop_put(hr_dev, table, obj, 0);
 	}
Signature · 1 line
2.53.0
author maintainer
#57 lore raw

PATCH 57/675 RDMA/siw: publish QP after initialization

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ruoyu Wang <[email protected]>

[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]

siw_create_qp() currently calls siw_qp_add() before the queues, CQ pointers, state, completion, and device list entry are ready. A QPN lookup can therefore reach a QP that is still being constructed.

Move siw_qp_add() to the end of siw_create_qp(), after QP initialization and before adding the QP to the siw device list.

---
 drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------
 1 file changed, 24 insertions(+), 20 deletions(-)
drivers/infiniband/sw/siw/siw_verbs.c +24 -20
index efa2f097b58289..9fbade0b85715a 100644
@@ -316,6 +316,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 	struct siw_ucontext *uctx =
 		rdma_udata_to_drv_context(udata, struct siw_ucontext,
 					  base_ucontext);
+	struct siw_uresp_create_qp uresp = {};
 	unsigned long flags;
 	int num_sqe, num_rqe, rv = 0;
 	size_t length;
@@ -369,11 +370,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 	spin_lock_init(&qp->rq_lock);
 	spin_lock_init(&qp->orq_lock);
 
-	rv = siw_qp_add(sdev, qp);
-	if (rv)
-		goto err_atomic;
-
-
 	/* All queue indices are derived from modulo operations
 	 * on a free running 'get' (consumer) and 'put' (producer)
 	 * unsigned counter. Having queue sizes at power of two
@@ -391,14 +387,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 
 	if (qp->sendq == NULL) {
 		rv = -ENOMEM;
-		goto err_out_xa;
+		goto err_out;
 	}
 	if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
 		if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
 			qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
 		else {
 			rv = -EINVAL;
-			goto err_out_xa;
+			goto err_out;
 		}
 	}
 	qp->pd = pd;
@@ -424,7 +420,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 
 		if (qp->recvq == NULL) {
 			rv = -ENOMEM;
-			goto err_out_xa;
+			goto err_out;
 		}
 		qp->attrs.rq_size = num_rqe;
 	}
@@ -439,11 +435,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 	qp->attrs.state = SIW_QP_STATE_IDLE;
 
 	if (udata) {
-		struct siw_uresp_create_qp uresp = {};
-
 		uresp.num_sqe = num_sqe;
 		uresp.num_rqe = num_rqe;
-		uresp.qp_id = qp_id(qp);
 
 		if (qp->sendq) {
 			length = num_sqe * sizeof(struct siw_sqe);
@@ -452,7 +445,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 						      length, &uresp.sq_key);
 			if (!qp->sq_entry) {
 				rv = -ENOMEM;
-				goto err_out_xa;
+				goto err_out;
 			}
 		}
 
@@ -464,9 +457,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 			if (!qp->rq_entry) {
 				uresp.sq_key = SIW_INVAL_UOBJ_KEY;
 				rv = -ENOMEM;
-				goto err_out_xa;
+				goto err_out;
 			}
 		}
+	}
+	qp->tx_cpu = siw_get_tx_cpu(sdev);
+	if (qp->tx_cpu < 0) {
+		rv = -EINVAL;
+		goto err_out;
+	}
+	init_completion(&qp->qp_free);
+
+	rv = siw_qp_add(sdev, qp);
+	if (rv)
+		goto err_out_tx;
+
+	if (udata) {
+		uresp.qp_id = qp_id(qp);
 
 		if (udata->outlen < sizeof(uresp)) {
 			rv = -EINVAL;
@@ -476,22 +483,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
 		if (rv)
 			goto err_out_xa;
 	}
-	qp->tx_cpu = siw_get_tx_cpu(sdev);
-	if (qp->tx_cpu < 0) {
-		rv = -EINVAL;
-		goto err_out_xa;
-	}
+
 	INIT_LIST_HEAD(&qp->devq);
 	spin_lock_irqsave(&sdev->lock, flags);
 	list_add_tail(&qp->devq, &sdev->qp_list);
 	spin_unlock_irqrestore(&sdev->lock, flags);
 
-	init_completion(&qp->qp_free);
-
 	return 0;
 
 err_out_xa:
 	xa_erase(&sdev->qp_xa, qp_id(qp));
+err_out_tx:
+	siw_put_tx_cpu(qp->tx_cpu);
+err_out:
 	if (uctx) {
 		rdma_user_mmap_entry_remove(qp->sq_entry);
 		rdma_user_mmap_entry_remove(qp->rq_entry);
Signature · 1 line
2.53.0
author maintainer
#58 lore raw

PATCH 58/675 mtd: fix double free and WARN_ON in add_mtd_device() error paths

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xue Lei <[email protected]>

[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]

When device_register() or mtd_nvmem_add() fails inside add_mtd_device() for a partition, the error handling triggers mtd_release() via put_device() or device_unregister(). mtd_release() calls release_mtd_partition() which frees the mtd_info structure. However, callers such as mtd_add_partition() and add_mtd_partitions() also call free_partition() in their error paths, resulting in a double free.

Additionally, release_mtd_partition() hits WARN_ON(!list_empty( &mtd->part.node)) because the partition node is still linked in the parent's partitions list when the release callback fires from the add_mtd_device() error path.

Fix this by overriding dev->type and dev->release before put_device() in the error paths, so that device_release() invokes a no-op function instead of mtd_release(). For the mtd_nvmem_add() failure case, device_unregister() is replaced with device_del() to separate the device removal from the final kobject reference drop, allowing the override to take effect before put_device() is called.

The callers' error paths (list_del + free_partition) remain the sole owners of mtd_info lifetime on add_mtd_device() failure, which is the expected contract.

The normal partition teardown path is not affected: del_mtd_device() goes through kref_put() -> mtd_device_release() -> device_unregister() with dev->type still set to &mtd_devtype, so mtd_release() -> release_mtd_partition() continues to work correctly for the regular removal case.

Reported-by [email protected]
Fixes 19bfa9ebebb5 ("mtd: use refcount to prevent corruption")
---
 drivers/mtd/mtdcore.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/mtd/mtdcore.c +19 -4
index 64808493b4f5ea..42cabd3c1efad1 100644
@@ -104,6 +104,15 @@ static void mtd_release(struct device *dev)
 	device_destroy(&mtd_class, index + 1);
 }
 
+/*
+ * No-op device release used in add_mtd_device() error paths.
+ * Prevents mtd_release() from being called via device_release(),
+ * which would free the mtd_info that the caller still manages.
+ */
+static void mtd_dev_release_nop(struct device *dev)
+{
+}
+
 static void mtd_device_release(struct kref *kref)
 {
 	struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
@@ -798,10 +807,8 @@ int add_mtd_device(struct mtd_info *mtd)
 	mtd_check_of_node(mtd);
 	of_node_get(mtd_get_of_node(mtd));
 	error = device_register(&mtd->dev);
-	if (error) {
-		put_device(&mtd->dev);
+	if (error)
 		goto fail_added;
-	}
 
 	/* Add the nvmem provider */
 	error = mtd_nvmem_add(mtd);
@@ -839,8 +846,16 @@ int add_mtd_device(struct mtd_info *mtd)
 	return 0;
 
 fail_nvmem_add:
-	device_unregister(&mtd->dev);
+	device_del(&mtd->dev);
 fail_added:
+	/*
+	 * Clear type and set nop release to prevent mtd_release() ->
+	 * release_mtd_partition() -> free_partition() from freeing mtd.
+	 * The caller handles cleanup on failure.
+	 */
+	mtd->dev.type = NULL;
+	mtd->dev.release = mtd_dev_release_nop;
+	put_device(&mtd->dev);
 	of_node_put(mtd_get_of_node(mtd));
 fail_devname:
 	idr_remove(&mtd_idr, i);
Signature · 1 line
2.53.0
author maintainer
#59 lore raw

PATCH 59/675 selftests/alsa: Fix memory leak in find_controls error path

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Malaya Kumar Rout <[email protected]>

[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]

In find_controls(), card_data is allocated with malloc() but when snd_ctl_open_lconf() fails, the code jumps to next_card without freeing the allocated memory. This results in a memory leak for each card where snd_ctl_open_lconf() fails.

Add free(card_data) before goto next_card to ensure proper cleanup of the allocated memory in the error path.

Fixes 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
---
 tools/testing/selftests/alsa/mixer-test.c | 1 +
 1 file changed, 1 insertion(+)
tools/testing/selftests/alsa/mixer-test.c +1 -0
index e113dafa5c2464..cfb7968fbac075 100644
@@ -84,6 +84,7 @@ static void find_controls(void)
 		if (err < 0) {
 			ksft_print_msg("Failed to get hctl for card %d: %s\n",
 				       card, snd_strerror(err));
+			free(card_data);
 			goto next_card;
 		}
 
Signature · 1 line
2.53.0
author maintainer
#60 lore raw

PATCH 60/675 RDMA/irdma: Prevent overflows in memory contiguity checks

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aleksandrova Alyona <[email protected]>

[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]

irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that PBL entries describe physically contiguous memory ranges.

Both functions calculate byte offsets using 32-bit operands. For example, with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.

These values are reachable in the driver. For MRs, palloc->total_cnt comes from iwmr->page_cnt, which is calculated by ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE, so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE resources do not exclude this value either: for gen3, the limit is based on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs are enough for 1048576 PBLEs.

Cast one operand to u64 before the multiplications so that the offset calculations are performed in 64-bit arithmetic.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
---
 drivers/infiniband/hw/irdma/verbs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/irdma/verbs.c +2 -2
index 5f5b79109d5471..4084168d0194fb 100644
@@ -2800,7 +2800,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
 	u32 pg_idx;
 
 	for (pg_idx = 0; pg_idx < npages; pg_idx++) {
-		if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
+		if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
 			return false;
 	}
 
@@ -2833,7 +2833,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
 
 	for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
 		arr = leaf->addr;
-		if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
+		if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
 			return false;
 		ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
 		if (!ret)
Signature · 1 line
2.53.0
author maintainer
#61 lore raw

PATCH 61/675 xfrm: clear mode callbacks after failed mode setup

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cen Zhang <[email protected]>

[ Upstream commit 2538bd3cd1ff5af655908469544ac7b7ae259386 ]

xfrm_state_gc_task can run long after a failed IPTFS state setup. In the reproduced case, __xfrm_init_state() cached x->mode_cbs, IPTFS setup returned -ENOMEM before publishing mode_data, and the temporary module reference from xfrm_get_mode_cbs() was dropped immediately. The dead state then kept x->mode_cbs until deferred GC ran after xfrm_iptfs had been unloaded.

Clear x->mode_cbs when mode init or clone fails before publishing mode_data. Those states never installed mode-specific state or the long-term IPTFS module pin, so deferred GC has nothing mode-specific to destroy and must not retain a callback table pointer past the temporary lookup reference.

The buggy scenario involves two paths, with each column showing the order within that path:

failed setup path:
1. cache x->mode_cbs
2. mode setup fails before mode_data
3. drop the temporary module ref
4. dead state keeps x->mode_cbs cached

GC/unload path:
1. xfrm_state_put() queues GC work
2. xfrm_iptfs unloads later
3. xfrm_state_gc_task runs
4. GC dereferences stale x->mode_cbs

This also covers the failed clone path where clone_state() returns before publishing mode_data.

Validation reproduced this kernel report:

Kernel panic - not syncing: Fatal exception

CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y failslab_stacktrace_filter matched xfrm_iptfs frames ack_error=-12
FAULT_INJECTION: forcing a failure

BUG: unable to handle page fault
Workqueue: events xfrm_state_gc_task
RIP: xfrm_state_gc_task+0x142/0x650
Modules linked in: esp4_offload xfrm_user [last unloaded: xfrm_iptfs]
Kernel panic - not syncing: Fatal exception
Fixes 4b3faf610cc6 ("xfrm: iptfs: add new iptfs xfrm mode impl")
Assisted-by Codex:gpt-5.5
---
 net/xfrm/xfrm_state.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/xfrm/xfrm_state.c +6 -1
index 89daad5db10c9d..b9049c2297bd5a 100644
@@ -2070,8 +2070,11 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
 
 	x->mode_cbs = orig->mode_cbs;
 	if (x->mode_cbs && x->mode_cbs->clone_state) {
-		if (x->mode_cbs->clone_state(x, orig))
+		if (x->mode_cbs->clone_state(x, orig)) {
+			if (!x->mode_data)
+				x->mode_cbs = NULL;
 			goto error;
+		}
 	}
 
 
@@ -3253,6 +3256,8 @@ int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 		if (x->mode_cbs->init_state)
 			err = x->mode_cbs->init_state(x);
 		module_put(x->mode_cbs->owner);
+		if (err && !x->mode_data)
+			x->mode_cbs = NULL;
 	}
 error:
 	return err;
Signature · 1 line
2.53.0
author maintainer
#62 lore raw

PATCH 62/675 xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chen YanJun <[email protected]>

[ Upstream commit 430ea57d6daf765e88f90046afbfd1e071cb7200 ]

When iptfs_skb_add_frags() copies frag references from the source frag walk into a new SKB, it increments the page reference count via __skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the destination SKB's skb_shinfo->flags.

If the source SKB carries shared frags (e.g. from a page-pool backed receive path), the new inner SKB will appear to ESP as having privately owned frags. A subsequent esp_input() call for a nested transport-mode SA then takes the no-COW fast path and decrypts in place, writing over pages that are still referenced by the outer IPTFS SKB. This causes kernel-visible memory corruption and can trigger a panic.

All other frag-transfer helpers in the kernel (skb_try_coalesce, skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this convention by setting the flag inside the loop immediately after __skb_frag_ref() and nr_frags++, so every exit path that attaches a frag unconditionally propagates SKBFL_SHARED_FRAG.

Fixes 5f2b6a909574 ("xfrm: iptfs: add skb-fragment sharing code")
---
 net/xfrm/xfrm_iptfs.c | 1 +
 1 file changed, 1 insertion(+)
net/xfrm/xfrm_iptfs.c +1 -0
index fe8e4f21b32819..d39253b06c4efd 100644
@@ -480,6 +480,7 @@ static int iptfs_skb_add_frags(struct sk_buff *skb,
 		}
 		__skb_frag_ref(tofrag);
 		shinfo->nr_frags++;
+		shinfo->flags |= SKBFL_SHARED_FRAG;
 
 		/* see if we are done */
 		fraglen = tofrag->len;
Signature · 1 line
2.53.0
author maintainer
#63 lore raw

PATCH 63/675 xfrm6: clear dst.dev on error to avoid double netdev_put in xfrm6_fill_dst()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei (Microsoft) <[email protected]>

[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]

On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst() releases the device reference with netdev_put() but leaves xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev) again, so the same net_device reference is released twice, underflowing its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for <dev> to become free").

Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.

ref_tracker: reference already released.
ref_tracker: allocated in:
xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
...
udpv6_sendmsg (net/ipv6/udp.c:1696)
...
ref_tracker: freed in:
xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
...

  WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780
   dst_destroy (net/core/dst.c:115)
   rcu_core
   handle_softirqs
   ...
Fixes 84c4a9dfbf43 ("xfrm6: release dev before returning error")
Reported-by [email protected]
---
 net/ipv6/xfrm6_policy.c | 1 +
 1 file changed, 1 insertion(+)
net/ipv6/xfrm6_policy.c +1 -0
index 125ea9a5b8a082..3b749475f6ed65 100644
@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
 	xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
 	if (!xdst->u.rt6.rt6i_idev) {
 		netdev_put(dev, &xdst->u.dst.dev_tracker);
+		xdst->u.dst.dev = NULL;
 		return -ENODEV;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#64 lore raw

PATCH 64/675 xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei (Microsoft) <[email protected]>

[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]

xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or fail. But its guard is inverted: it skips policies with prefixlen < threshold and preallocates for the rest.

prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the loop preallocates for the exact policies (which never allocate) and skips the inexact ones, whose bin/node is then allocated GFP_ATOMIC during reinsert. On failure the error path only WARN_ONCE()s and continues, leaving a poisoned bydst node; the next rebuild's hlist_del_rcu() dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure, deterministic via failslab.

Invert the guard so preallocation covers exactly the reinserted policies; the reinsert then allocates nothing and cannot fail.

Crash:

  Oops: general protection fault, probably for non-canonical address
  0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI
  KASAN: maybe wild-memory-access in range [0xdead...]
  ...
  Workqueue: events xfrm_hash_rebuild
  RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190
  RAX: dead000000000122   (LIST_POISON2 + offset)
  ...
  Call Trace:
   hlist_del_rcu (include/linux/rculist.h:599)
   xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365)
   process_one_work (kernel/workqueue.c:3322)
   worker_thread (kernel/workqueue.c:3486)
   kthread (kernel/kthread.c:436)
   ret_from_fork (arch/x86/kernel/process.c:158)
   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
   ...
  Kernel panic - not syncing: Fatal exception in interrupt
Fixes 24969facd704 ("xfrm: policy: store inexact policies in an rhashtable")
Reported-by [email protected]
---
 net/xfrm/xfrm_policy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/xfrm/xfrm_policy.c +2 -2
index 4dad1f8172286a..25f9cbd3ce6a4f 100644
@@ -1329,8 +1329,8 @@ static void xfrm_hash_rebuild(struct work_struct *work)
 			}
 		}
 
-		if (policy->selector.prefixlen_d < dbits ||
-		    policy->selector.prefixlen_s < sbits)
+		if (policy->selector.prefixlen_d >= dbits &&
+		    policy->selector.prefixlen_s >= sbits)
 			continue;
 
 		bin = xfrm_policy_inexact_alloc_bin(policy, dir);
Signature · 1 line
2.53.0
author maintainer
#65 lore raw

PATCH 65/675 wifi: cfg80211: cancel sched scan results work on unregister

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cen Zhang <[email protected]>

[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]

cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a driver result notification while a scheduled scan request is present. The work callback recovers the containing cfg80211_registered_device and then locks the wiphy and walks the scheduled-scan request list.

wiphy_unregister() already makes the wiphy unreachable and drains rdev work items before cfg80211_dev_free() can release the object, but it does not drain sched_scan_res_wk. A queued or running result work item can therefore cross the unregister/free boundary and access freed rdev state.

The buggy scenario involves two paths, with each column showing the order within that path:

scheduled-scan result path: unregister/free path:
1. cfg80211_sched_scan_results() 1. interface teardown stops and
queues rdev->sched_scan_res_wk. removes the scheduled scan request.
2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
item and recovers rdev. rdev work items.
3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
and walks rdev state. frees rdev.

Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev work items. cancel_work_sync() removes a pending result notification and waits for an already running callback, so cfg80211_dev_free() cannot free rdev while this work item is still active.

Validation reproduced this kernel report:

BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530
Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211]
Read of size 8
Call trace:
  dump_stack_lvl+0x66/0xa0
  print_report+0xce/0x630
  cfg80211_sched_scan_results_wk+0x4a6/0x530
  srso_alias_return_thunk+0x5/0xfbef5
  __virt_addr_valid+0x224/0x430
  kasan_report+0xac/0xe0
  lockdep_hardirqs_on_prepare+0xea/0x1a0
  process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212)
  lock_is_held_type+0x8f/0x100
  worker_thread+0x5ad/0xfd0
  __kthread_parkme+0xc6/0x200
  kthread+0x31e/0x410
  trace_hardirqs_on+0x1a/0x170
  ret_from_fork+0x576/0x810
  __switch_to+0x57e/0xe20
  __switch_to_asm+0x33/0x70
  ret_from_fork_asm+0x1a/0x30
Fixes 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
Assisted-by Codex:gpt-5.5
---
 net/wireless/core.c | 1 +
 1 file changed, 1 insertion(+)
net/wireless/core.c +1 -0
index 6b204ca91a140b..34b76479f888bf 100644
@@ -1195,6 +1195,7 @@ void wiphy_unregister(struct wiphy *wiphy)
 	/* this has nothing to do now but make sure it's gone */
 	cancel_work_sync(&rdev->wiphy_work);
 
+	cancel_work_sync(&rdev->sched_scan_res_wk);
 	cancel_work_sync(&rdev->rfkill_block);
 	cancel_work_sync(&rdev->conn_work);
 	flush_work(&rdev->event_work);
Signature · 1 line
2.53.0
author maintainer
#66 lore raw

PATCH 66/675 wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Abdun Nihaal <[email protected]>

[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]

The memory allocated in the ipw2100_alloc_device() function is not freed in some of the error paths in ipw2100_pci_init_one(). Fix that by converting the direct return into a goto to the error path return.

The error path when pci_enable_device() fails cannot jump to fail, since at this point priv is not set, so perform error handling inline.

---
 drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/intel/ipw2x00/ipw2100.c +4 -4
index 215814861cbda5..0808e69c3c1786 100644
@@ -6162,6 +6162,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 	if (err) {
 		printk(KERN_WARNING DRV_NAME
 		       "Error calling pci_enable_device.\n");
+		free_libipw(dev, 0);
+		pci_iounmap(pci_dev, ioaddr);
 		return err;
 	}
 
@@ -6174,16 +6176,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 	if (err) {
 		printk(KERN_WARNING DRV_NAME
 		       "Error calling pci_set_dma_mask.\n");
-		pci_disable_device(pci_dev);
-		return err;
+		goto fail;
 	}
 
 	err = pci_request_regions(pci_dev, DRV_NAME);
 	if (err) {
 		printk(KERN_WARNING DRV_NAME
 		       "Error calling pci_request_regions.\n");
-		pci_disable_device(pci_dev);
-		return err;
+		goto fail;
 	}
 
 	/* We disable the RETRY_TIMEOUT register (0x41) to keep
Signature · 1 line
2.53.0
author maintainer
#67 lore raw

PATCH 67/675 wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christophe JAILLET <[email protected]>

[ Upstream commit c6659f66d4ee4841aafae5659d2ef5e4c5c63cb6 ]

If the test against IEEE80211_MAX_SSID_LEN fails, then 'creq' leaks. Use the existing error handling path to fix it.

---
 net/wireless/scan.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/wireless/scan.c +4 -2
index 2f2104bb0d52ff..27d5f99dbb2289 100644
@@ -3627,8 +3627,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 	/* translate "Scan for SSID" request */
 	if (wreq) {
 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
-			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
-				return -EINVAL;
+			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
+				err = -EINVAL;
+				goto out;
+			}
 			memcpy(creq->req.ssids[0].ssid, wreq->essid,
 			       wreq->essid_len);
 			creq->req.ssids[0].ssid_len = wreq->essid_len;
Signature · 1 line
2.53.0
author maintainer
#68 lore raw

PATCH 68/675 wifi: mac80211_hwsim: clamp virtio RX length before skb_put

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <[email protected]>

[ Upstream commit 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]

hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by the device straight to skb_put() on a fixed-size receive skb. A backend reporting a length larger than the skb tailroom drives skb_put() past the buffer end and hits skb_over_panic() -- a host-triggerable guest panic (denial of service).

Clamp the length to the skb's available room before skb_put(). A conforming device never reports more than the posted buffer size, so valid frames are unaffected; a truncated over-report then fails the length/header checks in hwsim_virtio_handle_cmd() and is dropped, so truncating rather than dropping here cannot be turned into a parsing problem.

Fixes 5d44fe7c9808 ("mac80211_hwsim: add frame transmission support over virtio")
---
 drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/virtual/mac80211_hwsim.c +1 -0
index 20815fdc9d3764..a0724e1c530709 100644
@@ -6898,6 +6898,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
 
 	skb->data = skb->head;
 	skb_reset_tail_pointer(skb);
+	len = min(len, skb_end_offset(skb));
 	skb_put(skb, len);
 	hwsim_virtio_handle_cmd(skb);
 
Signature · 1 line
2.53.0
author maintainer
#69 lore raw

PATCH 69/675 wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei <[email protected]>

[ Upstream commit 1d067abcd37062426c59ec73dbc4e87a63f33fea ]

ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old template before allocating the replacement. If the kzalloc() then fails, it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points at the object already queued for freeing. A later update or AP teardown re-queues that same rcu_head; the second free is caught by KASAN when the RCU sheaf is processed in softirq:

  BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
  Free of addr ffff88800d06f300 by task exploit/145
   ...
   __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
   rcu_free_sheaf (mm/slub.c:5850)
   rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
   handle_softirqs (kernel/softirq.c:622)
  The buggy address belongs to the cache kmalloc-128 of size 128

Queue the old object for kfree_rcu() only after the new one is published, matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().

Fixes 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
Assisted-by Claude:claude-opus-4-8
---
 net/mac80211/cfg.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
net/mac80211/cfg.c +3 -2
index d32eacbb7517d7..001e4bb55b6199 100644
@@ -1157,8 +1157,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
 	link_conf->unsol_bcast_probe_resp_interval = params->interval;
 
 	old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata);
-	if (old)
-		kfree_rcu(old, rcu_head);
 
 	if (params->tmpl && params->tmpl_len) {
 		new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
@@ -1171,6 +1169,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
 		RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL);
 	}
 
+	if (old)
+		kfree_rcu(old, rcu_head);
+
 	*changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
 	return 0;
 }
Signature · 1 line
2.53.0
author maintainer
#70 lore raw

PATCH 70/675 wifi: mac80211: fix fils_discovery double free on alloc failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei <[email protected]>

[ Upstream commit 286e52a799fa158bdbd77da1426c4d93f9a6e7ad ]

ieee80211_set_fils_discovery() calls kfree_rcu() on the old template before allocating the replacement. If the kzalloc() then fails, it returns -ENOMEM while link->u.ap.fils_discovery still points at the object already queued for freeing. A later update or AP teardown (ieee80211_stop_ap()) re-queues that same rcu_head; the second free is caught by KASAN when the RCU sheaf is processed in softirq:

  BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
  Free of addr ffff88800c065280 by task swapper/0/0
   ...
   __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
   rcu_free_sheaf (mm/slub.c:5850)
   rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
   handle_softirqs (kernel/softirq.c:622)
  The buggy address belongs to the cache kmalloc-96 of size 96

Queue the old object for kfree_rcu() only after the new one is published, matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().

Fixes 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
Assisted-by Claude:claude-opus-4-8
---
 net/mac80211/cfg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/mac80211/cfg.c +3 -3
index 001e4bb55b6199..f6232948bc0f4a 100644
@@ -1124,9 +1124,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
 	fd->max_interval = params->max_interval;
 
 	old = sdata_dereference(link->u.ap.fils_discovery, sdata);
-	if (old)
-		kfree_rcu(old, rcu_head);
-
 	if (params->tmpl && params->tmpl_len) {
 		new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
 		if (!new)
@@ -1138,6 +1135,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
 		RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL);
 	}
 
+	if (old)
+		kfree_rcu(old, rcu_head);
+
 	*changed |= BSS_CHANGED_FILS_DISCOVERY;
 	return 0;
 }
Signature · 1 line
2.53.0
author maintainer
#71 lore raw

PATCH 71/675 wifi: libertas: fix memory leak in helper_firmware_cb()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dawei Feng <[email protected]>

[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]

helper_firmware_cb() neglects to free the single-stage firmware image after a successful async load, leading to a memory leak in the USB firmware-download path.

Fix this memory leak by calling release_firmware() immediately after lbs_fw_loaded() returns.

The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in the current wireless tree.

An x86_64 allyesconfig build showed no new warnings. As we do not have compatible Libertas USB hardware for exercising this firmware-download path, no runtime testing was able to be performed.

Fixes 1dfba3060fe7 ("libertas: move firmware lifetime handling to firmware.c")
---
 drivers/net/wireless/marvell/libertas/firmware.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/marvell/libertas/firmware.c +1 -0
index f124110944b7e9..9bf7d4c207b9ed 100644
@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context)
 	} else {
 		/* No main firmware needed for this helper --> success! */
 		lbs_fw_loaded(priv, 0, firmware, NULL);
+		release_firmware(firmware);
 	}
 }
 
Signature · 1 line
2.53.0
author maintainer
#72 lore raw

PATCH 72/675 wifi: mac80211: defer link RX stats percpu free to RCU

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maoyi Xie <[email protected]>

[ Upstream commit aa2eb62525188269cdd402a583b9a8ed94657ff0 ]

sta_remove_link() frees a removed MLO link's RX stats percpu buffer right away, but defers only the link container to RCU:

	sta_info_free_link(&alloc->info);
	kfree_rcu(alloc, rcu_head);

The RX fast path reads link_sta under rcu_read_lock and writes the percpu stats. A reader that resolved link_sta before the removal keeps the pointer. The container stays alive from the kfree_rcu, so the read still works. But the percpu block it points to is already freed. This needs uses_rss. That is when pcpu_rx_stats exists.

The full STA teardown frees the deflink stats only after synchronize_net(). The link removal path had no such barrier. The race is hard to win in practice, but the free should still wait for RCU.

Free the link together with its data from a single RCU callback, so the percpu block is reclaimed only after readers drain.

---
 net/mac80211/sta_info.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
net/mac80211/sta_info.c +11 -4
index b0d9bb830f2931..54a6b20a4c5cd5 100644
@@ -355,6 +355,15 @@ static void sta_info_free_link(struct link_sta_info *link_sta)
 	free_percpu(link_sta->pcpu_rx_stats);
 }
 
+static void sta_link_free_rcu(struct rcu_head *head)
+{
+	struct sta_link_alloc *alloc =
+		container_of(head, struct sta_link_alloc, rcu_head);
+
+	sta_info_free_link(&alloc->info);
+	kfree(alloc);
+}
+
 static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id)
 {
 	struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy,
@@ -427,10 +436,8 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id,
 
 	RCU_INIT_POINTER(sta->link[link_id], NULL);
 	RCU_INIT_POINTER(sta->sta.link[link_id], NULL);
-	if (alloc) {
-		sta_info_free_link(&alloc->info);
-		kfree_rcu(alloc, rcu_head);
-	}
+	if (alloc)
+		call_rcu(&alloc->rcu_head, sta_link_free_rcu);
 
 	ieee80211_sta_recalc_aggregates(&sta->sta);
 }
Signature · 1 line
2.53.0
author maintainer
#73 lore raw

PATCH 73/675 wifi: p54: validate RX frame length in p54_rx_eeprom_readback()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei <[email protected]>

[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]

p54_rx_eeprom_readback() copies the requested EEPROM slice out of a device-supplied readback frame without checking that the skb actually holds that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in p54_rx_eeprom_readback()") closed the destination overflow by copying a fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len), but the source side is still unbounded: nothing verifies the frame is long enough to supply that many bytes.

A malicious USB device can send a short frame whose advertised len matches priv->eeprom_slice_size while the payload is truncated. The equality check passes and memcpy() reads past the end of the skb, leaking adjacent heap:

  BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
  Read of size 1016 at addr ffff88800f077114 by task swapper/0/0
  Call Trace:
   <IRQ>
   ...
   __asan_memcpy (mm/kasan/shadow.c:105)
   p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507)
   p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163)
   __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
   dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005)
   ...
   </IRQ>

  The buggy address belongs to the object at ffff88800f0770c0
   which belongs to the cache skbuff_small_head of size 704
  The buggy address is located 84 bytes inside of
   allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)

Check that the slice fits in the skb before copying.

Fixes 7cb770729ba8 ("p54: move eeprom code into common library")
Assisted-by Claude:claude-opus-4-8
---
 drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/net/wireless/intersil/p54/txrx.c +8 -0
index 1294a1d6528e2c..9f491334c8d043 100644
@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,
 		if (le16_to_cpu(eeprom->v2.len) != priv->eeprom_slice_size)
 			return;
 
+		if (eeprom->v2.data + priv->eeprom_slice_size >
+		    skb_tail_pointer(skb))
+			return;
+
 		memcpy(priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size);
 	} else {
 		if (le16_to_cpu(eeprom->v1.len) != priv->eeprom_slice_size)
 			return;
 
+		if (eeprom->v1.data + priv->eeprom_slice_size >
+		    skb_tail_pointer(skb))
+			return;
+
 		memcpy(priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size);
 	}
 
Signature · 1 line
2.53.0
author maintainer
#74 lore raw

PATCH 74/675 wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Peddolla Harshavardhan Reddy <[email protected]>

[ Upstream commit 2b0eab425e1f658d8fe1df7590e3b9af5959505e ]

When a netlink socket that owns a PMSR session is closed, cfg80211_release_pmsr() clears the request's nl_portid and queues pmsr_free_wk to call cfg80211_pmsr_process_abort() asynchronously.

If the interface tears down concurrently, cfg80211_pmsr_wdev_down() is called under wiphy_lock and calls cancel_work_sync(&pmsr_free_wk) to wait for any running work. The work function acquires wiphy_lock via guard(wiphy) before calling process_abort.

This is a deadlock: wdev_down holds wiphy_lock and blocks inside cancel_work_sync(); pmsr_free_wk blocks trying to acquire that same wiphy_lock. Neither thread can proceed.

The same deadlock is reachable from cfg80211_leave_locked(), which calls cfg80211_pmsr_wdev_down() for all interface types under wiphy_lock.

Fix this by converting pmsr_free_wk from a plain work_struct to a wiphy_work. The wiphy_work dispatcher holds wiphy_lock when running work items, so the explicit guard(wiphy) in the work function is no longer needed. wiphy_work_cancel() can be called safely while holding wiphy_lock - since wiphy_lock prevents the work from running concurrently, wiphy_work_cancel() never blocks, eliminating the deadlock.

Remove the cancel_work_sync() for pmsr_free_wk from the NETDEV_GOING_DOWN handler. cfg80211_leave(), called unconditionally just before it, already cancels any pending work under wiphy_lock via wiphy_work_cancel() inside cfg80211_pmsr_wdev_down().

Fixes 6dccbc9f3e1d ("wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down")
---
 include/net/cfg80211.h | 2 +-
 net/wireless/core.c    | 3 +--
 net/wireless/core.h    | 2 +-
 net/wireless/pmsr.c    | 8 +++-----
 4 files changed, 6 insertions(+), 9 deletions(-)
include/net/cfg80211.h +1 -1
index 820e299f06b5ee..1509be85139ecf 100644
@@ -6740,7 +6740,7 @@ struct wireless_dev {
 
 	struct list_head pmsr_list;
 	spinlock_t pmsr_lock;
-	struct work_struct pmsr_free_wk;
+	struct wiphy_work pmsr_free_wk;
 
 	unsigned long unprot_beacon_reported;
 
net/wireless/core.c +1 -2
index 34b76479f888bf..efbf7b3046342e 100644
@@ -1444,7 +1444,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
 	INIT_LIST_HEAD(&wdev->mgmt_registrations);
 	INIT_LIST_HEAD(&wdev->pmsr_list);
 	spin_lock_init(&wdev->pmsr_lock);
-	INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
+	wiphy_work_init(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
 
 #ifdef CONFIG_CFG80211_WEXT
 	wdev->wext.default_key = -1;
@@ -1579,7 +1579,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
 		}
 		/* since we just did cfg80211_leave() nothing to do there */
 		cancel_work_sync(&wdev->disconnect_wk);
-		cancel_work_sync(&wdev->pmsr_free_wk);
 		break;
 	case NETDEV_DOWN:
 		wiphy_lock(&rdev->wiphy);
net/wireless/core.h +1 -1
index d5d78752227af9..9bfd39af1742e1 100644
@@ -566,7 +566,7 @@ cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len);
 
 void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid);
 void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev);
-void cfg80211_pmsr_free_wk(struct work_struct *work);
+void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work);
 
 void cfg80211_remove_link(struct wireless_dev *wdev, unsigned int link_id);
 void cfg80211_remove_links(struct wireless_dev *wdev);
net/wireless/pmsr.c +3 -5
index 13801cf35e9fca..d2546c27879fa4 100644
@@ -625,13 +625,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
 	}
 }
 
-void cfg80211_pmsr_free_wk(struct work_struct *work)
+void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work)
 {
 	struct wireless_dev *wdev = container_of(work, struct wireless_dev,
 						 pmsr_free_wk);
 
-	guard(wiphy)(wdev->wiphy);
-
 	cfg80211_pmsr_process_abort(wdev);
 }
 
@@ -647,7 +645,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
 	}
 	spin_unlock_bh(&wdev->pmsr_lock);
 
-	cancel_work_sync(&wdev->pmsr_free_wk);
+	wiphy_work_cancel(wdev->wiphy, &wdev->pmsr_free_wk);
 	if (found)
 		cfg80211_pmsr_process_abort(wdev);
 
@@ -662,7 +660,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
 	list_for_each_entry(req, &wdev->pmsr_list, list) {
 		if (req->nl_portid == portid) {
 			req->nl_portid = 0;
-			schedule_work(&wdev->pmsr_free_wk);
+			wiphy_work_queue(wdev->wiphy, &wdev->pmsr_free_wk);
 		}
 	}
 	spin_unlock_bh(&wdev->pmsr_lock);
Signature · 1 line
2.53.0
author maintainer
#75 lore raw

PATCH 75/675 wifi: nl80211: free RNR data on MBSSID mismatch

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]

nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR entries than MBSSID entries.

The rejected RNR allocation has not been attached to the beacon data yet, so free it before returning the error.

Fixes dbbb27e183b1 ("cfg80211: support RNR for EMA AP")
---
 net/wireless/nl80211.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/wireless/nl80211.c +3 -1
index 6e41a4269e1c57..e765c992eb20e4 100644
@@ -6232,8 +6232,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
 			if (IS_ERR(rnr))
 				return PTR_ERR(rnr);
 
-			if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
+			if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) {
+				kfree(rnr);
 				return -EINVAL;
+			}
 
 			bcn->rnr_ies = rnr;
 		}
Signature · 1 line
2.53.0
author maintainer
#76 lore raw

PATCH 76/675 wifi: cfg80211: derive S1G beacon TSF from S1G fields

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 4e5a4641e7b4763656336b7891d01359aaf363cd ]

cfg80211_inform_bss_frame_data() parses S1G beacons with the extension frame layout, but still reads the TSF from the regular probe response layout after the S1G branch. For S1G beacons that reads bytes at the regular management-frame timestamp offset instead of the S1G timestamp.

Use the 32-bit S1G beacon timestamp and the S1G Beacon Compatibility element's TSF completion field when informing an S1G BSS. Keep the regular management-frame timestamp read in the non-S1G branch.

---
 net/wireless/scan.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
net/wireless/scan.c +3 -2
index 27d5f99dbb2289..af1e2ce1628dae 100644
@@ -3326,14 +3326,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
 		bssid = ext->u.s1g_beacon.sa;
 		capability = le16_to_cpu(compat->compat_info);
 		beacon_interval = le16_to_cpu(compat->beacon_int);
+		tsf = le32_to_cpu(ext->u.s1g_beacon.timestamp);
+		tsf |= (u64)le32_to_cpu(compat->tsf_completion) << 32;
 	} else {
 		bssid = mgmt->bssid;
 		beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
 		capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
+		tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
 	}
 
-	tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
-
 	if (ieee80211_is_probe_resp(mgmt->frame_control))
 		ftype = CFG80211_BSS_FTYPE_PRESP;
 	else if (ext)
Signature · 1 line
2.53.0
author maintainer
#77 lore raw

PATCH 77/675 wifi: nl80211: validate nested MBSSID IE blobs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]

Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed information-element stream before storing it for beacon construction.

RNR parsing already validates each nested blob with validate_ie_attr() before storing it. Apply the same syntactic IE validation to MBSSID entries before counting and copying their data and length pointers.

Fixes dc1e3cb8da8b ("nl80211: MBSSID and EMA support in AP mode")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
---
 net/wireless/nl80211.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
net/wireless/nl80211.c +10 -2
index e765c992eb20e4..5583edf4852775 100644
@@ -6034,7 +6034,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
 }
 
 static struct cfg80211_mbssid_elems *
-nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
+nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs,
+			   struct netlink_ext_ack *extack)
 {
 	struct nlattr *nl_elems;
 	struct cfg80211_mbssid_elems *elems;
@@ -6045,6 +6046,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
 		return ERR_PTR(-EINVAL);
 
 	nla_for_each_nested(nl_elems, attrs, rem_elems) {
+		int ret;
+
+		ret = validate_ie_attr(nl_elems, extack);
+		if (ret)
+			return ERR_PTR(ret);
+
 		if (num_elems >= 255)
 			return ERR_PTR(-EINVAL);
 		num_elems++;
@@ -6216,7 +6223,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
 	if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
 		struct cfg80211_mbssid_elems *mbssid =
 			nl80211_parse_mbssid_elems(&rdev->wiphy,
-						   attrs[NL80211_ATTR_MBSSID_ELEMS]);
+						   attrs[NL80211_ATTR_MBSSID_ELEMS],
+						   extack);
 
 		if (IS_ERR(mbssid))
 			return PTR_ERR(mbssid);
Signature · 1 line
2.53.0
author maintainer
#78 lore raw

PATCH 78/675 wifi: nl80211: constrain MBSSID TX link ID range

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 172f06023669f0a96d32511669ff45c600731380 ]

MBSSID transmitted-profile link IDs are valid only in the range 0..IEEE80211_MLD_MAX_NUM_LINKS - 1. Constrain the nl80211 policy to reject out-of-range values during attribute validation.

Fixes 37523c3c47b3 ("wifi: nl80211: add link id of transmitted profile for MLO MBSSID")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
---
 net/wireless/nl80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/nl80211.c +1 -1
index 5583edf4852775..237e5d7eeb47c3 100644
@@ -501,7 +501,7 @@ nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
 	[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
 	[NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
 	[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID] =
-		NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS),
+		NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1),
 };
 
 static const struct nla_policy
Signature · 1 line
2.53.0
author maintainer
#79 lore raw

PATCH 79/675 wifi: cfg80211: validate PMSR measurement type data

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]

PMSR request parsing accepts missing or duplicated measurement type entries in NL80211_PMSR_REQ_ATTR_DATA.

Track whether one measurement type was already provided, reject a second one immediately, and return an error if the request data block contains no measurement type at all.

Fixes 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
---
 net/wireless/pmsr.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
net/wireless/pmsr.c +17 -2
index d2546c27879fa4..fd14a3c2eab45b 100644
@@ -196,6 +196,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
 {
 	struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
 	struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
+	bool have_measurement_type = false;
 	struct nlattr *treq;
 	int err, rem;
 
@@ -248,6 +249,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
 	}
 
 	nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
+		if (have_measurement_type) {
+			NL_SET_ERR_MSG_ATTR(info->extack, treq,
+					    "multiple measurement types in request data");
+			return -EINVAL;
+		}
+
+		have_measurement_type = true;
+
 		switch (nla_type(treq)) {
 		case NL80211_PMSR_TYPE_FTM:
 			err = pmsr_parse_ftm(rdev, treq, out, info);
@@ -257,10 +266,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
 					    "unsupported measurement type");
 			err = -EINVAL;
 		}
+		if (err)
+			return err;
 	}
 
-	if (err)
-		return err;
+	if (!have_measurement_type) {
+		NL_SET_ERR_MSG_ATTR(info->extack,
+				    req[NL80211_PMSR_REQ_ATTR_DATA],
+				    "missing measurement type in request data");
+		return -EINVAL;
+	}
 
 	return 0;
 }
Signature · 1 line
2.53.0
author maintainer
#80 lore raw

PATCH 80/675 wifi: cfg80211: validate PMSR FTM preamble range

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]

PMSR FTM request parsing accepts preamble values outside the enumerated nl80211 preamble range.

Reject out-of-range values before using them in the parser capability bit test using the policy.

Fixes 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
[drop unnecessary check]
---
 net/wireless/nl80211.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/wireless/nl80211.c +3 -1
index 237e5d7eeb47c3..776dcf8835d715 100644
@@ -347,7 +347,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
 static const struct nla_policy
 nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
 	[NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
-	[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
+	[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] =
+		NLA_POLICY_RANGE(NLA_U32, NL80211_PREAMBLE_LEGACY,
+				 NL80211_PREAMBLE_HE),
 	[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
 		NLA_POLICY_MAX(NLA_U8, 15),
 	[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
Signature · 1 line
2.53.0
author maintainer
#81 lore raw

PATCH 81/675 wifi: cfg80211: reject unsupported PMSR FTM location requests

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]

PMSR FTM location request flags are syntactically valid, but they must be rejected when the device capability does not advertise support for them.

Return an error immediately after rejecting unsupported LCI or civic location request bits so the request cannot reach the driver.

Fixes 9bb7e0f24e7e7 ("cfg80211: add peer measurement with FTM initiator API")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
---
 net/wireless/pmsr.c | 2 ++
 1 file changed, 2 insertions(+)
net/wireless/pmsr.c +2 -0
index fd14a3c2eab45b..06563f60848705 100644
@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 		NL_SET_ERR_MSG_ATTR(info->extack,
 				    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
 				    "FTM: LCI request not supported");
+		return -EOPNOTSUPP;
 	}
 
 	out->ftm.request_civicloc =
@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
 		NL_SET_ERR_MSG_ATTR(info->extack,
 				    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
 			    "FTM: civic location request not supported");
+		return -EOPNOTSUPP;
 	}
 
 	out->ftm.trigger_based =
Signature · 1 line
2.53.0
author maintainer
#82 lore raw

PATCH 82/675 wifi: mac80211: avoid non-S1G AID fallback for S1G assoc

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Li <[email protected]>

[ Upstream commit 035ed430ce6a2c35b01e211844a9f0a7643e57a4 ]

When assoc_data->s1g is set and no AID Response element is present, falling back to mgmt->u.assoc_resp.aid reads the non-S1G association-response layout.

Keep the fallback for non-S1G only. If a successful S1G association response omits the AID Response element, abandon the association instead of proceeding with AID 0. Initialize aid to 0 for other S1G responses so the later mask and logging flow keeps a defined value without reading the non-S1G layout.

Fixes 2a8a6b7c4cb0 ("wifi: mac80211: handle station association response with S1G")
Assisted-by Codex:gpt-5.5
Assisted-by Claude:claude-opus-4.8
---
 net/mac80211/mlme.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/mac80211/mlme.c +4 -2
index 8854e47b056721..9ec4125c06d193 100644
@@ -6476,7 +6476,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
-	u16 capab_info, status_code, aid;
+	u16 capab_info, status_code, aid = 0;
 	struct ieee80211_elems_parse_params parse_params = {
 		.bss = NULL,
 		.link_id = -1,
@@ -6553,8 +6553,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
 	if (elems->aid_resp)
 		aid = le16_to_cpu(elems->aid_resp->aid);
-	else
+	else if (!assoc_data->s1g)
 		aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
+	else if (status_code == WLAN_STATUS_SUCCESS)
+		goto abandon_assoc;
 
 	/*
 	 * The 5 MSB of the AID field are reserved for a non-S1G STA. For
Signature · 1 line
2.53.0
author maintainer
#83 lore raw

PATCH 83/675 wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cen Zhang <[email protected]>

[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]

ieee80211_do_stop() removes AP_VLAN packets from the parent AP ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then calls ieee80211_free_txskb() before dropping the lock.

ieee80211_free_txskb() is not just a passive SKB release. For SKBs with TX status state it can report a dropped frame through cfg80211/nl80211, and that path can reach netlink tap transmit. This is the same reason the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs under the queue lock and frees them after IRQ state is restored.

The buggy scenario involves two paths, with each column showing the order within that path:

AP_VLAN management TX:             AP_VLAN stop:
1. attach ACK-status state         1. clear the running state
2. queue a multicast SKB on        2. take ps->bc_buf.lock with IRQs

parent ps->bc_buf disabled
3. unlink the AP_VLAN SKB
4. call ieee80211_free_txskb()

Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock, but move them to a local free queue. Drop the lock and restore IRQ state before calling ieee80211_free_txskb().

WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
Fixes 397a7a24ef8c ("mac80211: free ps->bc_buf skbs on vlan device stop")
Assisted-by Codex:gpt-5.5
---
 net/mac80211/iface.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
net/mac80211/iface.c +7 -1
index 72c129478da088..499126317a914c 100644
@@ -581,6 +581,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 		WARN_ON(!list_empty(&sdata->u.ap.vlans));
 	} else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
 		/* remove all packets in parent bc_buf pointing to this dev */
+		__skb_queue_head_init(&freeq);
 		ps = &sdata->bss->ps;
 
 		spin_lock_irqsave(&ps->bc_buf.lock, flags);
@@ -588,10 +589,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 			if (skb->dev == sdata->dev) {
 				__skb_unlink(skb, &ps->bc_buf);
 				local->total_ps_buffered--;
-				ieee80211_free_txskb(&local->hw, skb);
+				__skb_queue_tail(&freeq, skb);
 			}
 		}
 		spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
+
+		skb_queue_walk_safe(&freeq, skb, tmp) {
+			__skb_unlink(skb, &freeq);
+			ieee80211_free_txskb(&local->hw, skb);
+		}
 	}
 
 	if (going_down)
Signature · 1 line
2.53.0
author maintainer
#84 lore raw

PATCH 84/675 wifi: brcmfmac: initialize SDIO data work before cleanup

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Runyu Xiao <[email protected]>

[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]

brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before allocating the ordered workqueue. If that allocation fails, the function jumps to fail and calls brcmf_sdio_remove().

brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the work item before the first failure path that can reach brcmf_sdio_remove(), so the cleanup path always observes a valid work object.

This issue was found by our static analysis tool and then confirmed by manual review of the probe error path and the remove-time work drain. The problem pattern is an early setup failure that reaches a cleanup helper which cancels an embedded work item before its initializer has run.

A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in the stack.

Fixes 9982464379e8 ("brcmfmac: make sdio suspend wait for threads to freeze")
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +1 -1
index a0e88dbaaebe67..9ab62a2667c7b6 100644
@@ -4465,6 +4465,7 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
 	bus->sdiodev = sdiodev;
 	sdiodev->bus = bus;
 	skb_queue_head_init(&bus->glom);
+	INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
 	bus->txbound = BRCMF_TXBOUND;
 	bus->rxbound = BRCMF_RXBOUND;
 	bus->txminmax = BRCMF_TXMINMAX;
@@ -4479,7 +4480,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
 		goto fail;
 	}
 	brcmf_sdiod_freezer_count(sdiodev);
-	INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
 	bus->brcmf_wq = wq;
 
 	/* attempt to attach to the dongle */
Signature · 1 line
2.53.0
author maintainer
#85 lore raw

PATCH 85/675 wifi: cfg80211: bound element ID read when checking non-inheritance

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: HE WEI (ギカク) <[email protected]>

[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]

cfg80211_is_element_inherited() reads the first data octet of the candidate element (id = elem->data[0]) to look it up in an extension non-inheritance list. It does so after testing elem->id, but without verifying that the element actually has a data octet. A zero-length extension element (WLAN_EID_EXTENSION with length 0) therefore makes it read one octet past the end of the element.

_ieee802_11_parse_elems_full() runs this check for every element of a frame once a non-inheritance context exists -- e.g. while parsing a per-STA profile of a Multi-Link element in a (re)association response, or a non-transmitted BSS profile -- so a crafted frame from an AP can trigger a one-octet slab-out-of-bounds read during element parsing:

  BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited
  Read of size 1 ... in net/wireless/scan.c

Return early (treat the element as inherited) when an extension element carries no data, mirroring the existing handling of empty ID lists.

The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.

Fixes f7dacfb11475 ("cfg80211: support non-inheritance element")
---
 net/wireless/scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/scan.c +1 -1
index af1e2ce1628dae..11f7a27bb7046c 100644
@@ -205,7 +205,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,
 		return true;
 
 	if (elem->id == WLAN_EID_EXTENSION) {
-		if (!ext_id_len)
+		if (!ext_id_len || !elem->datalen)
 			return true;
 		loop_len = ext_id_len;
 		list = &non_inherit_elem->data[3 + id_len];
Signature · 1 line
2.53.0
author maintainer
#86 lore raw

PATCH 86/675 firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mostafa Saleh <[email protected]>

[ Upstream commit 3383ffb7ef937317361713ffcc21921a7848511a ]

Sashiko (locally) reports multiple out-of-bound issues in ffa_setup_and_transmit:
1) Writing ep_mem_access->reserved can write out of bounds for FFA versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case while reserved has an offset of 24.
Instead of zeroing fields, memset the struct to zero first based on the FFA version.

2) Make sure there is enough size to write constituents.

While at it, convert the only sizeof() in the driver that uses a type instead of variable.

Fixes 111a833dc5cb ("firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors")
---
 drivers/firmware/arm_ffa/driver.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/firmware/arm_ffa/driver.c +3 -4
index feded15bb5e921..6f576c39e4832a 100644
@@ -719,11 +719,10 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
 	for (idx = 0; idx < args->nattrs; idx++) {
 		ep_mem_access = buffer +
 			ffa_mem_desc_offset(buffer, idx, drv_info->version);
+		memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
 		ep_mem_access->receiver = args->attrs[idx].receiver;
 		ep_mem_access->attrs = args->attrs[idx].attrs;
 		ep_mem_access->composite_off = composite_offset;
-		ep_mem_access->flag = 0;
-		ep_mem_access->reserved = 0;
 		ffa_emad_impdef_value_init(drv_info->version,
 					   ep_mem_access->impdef_val,
 					   args->attrs[idx].impdef_val);
@@ -763,7 +762,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
 			constituents = buffer;
 		}
 
-		if ((void *)constituents - buffer > max_fragsize) {
+		if ((void *)constituents + sizeof(*constituents) - buffer > max_fragsize) {
 			pr_err("Memory Region Fragment > Tx Buffer size\n");
 			return -EFAULT;
 		}
@@ -772,7 +771,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
 		constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE;
 		constituents->reserved = 0;
 		constituents++;
-		frag_len += sizeof(struct ffa_mem_region_addr_range);
+		frag_len += sizeof(*constituents);
 	} while ((args->sg = sg_next(args->sg)));
 
 	return ffa_transmit_fragment(func_id, addr, buf_sz, frag_len,
Signature · 1 line
2.53.0
author maintainer
#87 lore raw

PATCH 87/675 firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sebastian Ene <[email protected]>

[ Upstream commit b4d961351aa84fdf0148783fb1f3a1391b8a0adb ]

Use the descriptor's ep_mem_offset to calculate the start of the endpoint memory access array and to comply with the FF-A spec instead of defaulting to sizeof(struct ffa_mem_region).
This requires moving ffa_mem_region_additional_setup() earlier in the setup flow.
Also, add sanity checks to ensure the calculated descriptor offsets do not exceed max_fragsize.

Fixes 113580530ee7 ("firmware: arm_ffa: Update memory descriptor to support v1.1 format")
---
 drivers/firmware/arm_ffa/driver.c | 20 +++++++++++++++-----
 include/linux/arm_ffa.h           |  2 +-
 2 files changed, 16 insertions(+), 6 deletions(-)
drivers/firmware/arm_ffa/driver.c +15 -5
index 6f576c39e4832a..1d0bd586da4d6f 100644
@@ -707,19 +707,30 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
 	struct ffa_composite_mem_region *composite;
 	struct ffa_mem_region_addr_range *constituents;
 	struct ffa_mem_region_attributes *ep_mem_access;
-	u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg);
+	u32 idx, frag_len, length, buf_sz = 0, num_entries = sg_nents(args->sg), ep_offset;
+	u32 emad_end, emad_size = ffa_emad_size_get(drv_info->version);
 
 	mem_region->tag = args->tag;
 	mem_region->flags = args->flags;
 	mem_region->sender_id = drv_info->vm_id;
 	mem_region->attributes = ffa_memory_attributes_get(func_id);
+
+	ffa_mem_region_additional_setup(drv_info->version, mem_region);
 	composite_offset = ffa_mem_desc_offset(buffer, args->nattrs,
 					       drv_info->version);
+	if (composite_offset + sizeof(*composite) > max_fragsize)
+		return -ENXIO;
 
 	for (idx = 0; idx < args->nattrs; idx++) {
-		ep_mem_access = buffer +
-			ffa_mem_desc_offset(buffer, idx, drv_info->version);
-		memset(ep_mem_access, 0, ffa_emad_size_get(drv_info->version));
+		ep_offset = ffa_mem_desc_offset(buffer, idx, drv_info->version);
+		if (check_add_overflow(ep_offset, emad_size, &emad_end))
+			return -ENXIO;
+
+		if (emad_end > max_fragsize)
+			return -ENXIO;
+
+		ep_mem_access = buffer + ep_offset;
+		memset(ep_mem_access, 0, emad_size);
 		ep_mem_access->receiver = args->attrs[idx].receiver;
 		ep_mem_access->attrs = args->attrs[idx].attrs;
 		ep_mem_access->composite_off = composite_offset;
@@ -729,7 +740,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
 	}
 	mem_region->handle = 0;
 	mem_region->ep_count = args->nattrs;
-	ffa_mem_region_additional_setup(drv_info->version, mem_region);
 
 	composite = buffer + composite_offset;
 	composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg);
include/linux/arm_ffa.h +1 -1
index 81e603839c4a51..62d67dae8b7033 100644
@@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
 	if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
 		offset += offsetof(struct ffa_mem_region, ep_mem_offset);
 	else
-		offset += sizeof(struct ffa_mem_region);
+		offset += buf->ep_mem_offset;
 
 	return offset;
 }
Signature · 1 line
2.53.0
author maintainer
#88 lore raw

PATCH 88/675 ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christian Hewitt <[email protected]>

[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]

The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 + AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed, producing the "machine gun noise" buffer underrun - on start when switching outputs, and on stop when playback ends. The latter is audible on devices with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).

The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on both enable and disable (audio_hw_958_enable), and when reconfiguring (audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
reset before enabling the DCU on start, and before disabling on stop.

Fixes 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
---
 sound/soc/meson/aiu-fifo-spdif.c | 5 +++++
 1 file changed, 5 insertions(+)
sound/soc/meson/aiu-fifo-spdif.c +5 -0
index e0e00ec026dcc4..a9861c5d663745 100644
@@ -24,6 +24,7 @@
 #define AIU_MEM_IEC958_CONTROL_MODE_16BIT	BIT(7)
 #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR	BIT(8)
 #define AIU_MEM_IEC958_BUF_CNTL_INIT		BIT(0)
+#define AIU_RST_SOFT_958_FAST			BIT(2)
 
 #define AIU_FIFO_SPDIF_BLOCK			8
 
@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		snd_soc_component_write(component, AIU_RST_SOFT,
+					AIU_RST_SOFT_958_FAST);
 		fifo_spdif_dcu_enable(component, true);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_STOP:
+		snd_soc_component_write(component, AIU_RST_SOFT,
+					AIU_RST_SOFT_958_FAST);
 		fifo_spdif_dcu_enable(component, false);
 		break;
 	default:
Signature · 1 line
2.53.0
author maintainer
#89 lore raw

PATCH 89/675 ASoC: amd: ps: disable MSI on resume in ACP PCI driver

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vijendar Mukunda <[email protected]>

[ Upstream commit 5893013efabb056399a01e267f410cf76eba25eb ]

BIOS/firmware may re-enable MSI in PCI config space during system level resume even though this driver only uses legacy INTx interrupts. If MSI is left enabled with stale address/data registers, the device will write interrupts to a bogus address causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.

Clear the MSI Enable bit before reinitializing the ACP hardware on system level resume.

Fixes 491628388005 ("ASoC: amd: ps: add callback functions for acp pci driver pm ops")
---
 sound/soc/amd/ps/pci-ps.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
sound/soc/amd/ps/pci-ps.c +29 -0
index c62299b2920417..34efb42be768fb 100644
@@ -683,8 +683,37 @@ static int snd_acp_runtime_resume(struct device *dev)
 	return acp_hw_runtime_resume(dev);
 }
 
+static void acp_disable_msi_on_resume(struct pci_dev *pdev)
+{
+	u16 control;
+
+	if (!pdev->msi_cap)
+		return;
+
+	pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &control);
+	if (control & PCI_MSI_FLAGS_ENABLE) {
+		dev_warn(&pdev->dev,
+			 "ACP: MSI unexpectedly enabled after resume (flags=0x%04x), disabling\n",
+			 control);
+		control &= ~PCI_MSI_FLAGS_ENABLE;
+		pci_write_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, control);
+	}
+}
+
 static int snd_acp_resume(struct device *dev)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	/*
+	 * BIOS/firmware may re-enable MSI in PCI config space during
+	 * system resume even though this driver only uses legacy INTx
+	 * interrupts. If MSI is left enabled with stale address/data
+	 * registers, the device will write interrupts to a bogus address
+	 * causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.
+	 * Explicitly clear the MSI Enable bit before reinitializing
+	 * the ACP hardware.
+	 */
+	acp_disable_msi_on_resume(pdev);
 	return acp_hw_resume(dev);
 }
 
Signature · 1 line
2.53.0
author maintainer
#90 lore raw

PATCH 90/675 ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vijendar Mukunda <[email protected]>

[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]

The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was claimed with the stale name "AMD ACP6.2 audio" left over from the original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".

---
 sound/soc/amd/ps/pci-ps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/amd/ps/pci-ps.c +1 -1
index 34efb42be768fb..8f37c250d4b895 100644
@@ -595,7 +595,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
 		return -ENODEV;
 	}
 
-	ret = pci_request_regions(pci, "AMD ACP6.2 audio");
+	ret = pci_request_regions(pci, "AMD ACP6.3 audio");
 	if (ret < 0) {
 		dev_err(&pci->dev, "pci_request_regions failed\n");
 		goto disable_pci;
Signature · 1 line
2.53.0
author maintainer
#91 lore raw

PATCH 91/675 ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vijendar Mukunda <[email protected]>

[ Upstream commit dec5aaa27603e1d7b426ce3504af6d1a62e4d444 ]

The condition 'irq_flag | wake_irq_flag' uses bitwise OR to combine two integer flags that are used as booleans. Replace with logical OR '||' to correctly express the intended boolean check.

Fixes 7f91f012c1df0 ("ASoC: amd: ps: fix for irq handler return status")
---
 sound/soc/amd/ps/pci-ps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/amd/ps/pci-ps.c +1 -1
index 8f37c250d4b895..cf06d4ae299b51 100644
@@ -248,7 +248,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
 	if (sdw_dma_irq_flag)
 		return IRQ_WAKE_THREAD;
 
-	if (irq_flag | wake_irq_flag)
+	if (irq_flag || wake_irq_flag)
 		return IRQ_HANDLED;
 	else
 		return IRQ_NONE;
Signature · 1 line
2.53.0
author maintainer
#92 lore raw

PATCH 92/675 ASoC: cs42l43: Correct report for forced microphone jack

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Charles Keepax <[email protected]>

[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]

Currently if the jack is forced to the microphone mode, it will report as line in. Correct the report to microphone.

Fixes fc918cbe874e ("ASoC: cs42l43: Add support for the cs42l43")
---
 sound/soc/codecs/cs42l43-jack.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/codecs/cs42l43-jack.c +2 -1
index ecba6c79523840..36fb67059e0652 100644
@@ -310,6 +310,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
 #define CS42L43_JACK_ABSENT 0x0
 
 #define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
+#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
 #define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
 #define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
 #define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
@@ -871,7 +872,7 @@ static const struct cs42l43_jack_override_mode {
 		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
 		.mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
 			    CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
-		.report = CS42L43_JACK_LINEIN,
+		.report = CS42L43_JACK_MICROPHONE,
 	},
 	[CS42L43_JACK_RAW_OPTICAL] = {
 		.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
Signature · 1 line
2.53.0
author maintainer
#93 lore raw

PATCH 93/675 ASoC: tas2562: fix deprecated shut-down GPIO always cleared after lookup

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Uday Khare <[email protected]>

[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]

In tas2562_parse_dt(), the fallback lookup for the deprecated "shut-down" GPIO property is broken due to a missing pair of braces.

The code intends to reset sdz_gpio to NULL only when the lookup returns an error that is not -EPROBE_DEFER (so the driver gracefully continues without a GPIO). However, without braces the statement:

    tas2562->sdz_gpio = NULL;

falls outside the IS_ERR() check and is executed unconditionally for every path through the if block, including a successful GPIO lookup.

This means any device using the deprecated 'shut-down' DT property will always have sdz_gpio == NULL after probe, making the GPIO completely non-functional.

Fix this by adding the missing braces to scope the NULL assignment inside the IS_ERR() branch, matching the pattern already used for the primary 'shutdown' GPIO lookup above.

Fixes f78a97003b8b ("ASoC: tas2562: Update shutdown GPIO property")
---
 sound/soc/codecs/tas2562.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
sound/soc/codecs/tas2562.c +3 -2
index 8e00dcc09d0c28..795c66cb47134e 100644
@@ -675,11 +675,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
 	if (tas2562->sdz_gpio == NULL) {
 		tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
 							      GPIOD_OUT_HIGH);
-		if (IS_ERR(tas2562->sdz_gpio))
+		if (IS_ERR(tas2562->sdz_gpio)) {
 			if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
 				return -EPROBE_DEFER;
 
-		tas2562->sdz_gpio = NULL;
+			tas2562->sdz_gpio = NULL;
+		}
 	}
 
 	if (tas2562->model_id == TAS2110)
Signature · 1 line
2.53.0
author maintainer
#94 lore raw

PATCH 94/675 firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pushpendra Singh <[email protected]>

[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]

The scmi_notify() function is called from interrupt context to queue received notification events onto a per-protocol kfifo. When the kfifo is full, it logs a warning via dev_warn() for every dropped event.

Under conditions where the platform sends a burst of SCMI notifications faster than the deferred worker can drain the queue, this results in a flood of dev_warn() calls from IRQ context. Each call acquires the console lock and may execute blocking console writes, causing the CPU to be held in interrupt context for an extended period and leading to observable system stalls.

Fix this by switching to dev_warn_ratelimited() to limit the frequency of log messages when the notification queue is full. This reduces console overhead in interrupt context and prevents CPU stalls caused by excessive logging, while still preserving diagnostic visibility.

Fixes bd31b249692e ("firmware: arm_scmi: Add notification dispatch and delivery")
---
 drivers/firmware/arm_scmi/notify.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/firmware/arm_scmi/notify.c +3 -3
index 2047edbdc5f6b1..9bf7f43ab868c8 100644
@@ -600,9 +600,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
 		return -EINVAL;
 	}
 	if (kfifo_avail(&r_evt->proto->equeue.kfifo) < sizeof(eh) + len) {
-		dev_warn(handle->dev,
-			 "queue full, dropping proto_id:%d  evt_id:%d  ts:%lld\n",
-			 proto_id, evt_id, ktime_to_ns(ts));
+		dev_warn_ratelimited(handle->dev,
+				     "queue full, dropping proto_id:%d  evt_id:%d  ts:%lld\n",
+				     proto_id, evt_id, ktime_to_ns(ts));
 		return -ENOMEM;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#95 lore raw

PATCH 95/675 cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rafael J. Wysocki <[email protected]>

[ Upstream commit d2d5c129d07ea8eb91cd8a8633b5774116c4d171 ]

If arch_scale_freq_ref() is not defined for a given arch (like x86, for example), cpufreq_update_pressure() will always set cpufreq_pressure to zero for all CPUs in the system, which is generally problematic on systems with asymmetric capacity [1].

However, in the absence of arch_scale_freq_ref(), it is reasonable to assume that cpuinfo.max_freq is the maximum sustainable frequency for the given cpufreq policy. Moreover, there are cases in which arch_scale_freq_ref() would need to be defined to return essentially the cpuinfo.max_freq value anyway (for example, intel_pstate on hybrid platforms).

For the above reasons, update cpufreq_update_pressure() to fall back to using cpuinfo.max_freq as the reference frequency if zero is returned by arch_scale_freq_ref().

---
 drivers/cpufreq/cpufreq.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/cpufreq/cpufreq.c +3 -0
index a70df77f9b7d11..ced96d9e254ee4 100644
@@ -2584,6 +2584,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
 
 	cpu = cpumask_first(policy->related_cpus);
 	max_freq = arch_scale_freq_ref(cpu);
+	if (!max_freq)
+		max_freq = policy->cpuinfo.max_freq;
+
 	capped_freq = policy->max;
 
 	/*
Signature · 1 line
2.53.0
author maintainer
#96 lore raw

PATCH 96/675 ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Norbert Szetei <[email protected]>

[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]

pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:

l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
-> ppp_input(&po->chan)

It runs under rcu_read_lock() holding only an l2tp_session reference and takes NO reference on the internal PPP channel (struct channel, chan->ppp) that ppp_input() dereferences.

The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel are RCU-safe. But the internal struct channel is a separate allocation that ppp_release_channel() frees with a plain kfree():

close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
-> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)

For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit (no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips both ppp_disconnect_channel()'s synchronize_net() and ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace period. rcu_read_lock() in pppol2tp_recv() does not protect against a plain kfree(), so an in-flight ppp_input() on one CPU can dereference the channel just freed by close() on another CPU.

The bug is reachable by an unprivileged user.

Defer the channel free to an RCU callback via call_rcu() so the grace period fences any in-flight ppp_input(). The disconnect and unbridge teardown paths already fence with synchronize_net()/synchronize_rcu(); call_rcu() does the same here without stalling the close() path.

Fixes ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU")
Assisted-by Claude:claude-opus-4-8
---
 drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/net/ppp/ppp_generic.c +15 -3
index 507d216256c0dd..72e98286fba2fe 100644
@@ -185,6 +185,7 @@ struct channel {
 	struct list_head clist;		/* link in list of channels per unit */
 	spinlock_t	upl;		/* protects `ppp' and 'bridge' */
 	struct channel __rcu *bridge;	/* "bridged" ppp channel */
+	struct rcu_head rcu;		/* for RCU-deferred free of the channel */
 #ifdef CONFIG_PPP_MULTILINK
 	u8		avail;		/* flag used in multilink stuff */
 	u8		had_frag;	/* >= 1 fragments have been sent */
@@ -3570,6 +3571,18 @@ ppp_disconnect_channel(struct channel *pch)
 	return err;
 }
 
+/* Purge after the grace period: a late ppp_input() may still queue an
+ * skb on pch->file.rq before the last RCU reader drains.
+ */
+static void ppp_release_channel_free(struct rcu_head *rcu)
+{
+	struct channel *pch = container_of(rcu, struct channel, rcu);
+
+	skb_queue_purge(&pch->file.xq);
+	skb_queue_purge(&pch->file.rq);
+	kfree(pch);
+}
+
 /*
  * Free up the resources used by a ppp channel.
  */
@@ -3585,9 +3598,7 @@ static void ppp_destroy_channel(struct channel *pch)
 		pr_err("ppp: destroying undead channel %p !\n", pch);
 		return;
 	}
-	skb_queue_purge(&pch->file.xq);
-	skb_queue_purge(&pch->file.rq);
-	kfree(pch);
+	call_rcu(&pch->rcu, ppp_release_channel_free);
 }
 
 static void __exit ppp_cleanup(void)
@@ -3600,6 +3611,7 @@ static void __exit ppp_cleanup(void)
 	device_destroy(&ppp_class, MKDEV(PPP_MAJOR, 0));
 	class_unregister(&ppp_class);
 	unregister_pernet_device(&ppp_net_ops);
+	rcu_barrier(); /* wait for RCU callbacks before module unload */
 }
 
 /*
Signature · 1 line
2.53.0
author maintainer
#97 lore raw

PATCH 97/675 ipv4: fib: free fib_alias with kfree_rcu() on insert error path

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Weiming Shi <[email protected]>

[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]

fib_table_insert() publishes new_fa into the leaf's fa_list with fib_insert_alias() before calling the fib entry notifiers. When a notifier fails, the error path removes new_fa with fib_remove_alias() (hlist_del_rcu) and frees it right away with kmem_cache_free().

fib_table_lookup() walks that list under rcu_read_lock() only, so a concurrent lookup that already reached new_fa keeps reading it after the free:

 BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601)
 Read of size 1 at addr ffff88810676d4eb by task exploit/297
 Call Trace:
  fib_table_lookup (net/ipv4/fib_trie.c:1601)
  ip_route_output_key_hash_rcu (net/ipv4/route.c:2814)
  ip_route_output_key_hash (net/ipv4/route.c:2705)
  __ip4_datagram_connect (net/ipv4/datagram.c:49)
  udp_connect (net/ipv4/udp.c:2144)
  __sys_connect (net/socket.c:2167)
  __x64_sys_connect (net/socket.c:2173)
  do_syscall_64
  entry_SYSCALL_64_after_hwframe
 which belongs to the cache ip_fib_alias of size 56

Triggering the error path needs CAP_NET_ADMIN and a registered fib notifier that can reject a route; a netdevsim device whose IPv4 FIB resource is exhausted is enough.

Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already does for a fib_alias removed from the trie.

Fixes a6c76c17df02 ("ipv4: Notify route after insertion to the routing table")
Assisted-by Claude:claude-opus-4-8
---
 net/ipv4/fib_trie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/fib_trie.c +1 -1
index 1308213791f19d..2dc87e2156d373 100644
@@ -1385,7 +1385,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
 out_remove_new_fa:
 	fib_remove_alias(t, tp, l, new_fa);
 out_free_new_fa:
-	kmem_cache_free(fn_alias_kmem, new_fa);
+	alias_free_mem_rcu(new_fa);
 out:
 	fib_release_info(fi);
 err:
Signature · 1 line
2.53.0
author maintainer
#98 lore raw

PATCH 98/675 net/iucv: take a reference on the socket found in afiucv_hs_rcv()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <[email protected]>

[ Upstream commit 4fa349156043dc119721d067329714179f501749 ]

afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock, drops the lock, and then passes the socket to the afiucv_hs_callback_*() handlers without holding a reference. AF_IUCV sockets are not RCU-protected and are freed synchronously by iucv_sock_kill() -> sock_put(), so a concurrent close can free the socket in the window between read_unlock() and the handler, which then dereferences freed memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).

Take a reference with sock_hold() while the socket is still on the list and release it with sock_put() once the handler has run.

---
 net/iucv/af_iucv.c | 4 ++++
 1 file changed, 4 insertions(+)
net/iucv/af_iucv.c +4 -0
index c66b90c912e78e..bd0405373c5e97 100644
@@ -2089,6 +2089,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
 			}
 		}
 	}
+	if (sk)
+		sock_hold(sk);
 	read_unlock(&iucv_sk_list.lock);
 	if (!iucv)
 		sk = NULL;
@@ -2138,6 +2140,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
 		kfree_skb(skb);
 	}
 
+	if (sk)
+		sock_put(sk);
 	return err;
 }
 
Signature · 1 line
2.53.0
author maintainer
#99 lore raw

PATCH 99/675 udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Robert Mader <[email protected]>

[ Upstream commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 ]

The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning") says:

Quoted 4 lines

The CPU sync at map/unmap time is also redundant for udmabuf:
begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU access is requested through the dma-buf interface.

This, however, does not apply to the first time begin_cpu_udmabuf() is called on an udmabuf, in which case the implementation previously relied on get_sg_table() to perform the cache synchronisation.

Ensure to call dma_sync_sgtable_for_cpu() in that case as well.

Fixes 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning")
---
 drivers/dma-buf/udmabuf.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/dma-buf/udmabuf.c +5 -4
index be47d1ff6c508b..30b0f0c72e928c 100644
@@ -249,21 +249,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
 {
 	struct udmabuf *ubuf = buf->priv;
 	struct device *dev = ubuf->device->this_device;
-	int ret = 0;
 
 	if (!ubuf->sg) {
 		ubuf->sg = get_sg_table(dev, buf, direction);
 		if (IS_ERR(ubuf->sg)) {
+			int ret;
+
 			ret = PTR_ERR(ubuf->sg);
 			ubuf->sg = NULL;
+			return ret;
 		} else {
 			ubuf->sg_dir = direction;
 		}
-	} else {
-		dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
 	}
 
-	return ret;
+	dma_sync_sgtable_for_cpu(dev, ubuf->sg, direction);
+	return 0;
 }
 
 static int end_cpu_udmabuf(struct dma_buf *buf,
Signature · 1 line
2.53.0
author maintainer
#100 lore raw

PATCH 100/675 scsi: core: wake eh reliably when using scsi_schedule_eh

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Jeffery <[email protected]>

[ Upstream commit dccf3b1798b70f94e958b3d00b83010399e6fb05 ]

Drivers which use the scsi_schedule_eh function to run the error handler currently risk the error handler thread never waking once all commands are timed out or inactive. There is no enforced memory order between setting the host into error recovery state and counting busy commands. This can result in a race with scsi_dec_host_busy where neither CPU sees both conditions of all commands inactive and the host error state to request waking the error handler.

To fix this, run the scsi_schedule_eh's scsi_eh_wakeup from a new work item which will use rcu to ensure scsi_schedule_eh's call to scsi_host_busy will occur after the error state is globally visible and will be seen by any current scsi_dec_host_busy callers.

Fixes 6eb045e092ef ("scsi: core: avoid host-wide host_busy counter for scsi_mq")
---
 drivers/scsi/hosts.c      |  2 ++
 drivers/scsi/scsi_error.c | 22 +++++++++++++++++++++-
 drivers/scsi/scsi_priv.h  |  1 +
 include/scsi/scsi_host.h  |  3 +++
 4 files changed, 27 insertions(+), 1 deletion(-)
drivers/scsi/hosts.c +2 -0
index 17173239301e61..a1055fe4922f64 100644
@@ -343,6 +343,7 @@ static void scsi_host_dev_release(struct device *dev)
 	/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
 	rcu_barrier();
 
+	cancel_work_sync(&shost->eh_work);
 	if (shost->tmf_work_q)
 		destroy_workqueue(shost->tmf_work_q);
 	if (shost->ehandler)
@@ -408,6 +409,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
 	INIT_LIST_HEAD(&shost->starved_list);
 	init_waitqueue_head(&shost->host_wait);
 	mutex_init(&shost->scan_mutex);
+	INIT_WORK(&shost->eh_work, scsi_rcu_eh_wakeup);
 
 	index = ida_alloc(&host_index_ida, GFP_KERNEL);
 	if (index < 0) {
drivers/scsi/scsi_error.c +21 -1
index 2fd4ca96b3089d..13d46b6e0359e2 100644
@@ -73,6 +73,26 @@ void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy)
 	}
 }
 
+void scsi_rcu_eh_wakeup(struct work_struct *work)
+{
+	struct Scsi_Host *shost = container_of(work, struct Scsi_Host, eh_work);
+	unsigned long flags;
+	unsigned int busy;
+
+	/*
+	 * Ensure any running scsi_dec_host_busy has completed its rcu section
+	 * so changes to host state and host_eh_scheduled are visible to all
+	 * future calls of scsi_dec_host_busy
+	 */
+	synchronize_rcu();
+
+	busy = scsi_host_busy(shost);
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	scsi_eh_wakeup(shost, busy);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
 /**
  * scsi_schedule_eh - schedule EH for SCSI host
  * @shost:	SCSI host to invoke error handling on.
@@ -88,7 +108,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
 	if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 ||
 	    scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) {
 		shost->host_eh_scheduled++;
-		scsi_eh_wakeup(shost, scsi_host_busy(shost));
+		queue_work(shost->tmf_work_q, &shost->eh_work);
 	}
 
 	spin_unlock_irqrestore(shost->host_lock, flags);
drivers/scsi/scsi_priv.h +1 -0
index 5b2b19f5e8ec8a..68866b18a60058 100644
@@ -91,6 +91,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req);
 extern int scsi_error_handler(void *host);
 extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd);
 extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy);
+extern void scsi_rcu_eh_wakeup(struct work_struct *work);
 extern void scsi_eh_scmd_add(struct scsi_cmnd *);
 void scsi_eh_ready_devs(struct Scsi_Host *shost,
 			struct list_head *work_q,
include/scsi/scsi_host.h +3 -0
index f5a24326123605..936403c15e53d3 100644
@@ -714,6 +714,9 @@ struct Scsi_Host {
 	 */
 	struct device *dma_dev;
 
+	/* Used for an rcu-synchronizing eh wakeup */
+	struct work_struct eh_work;
+
 	/* Delay for runtime autosuspend */
 	int rpm_autosuspend_delay;
 
Signature · 1 line
2.53.0
author maintainer
#101 lore raw

PATCH 101/675 ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rosen Penev <[email protected]>

[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]

sata_dwc_enable_interrupts() is called before platform_get_irq() and ata_host_activate(), leaving the SATA controller's interrupt mask enabled without a registered handler. If a later step fails (irq request, phy init, etc.) or if the controller asserts an interrupt during probe, the irq line may fire with no handler, causing a spurious interrupt storm.

Move sata_dwc_enable_interrupts() after ata_host_activate() so that interrupts are only unmasked once the handler is registered and the core is fully initialized.

Fixes 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by opencode:big-pickle
---
 drivers/ata/sata_dwc_460ex.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/ata/sata_dwc_460ex.c +2 -3
index 7a4f59202156ec..4029e082577fe1 100644
@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	/* Save dev for later use in dev_xxx() routines */
 	hsdev->dev = dev;
 
-	/* Enable SATA Interrupts */
-	sata_dwc_enable_interrupts(hsdev);
-
 	/* Get SATA interrupt number */
 	irq = irq_of_parse_and_map(np, 0);
 	if (!irq) {
@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	if (err)
 		dev_err(dev, "failed to activate host");
 
+	/* Enable SATA Interrupts */
+	sata_dwc_enable_interrupts(hsdev);
 	return 0;
 
 error_out:
Signature · 1 line
2.53.0
author maintainer
#102 lore raw

PATCH 102/675 ata: sata_dwc_460ex: use platform_get_irq()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rosen Penev <[email protected]>

[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]

Replace irq_of_parse_and_map() with platform_get_irq() in both sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred way to obtain IRQs for platform devices and provides better error reporting. Remove the now-unnecessary #include <linux/of_irq.h>.

irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.

Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.

Fixes 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by opencode:big-pickle
---
 drivers/ata/sata_dwc_460ex.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)
drivers/ata/sata_dwc_460ex.c +7 -14
index 4029e082577fe1..639eab75210f29 100644
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <linux/dmaengine.h>
 #include <linux/of.h>
-#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
 #include <linux/libata.h>
@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
 				 struct sata_dwc_device *hsdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
 
 	hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL);
 	if (!hsdev->dma)
@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev,
 	hsdev->dma->id = pdev->id;
 
 	/* Get SATA DMA interrupt number */
-	hsdev->dma->irq = irq_of_parse_and_map(np, 1);
-	if (!hsdev->dma->irq) {
-		dev_err(dev, "no SATA DMA irq\n");
-		return -ENODEV;
-	}
+	hsdev->dma->irq = platform_get_irq(pdev, 1);
+	if (hsdev->dma->irq < 0)
+		return hsdev->dma->irq;
 
 	/* Get physical SATA DMA register base address */
 	hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1);
@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {
 static int sata_dwc_probe(struct platform_device *ofdev)
 {
 	struct device *dev = &ofdev->dev;
-	struct device_node *np = dev->of_node;
 	struct sata_dwc_device *hsdev;
 	u32 idr, versionr;
 	char *ver = (char *)&versionr;
@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev)
 	hsdev->dev = dev;
 
 	/* Get SATA interrupt number */
-	irq = irq_of_parse_and_map(np, 0);
-	if (!irq) {
-		dev_err(dev, "no SATA DMA irq\n");
-		return -ENODEV;
-	}
+	irq = platform_get_irq(ofdev, 0);
+	if (irq < 0)
+		return irq;
 
 #ifdef CONFIG_SATA_DWC_OLD_DMA
-	if (!of_property_present(np, "dmas")) {
+	if (!of_property_present(dev->of_node, "dmas")) {
 		err = sata_dwc_dma_init_old(ofdev, hsdev);
 		if (err)
 			return err;
Signature · 1 line
2.53.0
author maintainer
#103 lore raw

PATCH 103/675 ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rosen Penev <[email protected]>

[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]

clear_interrupt_bit() ignores the bit argument and performs a read-write-back of the entire INTPR register. If INTPR uses standard Write-1-to-Clear semantics, this clears every pending interrupt bit, not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP) would be cleared together, silently losing the second event.

Write only the specific bit to clear so that other pending interrupts are preserved.

Fixes 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by opencode:big-pickle
---
 drivers/ata/sata_dwc_460ex.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/ata/sata_dwc_460ex.c +1 -2
index 639eab75210f29..d3472bfc606ffc 100644
@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)
 
 static void clear_interrupt_bit(struct sata_dwc_device *hsdev, u32 bit)
 {
-	sata_dwc_writel(&hsdev->sata_dwc_regs->intpr,
-			sata_dwc_readl(&hsdev->sata_dwc_regs->intpr));
+	sata_dwc_writel(&hsdev->sata_dwc_regs->intpr, bit);
 }
 
 static u32 qcmd_tag_to_mask(u8 tag)
Signature · 1 line
2.53.0
author maintainer
#104 lore raw

PATCH 104/675 ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rosen Penev <[email protected]>

[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]

The hand-rolled bit-scanning loop in the NCQ completion path has an infinite loop bug. When tag_mask has only high bits set (e.g. 0x80000000), the inner while loop left-shifts tag_mask until it overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1 stays 0, causing an infinite loop in hardirq context with a spinlock held.

Replace the open-coded bit-scanning with __ffs() which correctly finds the least significant set bit and is bounded by the width of the argument.

Fixes 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex")
Assisted-by opencode:big-pickle
---
 drivers/ata/sata_dwc_460ex.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/ata/sata_dwc_460ex.c +2 -7
index d3472bfc606ffc..36cc28b8986509 100644
@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
 	status = ap->ops->sff_check_status(ap);
 	dev_dbg(ap->dev, "%s ATA status register=0x%x\n", __func__, status);
 
-	tag = 0;
 	while (tag_mask) {
-		while (!(tag_mask & 0x00000001)) {
-			tag++;
-			tag_mask <<= 1;
-		}
-
-		tag_mask &= (~0x00000001);
+		tag = __ffs(tag_mask);
+		tag_mask &= ~(1U << tag);
 		qc = ata_qc_from_tag(ap, tag);
 		if (unlikely(!qc)) {
 			dev_err(ap->dev, "failed to get qc");
Signature · 1 line
2.53.0
author maintainer
#105 lore raw

PATCH 105/675 accel/ivpu: Fix wrong register read in LNL failure diagnostics

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Karol Wachowski <[email protected]>

[ Upstream commit e4159045c2704dfe146f0ccb0445d9d074cd6882 ]

diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a different register with a different bit layout, so failure diagnostics decoded the wrong register and reported a bogus error cause. Read the LNL interrupt status register instead.

Fixes 8a27ad81f7d3 ("accel/ivpu: Split IP and buttress code")
---
 drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/ivpu/ivpu_hw_btrs.c +1 -1
index aa33f562d29c12..e9786204feca43 100644
@@ -845,7 +845,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev)
 
 static void diagnose_failure_lnl(struct ivpu_device *vdev)
 {
-	u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+	u32 reg = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
 
 	if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) {
 		ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
Signature · 1 line
2.53.0
author maintainer
#106 lore raw

PATCH 106/675 ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]

Salvador reported that the recent fix for applying the DSD quirk to Musical Fidelity devices broke for his M6s DAC model (2772:0502).

Although this is basically a firmware bug, the model in question is fairly old, and no further firmware update can be expected, so it'd be better to address in the driver side.

As an ad hoc workaround, skip the DSD quirk for this device by adding an empty quirk entry of 2772:0502; this essentially skips the later DSD quirk entry by the match with the vendor 2772.

---
 sound/usb/quirks.c | 2 ++
 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
index 1b4cfc2b68f9dc..3d81b003a5109b 100644
@@ -2380,6 +2380,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 		   QUIRK_FLAG_DSD_RAW),
 	DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
+	DEVICE_FLG(0x2772, 0x0502, /* Musical Fidelity M6s DAC */
+		   0), /* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */
 	DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
 		   QUIRK_FLAG_GET_SAMPLE_RATE),
 	DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
Signature · 1 line
2.53.0
author maintainer
#107 lore raw

PATCH 107/675 Bluetooth: qca: fix NVM tag length underflow in TLV parser

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiang Mei <[email protected]>

[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]

In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is "while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a size_t (12), so "length" is converted to size_t and any firmware-supplied "length" < 12 makes the subtraction wrap to a huge value. The loop body then reads a 12-byte struct tlv_type_nvm past the end of the short vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).

Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both operands are non-negative, so it no longer underflows and a "length" too small for one record correctly skips the loop.

  BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421)
  Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52
  Workqueue: hci0 hci_power_on
  Call Trace:
   ...
   kasan_report (mm/kasan/report.c:595)
   qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617)
   qca_uart_setup (drivers/bluetooth/btqca.c:948)
   qca_setup (drivers/bluetooth/hci_qca.c:2029)
   hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438)
   hci_dev_open_sync (net/bluetooth/hci_sync.c:5227)
   hci_power_on (net/bluetooth/hci_core.c:920)
   process_one_work (kernel/workqueue.c:3322)
   worker_thread (kernel/workqueue.c:3486)
   kthread (kernel/kthread.c:436)
   ret_from_fork (arch/x86/kernel/process.c:158)
   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
Fixes 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks")
Assisted-by Claude:claude-opus-4-8
---
 drivers/bluetooth/btqca.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/bluetooth/btqca.c +1 -1
index 86a48d009d1ba2..afab479ac89448 100644
@@ -413,7 +413,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
 
 		idx = 0;
 		data = tlv->data;
-		while (idx < length - sizeof(struct tlv_type_nvm)) {
+		while (idx + sizeof(struct tlv_type_nvm) <= length) {
 			tlv_nvm = (struct tlv_type_nvm *)(data + idx);
 
 			tag_id = le16_to_cpu(tlv_nvm->tag_id);
Signature · 1 line
2.53.0
author maintainer
#108 lore raw

PATCH 108/675 Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cen Zhang <[email protected]>

[ Upstream commit 2bf282f8f715f5d05d6f4c49ffb3bd241c5e667e ]

MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter update changes an existing LE central connection. The queued work currently stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later LOAD_CONN_PARAM request can clear disabled parameters and free that entry before hci_cmd_sync_work() runs the queued callback.

Do not keep the borrowed hci_conn_params pointer in queued work. Queue the hci_conn instead and hold a reference until the queued callback completes. When the work runs, revalidate that the connection is still present, look up the current hci_conn_params entry, and cancel the update if userspace removed that entry while the work was pending.

Copy the interval values from the current params entry under hdev->lock, then drop the lock and keep using hci_le_conn_update_sync() to issue the update.

Validation reproduced this kernel report:

BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth]
Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377
Workqueue: hci0 hci_cmd_sync_work [bluetooth]

Call Trace:
 <TASK>
 dump_stack_lvl+0x66/0xa0
 print_report+0xce/0x5f0
 kasan_report+0xe0/0x110
 conn_update_sync+0x2a/0xf0 [bluetooth]
 hci_cmd_sync_work+0x187/0x210 [bluetooth]
 process_one_work+0x4fd/0xbc0
 worker_thread+0x2d8/0x570
 kthread+0x1ad/0x1f0
 ret_from_fork+0x3c9/0x540
 ret_from_fork_asm+0x1a/0x30

Allocated by task 466:
 hci_conn_params_add+0xa6/0x240 [bluetooth]
 load_conn_param+0x4e1/0x850 [bluetooth]
 hci_sock_sendmsg+0x96b/0xf80 [bluetooth]

Freed by task 474:
 kfree+0x313/0x590
 hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth]
 load_conn_param+0x4bf/0x850 [bluetooth]
 hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
Fixes 0ece498c27d8c ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection")
Assisted-by Codex:gpt-5.5
---
 net/bluetooth/mgmt.c | 44 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)
net/bluetooth/mgmt.c +35 -9
index 410910f64c1c49..4c8b172e85d006 100644
@@ -7924,14 +7924,36 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
 
 static int conn_update_sync(struct hci_dev *hdev, void *data)
 {
-	struct hci_conn_params *params = data;
-	struct hci_conn *conn;
+	struct hci_conn *conn = data;
+	struct hci_conn_params *params;
+	struct hci_conn_params local = {};
 
-	conn = hci_conn_hash_lookup_le(hdev, &params->addr, params->addr_type);
-	if (!conn)
-		return -ECANCELED;
+	hci_dev_lock(hdev);
+
+	if (!hci_conn_valid(hdev, conn) || conn->role != HCI_ROLE_MASTER)
+		goto cancel;
+
+	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+	if (!params)
+		goto cancel;
+
+	local.conn_min_interval = params->conn_min_interval;
+	local.conn_max_interval = params->conn_max_interval;
+	local.conn_latency = params->conn_latency;
+	local.supervision_timeout = params->supervision_timeout;
 
-	return hci_le_conn_update_sync(hdev, conn, params);
+	hci_dev_unlock(hdev);
+
+	return hci_le_conn_update_sync(hdev, conn, &local);
+
+cancel:
+	hci_dev_unlock(hdev);
+	return -ECANCELED;
+}
+
+static void conn_update_sync_destroy(struct hci_dev *hdev, void *data, int err)
+{
+	hci_conn_put(data);
 }
 
 static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -8041,9 +8063,13 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
 			    (conn->le_conn_min_interval != min ||
 			     conn->le_conn_max_interval != max ||
 			     conn->le_conn_latency != latency ||
-			     conn->le_supv_timeout != timeout))
-				hci_cmd_sync_queue(hdev, conn_update_sync,
-						   hci_param, NULL);
+			     conn->le_supv_timeout != timeout)) {
+				hci_conn_get(conn);
+				if (hci_cmd_sync_queue(hdev, conn_update_sync,
+						       conn,
+						       conn_update_sync_destroy) < 0)
+					hci_conn_put(conn);
+			}
 		}
 	}
 
Signature · 1 line
2.53.0